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

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README.md55
-rw-r--r--lib/Slic3r.pm3
-rw-r--r--lib/Slic3r/GUI.pm2
-rw-r--r--lib/Slic3r/GUI/MainFrame.pm16
-rw-r--r--lib/Slic3r/GUI/Plater/3DPreview.pm11
-rw-r--r--resources/icons/Slic3r-console.icobin17542 -> 17542 bytes
-rw-r--r--resources/icons/Slic3r.icobin102134 -> 102134 bytes
-rw-r--r--resources/icons/Slic3r.pngbin16469 -> 14688 bytes
-rw-r--r--resources/icons/Slic3r_128px.pngbin13016 -> 11866 bytes
-rw-r--r--resources/icons/Slic3r_192px.pngbin21962 -> 19642 bytes
-rw-r--r--resources/icons/Slic3r_192px_transparent.pngbin21125 -> 18588 bytes
-rw-r--r--resources/localization/fr_FR/Slic3rPE.mobin132575 -> 139702 bytes
-rw-r--r--resources/localization/fr_FR/Slic3rPE_fr.po9703
-rw-r--r--resources/localization/zh_CN/Slic3rPE_zh.po8
-rw-r--r--resources/profiles/PrusaResearch.ini5
-rw-r--r--src/avrdude/main.c2
-rw-r--r--src/libslic3r/BridgeDetector.cpp107
-rw-r--r--src/libslic3r/BridgeDetector.hpp5
-rw-r--r--src/libslic3r/CMakeLists.txt4
-rw-r--r--src/libslic3r/ClipperUtils.hpp8
-rw-r--r--src/libslic3r/ExPolygon.cpp214
-rw-r--r--src/libslic3r/ExPolygon.hpp4
-rw-r--r--src/libslic3r/ExtrusionEntity.hpp37
-rw-r--r--src/libslic3r/ExtrusionEntityCollection.cpp41
-rw-r--r--src/libslic3r/ExtrusionEntityCollection.hpp4
-rw-r--r--src/libslic3r/Fill/Fill.cpp125
-rw-r--r--src/libslic3r/Fill/Fill3DHoneycomb.cpp59
-rw-r--r--src/libslic3r/Fill/FillBase.cpp384
-rw-r--r--src/libslic3r/Fill/FillBase.hpp25
-rw-r--r--src/libslic3r/Fill/FillConcentric.cpp97
-rw-r--r--src/libslic3r/Fill/FillConcentric.hpp25
-rw-r--r--src/libslic3r/Fill/FillGyroid.cpp95
-rw-r--r--src/libslic3r/Fill/FillRectilinear.cpp6
-rw-r--r--src/libslic3r/Fill/FillRectilinear2.cpp279
-rw-r--r--src/libslic3r/Fill/FillRectilinear2.hpp33
-rw-r--r--src/libslic3r/Fill/FillRectilinear3.cpp4
-rw-r--r--src/libslic3r/Fill/FillSmooth.cpp278
-rw-r--r--src/libslic3r/Fill/FillSmooth.hpp112
-rw-r--r--src/libslic3r/GCode.cpp173
-rw-r--r--src/libslic3r/GCode.hpp4
-rw-r--r--src/libslic3r/GCode/CoolingBuffer.cpp38
-rw-r--r--src/libslic3r/GCode/PreviewData.cpp3
-rw-r--r--src/libslic3r/GCode/PreviewData.hpp1
-rw-r--r--src/libslic3r/GCode/ToolOrdering.cpp12
-rw-r--r--src/libslic3r/GCode/WipeTowerPrusaMM.cpp12
-rw-r--r--src/libslic3r/GCode/WipeTowerPrusaMM.hpp8
-rw-r--r--src/libslic3r/Geometry.cpp267
-rw-r--r--src/libslic3r/Geometry.hpp32
-rw-r--r--src/libslic3r/Layer.cpp6
-rw-r--r--src/libslic3r/Layer.hpp6
-rw-r--r--src/libslic3r/LayerRegion.cpp46
-rw-r--r--src/libslic3r/Line.cpp11
-rw-r--r--src/libslic3r/Line.hpp4
-rw-r--r--src/libslic3r/MedialAxis.cpp1644
-rw-r--r--src/libslic3r/MedialAxis.hpp74
-rw-r--r--src/libslic3r/MultiPoint.cpp37
-rw-r--r--src/libslic3r/MultiPoint.hpp2
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp1066
-rw-r--r--src/libslic3r/PerimeterGenerator.hpp30
-rw-r--r--src/libslic3r/Point.cpp23
-rw-r--r--src/libslic3r/Point.hpp15
-rw-r--r--src/libslic3r/Polyline.cpp107
-rw-r--r--src/libslic3r/Polyline.hpp29
-rw-r--r--src/libslic3r/Print.cpp252
-rw-r--r--src/libslic3r/Print.hpp6
-rw-r--r--src/libslic3r/PrintConfig.cpp510
-rw-r--r--src/libslic3r/PrintConfig.hpp108
-rw-r--r--src/libslic3r/PrintObject.cpp549
-rw-r--r--src/libslic3r/Slicing.cpp39
-rw-r--r--src/libslic3r/Slicing.hpp1
-rw-r--r--src/libslic3r/SupportMaterial.cpp194
-rw-r--r--src/libslic3r/SupportMaterial.hpp20
-rw-r--r--src/libslic3r/Surface.cpp26
-rw-r--r--src/libslic3r/Surface.hpp39
-rw-r--r--src/libslic3r/TriangleMesh.cpp2
-rw-r--r--src/libslic3r/TriangleMesh.hpp1
-rw-r--r--src/libslic3r/libslic3r.h5
-rw-r--r--src/slic3r/GUI/AboutDialog.cpp5
-rw-r--r--src/slic3r/GUI/ConfigWizard.cpp16
-rw-r--r--src/slic3r/GUI/Field.cpp49
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp3
-rw-r--r--src/slic3r/GUI/GUI.cpp16
-rw-r--r--src/slic3r/GUI/GUI_App.cpp10
-rw-r--r--src/slic3r/GUI/MainFrame.cpp50
-rw-r--r--src/slic3r/GUI/OptionsGroup.cpp22
-rw-r--r--src/slic3r/GUI/Preset.cpp54
-rw-r--r--src/slic3r/GUI/PresetBundle.cpp2
-rw-r--r--src/slic3r/GUI/PresetHints.cpp20
-rw-r--r--src/slic3r/GUI/Tab.cpp238
-rw-r--r--src/slic3r/GUI/Tab.hpp2
-rw-r--r--t/fill.t3
-rw-r--r--t/flow.t1
-rw-r--r--t/perimeters.t2
-rw-r--r--t/thin.t37
-rw-r--r--version.inc2
96 files changed, 10303 insertions, 7384 deletions
diff --git a/.gitignore b/.gitignore
index d56825aca..1612499f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,5 @@ xs/MANIFEST.bak
xs/assertlib*
.init_bundle.ini
local-lib
+build*
+deps/deps-build
diff --git a/README.md b/README.md
index f6c0677c4..7716210a5 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-_Q: Oh cool, a new RepRap slicer?_
+_Q: Oh cool, a new fork of slic3r?_
-A: Yes.
+A: Yeah!
Slic3r
======
-Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/Slic3r/releases).
+Prebuilt Windows 32b is available through the [git releases page](https://github.com/supermerill/Slic3r/releases).
<img width=256 src=https://cloud.githubusercontent.com/assets/31754/22719818/09998c92-ed6d-11e6-9fa0-09de638f3a36.png />
@@ -18,14 +18,24 @@ See the [project homepage](http://slic3r.org/) at slic3r.org and the
### What language is it written in?
-The core geometric algorithms and data structures are written in C++,
-and Perl is used for high-level flow abstraction, GUI and testing.
-If you're wondering why Perl, see https://xkcd.com/224/
+Almost everything are written in C++,
The C++ API is public and its use in other projects is encouraged.
The goal is to make Slic3r fully modular so that any part of its logic
can be used separately.
+### What are this fork main features/differences?
+
+* **Ironing** top surface & many new settings to fine-tune the top surface quality.
+* A "denser infill" option for supporting the (solid) top layers.
+* Better overhangs (add perimeters if needed, slice them in opposite direction each layer).
+* Better Thin walls (anchored inside the print, no more random bits at the ends).
+* Can join perimeters into a big one to avoid travel moves.
+* Many other little options and corrections (like the filled concentric pattern).
+* It has also all the current slic3rPE features.
+
+See the wiki for examples.
+
### What are Slic3r's main features?
Key features are:
@@ -41,12 +51,12 @@ Key features are:
Other major features are:
-* combine infill every 'n' perimeters layer to speed up printing
+* combine infill every 'n' perimeters layer & varying density to speed up printing
* **3D preview** (including multi-material files)
* **multiple layer heights** in a single print
* **spiral vase** mode for bumpless vases
* fine-grained configuration of speed, acceleration, extrusion width
-* several infill patterns including honeycomb, spirals, Hilbert curves
+* several infill patterns including honeycomb, spirals, Hilbert curves, gyroid
* support material, raft, brim, skirt
* **standby temperature** and automatic wiping for multi-extruder printing
* customizable **G-code macros** and output filename with variable placeholders
@@ -55,39 +65,34 @@ Other major features are:
### How to install?
-You can download a precompiled package from [slic3r.org](http://slic3r.org/);
+You can download a precompiled package from the release page.
it will run without the need for any dependency.
If you want to compile the source yourself follow the instructions on one of these wiki pages:
-* [Linux](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-GNU-Linux)
-* [Windows](https://github.com/prusa3d/Slic3r/wiki/How-to-compile-Slic3r-Prusa-Edition-on-MS-Windows)
-* [Mac OSX](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-OS-X)
+* [Linux](https://github.com/supermerill/Slic3r/tree/master/doc/How%20to%20build%20-%20UNIX.md)
+* [Windows](https://github.com/supermerill/Slic3r/tree/master/doc/How%20to%20build%20-%20Windows.md)
+* [Mac OSX](https://github.com/supermerill/Slic3r/tree/master/doc/How_to_build_Slic3r.txt)
### Can I help?
Sure! You can do the following to find things that are available to help with:
-* [Pull Request Milestone](https://github.com/alexrj/Slic3r/milestone/31)
- * Please comment in the related github issue that you are working on it so that other people know.
-* Items in the [TODO](https://github.com/alexrj/Slic3r/wiki/TODO) wiki page.
- * Please comment in the related github issue that you are working on it so that other people know.
-* Drop me a line at aar@cpan.org.
-* You can also find me (rarely) in #reprap and in #slic3r on [FreeNode](https://webchat.freenode.net) with the nickname _Sound_. Another contributor, _LoH_, is also in both channels.
-* Add an [issue](https://github.com/alexrj/Slic3r/issues) to the github tracker if it isn't already present.
+* Add an issue to the github tracker if it isn't already present.
Before sending patches and pull requests contact me (preferably through opening a github issue or commenting on an existing, related, issue) to discuss your proposed
-changes: this way we'll ensure nobody wastes their time and no conflicts arise
-in development.
+changes: this way we'll ensure nobody wastes their time and no conflicts arise in development.
### What's Slic3r license?
Slic3r is licensed under the _GNU Affero General Public License, version 3_.
-The author is Alessandro Ranellucci.
+The first author is Alessandro Ranellucci, and many contributors
+Then the he Prusa team
+Then Durand remi for this fork
-The [Silk icon set](http://www.famfamfam.com/lab/icons/silk/) used in Slic3r is
+The [Silk icon set](http://www.famfamfam.com/lab/icons/silk/) used (and modified) in Slic3r is
licensed under the _Creative Commons Attribution 3.0 License_.
The author of the Silk icon set is Mark James.
-### How can I invoke slic3r.pl using the command line?
+### How can I invoke slic3r.pl using the command line? (not up-to-date yet, use the --help command instead)
Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ...
@@ -296,6 +301,7 @@ The author of the Silk icon set is Mark James.
--min-fan-speed Minimum fan speed (default: 35%)
--max-fan-speed Maximum fan speed (default: 100%)
--bridge-fan-speed Fan speed to use when bridging (default: 100%)
+ --top-fan-speed Fan speed to use when printing top layer (default: 100%)
--fan-below-layer-time Enable fan if layer print time is below this approximate number
of seconds (default: 60)
--slowdown-below-layer-time Slow down if layer print time is below this approximate number
@@ -358,6 +364,7 @@ The author of the Silk icon set is Mark James.
Set a different extrusion width for support material
--infill-overlap Overlap between infill and perimeters (default: 15%)
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1)
+ --over-bridge-flow-ratio Multiplier for extrusion when printing the layer above a bride (> 0, default: 1.15)
Multiple extruder options:
--extruder-offset Offset of each extruder, if firmware doesn't handle the displacement
diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm
index 44100db8c..b5196515a 100644
--- a/lib/Slic3r.pm
+++ b/lib/Slic3r.pm
@@ -106,12 +106,13 @@ sub copyright_info
my (%params) = @_;
my %tag = Slic3r::tags($params{format});
my $out =
+ 'Copyright &copy; 2018 Durand Rémi. <br />' .
'Copyright &copy; 2016 Vojtech Bubnik, Prusa Research. <br />' .
'Copyright &copy; 2011-2016 Alessandro Ranellucci. <br />' .
'<a href="http://slic3r.org/">Slic3r</a> is licensed under the ' .
'<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License, version 3</a>.' .
'<br /><br /><br />' .
- 'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' .
+ 'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake, Durand Rémi and numerous others. ' .
'Manual by Gary Hodgson. Inspired by the RepRap community. <br />' .
'Slic3r logo designed by Corey Daniels, <a href="http://www.famfamfam.com/lab/icons/silk/">Silk Icon Set</a> designed by Mark James. ';
return $out;
diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm
index 31f614ba9..82c7c5e77 100644
--- a/lib/Slic3r/GUI.pm
+++ b/lib/Slic3r/GUI.pm
@@ -57,7 +57,7 @@ sub OnInit {
my ($self) = @_;
$self->SetAppName('Slic3rPE');
- $self->SetAppDisplayName('Slic3r Prusa Edition');
+ $self->SetAppDisplayName('Slic3r++');
Slic3r::debugf "wxWidgets version %s, Wx version %s\n", &Wx::wxVERSION_STRING, $Wx::VERSION;
# Set the Slic3r data directory at the Slic3r XS module.
diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm
index c1975cd5d..4d16356ba 100644
--- a/lib/Slic3r/GUI/MainFrame.pm
+++ b/lib/Slic3r/GUI/MainFrame.pm
@@ -74,7 +74,7 @@ sub new {
# initialize status bar
$self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new();
$self->{statusbar}->Embed;
- $self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"));
+ $self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/supermerill/slic3r/releases"));
# Make the global status bar and its progress indicator available in C++
Slic3r::GUI::set_progress_status_bar($self->{statusbar});
$appController->set_global_progress_indicator($self->{statusbar});
@@ -389,11 +389,11 @@ sub _init_menubar {
# Help menu
my $helpMenu = Wx::Menu->new;
{
- $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/');
- });
- $self->_append_menu_item($helpMenu, L("Prusa Edition Releases"), L('Open the Prusa Edition releases page in your browser'), sub {
- Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/releases');
+
+
+
+ $self->_append_menu_item($helpMenu, L("Slic3r++ Releases"), L('Open the Slic3r++ releases page in your browser'), sub {
+ Wx::LaunchDefaultBrowser('http://github.com/supermerill/slic3r/releases');
});
# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub {
# wxTheApp->check_version(1);
@@ -412,8 +412,8 @@ sub _init_menubar {
$self->_append_menu_item($helpMenu, L("Show &Configuration Folder"), L('Show user configuration folder (datadir)'), sub {
Slic3r::GUI::desktop_open_datadir_folder();
});
- $self->_append_menu_item($helpMenu, L("Report an Issue"), L('Report an issue on the Slic3r Prusa Edition'), sub {
- Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/issues/new');
+ $self->_append_menu_item($helpMenu, L("Report an Issue"), L('Report an issue on the Slic3r++ github'), sub {
+ Wx::LaunchDefaultBrowser('http://github.com/supermerill/slic3r/issues/new');
});
$self->_append_menu_item($helpMenu, L("&About Slic3r"), L('Show about dialog'), sub {
Slic3r::GUI::about;
diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm
index 06d1a798b..bc229723c 100644
--- a/lib/Slic3r/GUI/Plater/3DPreview.pm
+++ b/lib/Slic3r/GUI/Plater/3DPreview.pm
@@ -78,10 +78,12 @@ sub new {
$choice_view_type->Append(L("Speed"));
$choice_view_type->Append(L("Volumetric flow rate"));
$choice_view_type->Append(L("Tool"));
+ $choice_view_type->Append(L("Filament"));
$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;
+ $self->{filament_idx} = 6;
my $label_show_features = $self->{label_show_features} = Wx::StaticText->new($self, -1, L("Show"));
@@ -371,6 +373,15 @@ sub load_print {
push @colors, $color;
}
}
+ if($self->gcode_preview_data->type == $self->{filament_idx}) {
+ my @extruder_colors = @{$self->{config}->extruder_colour};
+ my @filament_colors = @{$self->{config}->filament_colour};
+ for (my $i = 0; $i <= $#extruder_colors; $i += 1) {
+ my $color = $filament_colors[$i];
+ $color = '#FFFFFF' if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
+ push @colors, $color;
+ }
+ }
if ($self->IsShown) {
# used to set the sliders to the extremes of the current zs range
diff --git a/resources/icons/Slic3r-console.ico b/resources/icons/Slic3r-console.ico
index 64e818340..7d168c874 100644
--- a/resources/icons/Slic3r-console.ico
+++ b/resources/icons/Slic3r-console.ico
Binary files differ
diff --git a/resources/icons/Slic3r.ico b/resources/icons/Slic3r.ico
index 5765f77d2..9a92bb103 100644
--- a/resources/icons/Slic3r.ico
+++ b/resources/icons/Slic3r.ico
Binary files differ
diff --git a/resources/icons/Slic3r.png b/resources/icons/Slic3r.png
index 896cc4460..d480dc881 100644
--- a/resources/icons/Slic3r.png
+++ b/resources/icons/Slic3r.png
Binary files differ
diff --git a/resources/icons/Slic3r_128px.png b/resources/icons/Slic3r_128px.png
index e8b2e3e3e..006e95f51 100644
--- a/resources/icons/Slic3r_128px.png
+++ b/resources/icons/Slic3r_128px.png
Binary files differ
diff --git a/resources/icons/Slic3r_192px.png b/resources/icons/Slic3r_192px.png
index 9af2bfc74..2e08916fc 100644
--- a/resources/icons/Slic3r_192px.png
+++ b/resources/icons/Slic3r_192px.png
Binary files differ
diff --git a/resources/icons/Slic3r_192px_transparent.png b/resources/icons/Slic3r_192px_transparent.png
index f85c835b3..8b7165a60 100644
--- a/resources/icons/Slic3r_192px_transparent.png
+++ b/resources/icons/Slic3r_192px_transparent.png
Binary files differ
diff --git a/resources/localization/fr_FR/Slic3rPE.mo b/resources/localization/fr_FR/Slic3rPE.mo
index a304f789a..128106a4c 100644
--- a/resources/localization/fr_FR/Slic3rPE.mo
+++ b/resources/localization/fr_FR/Slic3rPE.mo
Binary files differ
diff --git a/resources/localization/fr_FR/Slic3rPE_fr.po b/resources/localization/fr_FR/Slic3rPE_fr.po
index 84bf2ffab..36a89e94d 100644
--- a/resources/localization/fr_FR/Slic3rPE_fr.po
+++ b/resources/localization/fr_FR/Slic3rPE_fr.po
@@ -1,7104 +1,4831 @@
msgid ""
msgstr ""
-"Project-Id-Version: \n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-17 13:39+0100\n"
-"PO-Revision-Date: \n"
-"Last-Translator: Oleksandra Iushchenko <yusanka@gmail.com>\n"
-"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 2.0.8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: Oleksandra Iushchenko <yusanka@gmail.com>\n"
+"Language-Team: \n"
-#: src/slic3r/GUI/AboutDialog.cpp:33
-msgid "About Slic3r"
-msgstr "A propos de Slic3r"
-
-#: src/slic3r/GUI/AboutDialog.cpp:68 src/slic3r/GUI/MainFrame.cpp:51
-msgid "Version"
-msgstr "Version"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:43
-msgid "Shape"
-msgstr "Forme"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:50
-msgid "Rectangular"
-msgstr "Rectangle"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:54
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:207 src/slic3r/GUI/Plater.cpp:125
-#: src/slic3r/GUI/Tab.cpp:2122
-msgid "Size"
-msgstr "Taille"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:55
-msgid "Size in X and Y of the rectangular plate."
-msgstr "Taille en X et Y du plateau rectangulaire."
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:61
-msgid "Origin"
-msgstr "Origine"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:62
-msgid ""
-"Distance of the 0,0 G-code coordinate from the front left corner of the "
-"rectangle."
-msgstr ""
-"Distance des coordonnées 0,0 du G-code depuis le coin avant gauche du "
-"rectangle."
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:66
-msgid "Circular"
-msgstr "Circulaire"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:69 src/slic3r/GUI/ConfigWizard.cpp:92
-#: src/slic3r/GUI/ConfigWizard.cpp:456 src/slic3r/GUI/ConfigWizard.cpp:470
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:204
-#: src/slic3r/GUI/RammingChart.cpp:81 src/slic3r/GUI/WipeTowerDialog.cpp:80
-#: src/libslic3r/PrintConfig.cpp:50 src/libslic3r/PrintConfig.cpp:58
-#: src/libslic3r/PrintConfig.cpp:180 src/libslic3r/PrintConfig.cpp:254
-#: src/libslic3r/PrintConfig.cpp:263 src/libslic3r/PrintConfig.cpp:315
-#: src/libslic3r/PrintConfig.cpp:326 src/libslic3r/PrintConfig.cpp:448
-#: src/libslic3r/PrintConfig.cpp:460 src/libslic3r/PrintConfig.cpp:480
-#: src/libslic3r/PrintConfig.cpp:679 src/libslic3r/PrintConfig.cpp:1178
-#: src/libslic3r/PrintConfig.cpp:1243 src/libslic3r/PrintConfig.cpp:1263
-#: src/libslic3r/PrintConfig.cpp:1283 src/libslic3r/PrintConfig.cpp:1365
-#: src/libslic3r/PrintConfig.cpp:1376 src/libslic3r/PrintConfig.cpp:1499
-#: src/libslic3r/PrintConfig.cpp:1508 src/libslic3r/PrintConfig.cpp:1554
-#: src/libslic3r/PrintConfig.cpp:1563 src/libslic3r/PrintConfig.cpp:1574
-#: src/libslic3r/PrintConfig.cpp:1583 src/libslic3r/PrintConfig.cpp:1592
-#: src/libslic3r/PrintConfig.cpp:1682 src/libslic3r/PrintConfig.cpp:1918
-#: src/libslic3r/PrintConfig.cpp:1995 src/libslic3r/PrintConfig.cpp:2031
-#: src/libslic3r/PrintConfig.cpp:2241 src/libslic3r/PrintConfig.cpp:2249
-#: src/libslic3r/PrintConfig.cpp:2257 src/libslic3r/PrintConfig.cpp:2291
-#: src/libslic3r/PrintConfig.cpp:2302 src/libslic3r/PrintConfig.cpp:2313
-#: src/libslic3r/PrintConfig.cpp:2321 src/libslic3r/PrintConfig.cpp:2328
-#: src/libslic3r/PrintConfig.cpp:2424 src/libslic3r/PrintConfig.cpp:2497
-#: src/libslic3r/PrintConfig.cpp:2506 src/libslic3r/PrintConfig.cpp:2515
-#: src/libslic3r/PrintConfig.cpp:2524 src/libslic3r/PrintConfig.cpp:2560
-#: src/libslic3r/PrintConfig.cpp:2569 src/libslic3r/PrintConfig.cpp:2587
-#: src/libslic3r/PrintConfig.cpp:2596 src/libslic3r/PrintConfig.cpp:2623
-#: src/libslic3r/PrintConfig.cpp:2639 src/libslic3r/PrintConfig.cpp:2648
-#: src/libslic3r/PrintConfig.cpp:2657 src/libslic3r/PrintConfig.cpp:2666
-msgid "mm"
-msgstr "mm"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:70 src/libslic3r/PrintConfig.cpp:676
-msgid "Diameter"
-msgstr "Diamètre"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:71
-msgid ""
-"Diameter of the print bed. It is assumed that origin (0,0) is located in the "
-"center."
-msgstr ""
-"Diamètre du plateau d'impression. Il est supposé que l'origine (0,0) est "
-"située au centre."
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:75 src/slic3r/GUI/GUI_Preview.cpp:265
-#: src/libslic3r/GCode/PreviewData.cpp:175
-msgid "Custom"
-msgstr "Personnalisé"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:79
-msgid "Load shape from STL..."
-msgstr "Charger une forme depuis un STL..."
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:125
-msgid "Settings"
-msgstr "Réglages"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:298
-msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):"
-msgstr ""
-"Choisir un fichier à partir duquel importer la forme du plateau (STL/OBJ/"
-"AMF/3MF/PRUSA) :"
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:315 src/slic3r/GUI/GUI_ObjectList.cpp:835
-msgid "Error! "
-msgstr "Erreur ! "
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:324
-msgid "The selected file contains no geometry."
-msgstr "Le fichier sélectionné ne contient aucune géométrie."
-
-#: src/slic3r/GUI/BedShapeDialog.cpp:328
-msgid ""
-"The selected file contains several disjoint areas. This is not supported."
-msgstr ""
-"Le fichier sélectionné contient plusieurs zones disjointes. Cela n'est pas "
-"utilisable."
-
-#: src/slic3r/GUI/BedShapeDialog.hpp:44 src/slic3r/GUI/ConfigWizard.cpp:419
-msgid "Bed Shape"
-msgstr "Forme du plateau"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:54
-msgid "Network lookup"
-msgstr "Recherche réseau"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:67
-msgid "Address"
-msgstr "Adresse"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:68
-msgid "Hostname"
-msgstr "Nom d'hôte"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:69
-msgid "Service name"
-msgstr "Nom du service"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:70
-msgid "OctoPrint version"
-msgstr "Version d'OctoPrint"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:188
-msgid "Searching for devices"
-msgstr "Recherche des dispositifs"
-
-#: src/slic3r/GUI/BonjourDialog.cpp:195
-msgid "Finished"
-msgstr "Terminé"
-
-#: src/slic3r/GUI/ButtonsDescription.cpp:15
-msgid "Buttons And Text Colors Description"
-msgstr "Description des Boutons et des Couleurs de Texte"
-
-#: src/slic3r/GUI/ButtonsDescription.cpp:40
-msgid "Value is the same as the system value"
-msgstr "La valeur est identique à la valeur du système"
-
-#: src/slic3r/GUI/ButtonsDescription.cpp:57
-msgid ""
-"Value was changed and is not equal to the system value or the last saved "
-"preset"
-msgstr ""
-"La valeur a été changée et n'est pas égale à la valeur du système ou au "
-"dernier préréglage sauvegardé"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:16
-msgid "Upgrade"
-msgstr "Mise à jour"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:18
-msgid "Downgrade"
-msgstr "Rétrograder"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:20
-msgid "Before roll back"
-msgstr "Avant le retour en arrière"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:22
-msgid "User"
-msgstr "Utilisateur"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:25
-msgid "Unknown"
-msgstr "Inconnu"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:37
-msgid "Active: "
-msgstr "Actif : "
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:43
-msgid "slic3r version"
-msgstr "version de slic3r"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:44 src/slic3r/GUI/Preset.cpp:1156
-msgid "print"
-msgstr "imprimer"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:45
-msgid "filaments"
-msgstr "filaments"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:46 src/slic3r/GUI/Preset.cpp:1160
-msgid "printer"
-msgstr "imprimer"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:50 src/slic3r/GUI/Tab.cpp:838
-msgid "vendor"
-msgstr "fabriquant"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:50
-msgid "version"
-msgstr "version"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:51
-msgid "min slic3r version"
-msgstr "version minimale de slic3r"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:53
-msgid "max slic3r version"
-msgstr "version maximale de slic3r"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:56
-msgid "model"
-msgstr "modèle"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:56
-msgid "variants"
-msgstr "variantes"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:68
-msgid "Incompatible with this Slic3r"
-msgstr "Incompatible avec ce Slic3r"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:71
-msgid "Activate"
-msgstr "Activer"
-
-#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:97
-msgid "Configuration Snapshots"
-msgstr "Instantanés de Configuration"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:92
-msgid "nozzle"
-msgstr "buse"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:93
-msgid "default"
-msgstr "défaut"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:116
-msgid "Select all"
-msgstr "Tout sélectionner"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:117
-msgid "Select none"
-msgstr "Ne sélectionner aucun"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:226
-#, c-format
-msgid "Welcome to the Slic3r %s"
-msgstr "Bienvenue sur Slic3r %s"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:226
-msgid "Welcome"
-msgstr "Bienvenue"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:232 src/slic3r/GUI/GUI_App.cpp:606
-#, c-format
-msgid "Run %s"
-msgstr "Run %s"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:234
-#, 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 ""
-"Bonjour, bienvenu dans Slic3r Prusa Edition ! Ce %s vous aide à la "
-"configuration initiale ; juste quelques paramètres et vous serez prêt à "
-"imprimer."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:238
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1488
msgid ""
-"Remove user profiles - install from scratch (a snapshot will be taken "
-"beforehand)"
+"\n"
+"\n"
+"and it has the following unsaved changes:"
msgstr ""
-"Supprimer les profils d'utilisateur - installation à partir de zéro (un "
-"snapshot sera fait avant)"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:263
-msgid "Other vendors"
-msgstr "Autres fabriquants"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:265
-msgid "Custom setup"
-msgstr "Configuration personnalisée"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:289
-msgid "Automatic updates"
-msgstr "Mises à jour automatiques"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:289
-msgid "Updates"
-msgstr "Mises à jour"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:297 src/slic3r/GUI/Preferences.cpp:59
-msgid "Check for application updates"
-msgstr "Vérifier les mises à jour de l'application"
+"\n"
+"\n"
+"et il y a les changements non sauvegardés suivants :"
-#: src/slic3r/GUI/ConfigWizard.cpp:300 src/slic3r/GUI/Preferences.cpp:61
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1491
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."
+"\n"
+"\n"
+"Discard changes and continue anyway?"
msgstr ""
-"Si activé, Slic3r vérifie en ligne l'existence de nouvelles versions de "
-"Slic3r PE. Lorsqu'une nouvelle version est disponible, une notification est "
-"affichée au démarrage suivant de l'application (jamais pendant l'utilisation "
-"du programme). Ceci est uniquement un mécanisme de notification, aucune "
-"installation automatique n'est faite."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:304 src/slic3r/GUI/Preferences.cpp:67
-msgid "Update built-in Presets automatically"
-msgstr "Mettre à jour automatiquement les Préréglages intégrés"
+"\n"
+"\n"
+"Annuler les changements et continuer malgré tout ?"
-#: src/slic3r/GUI/ConfigWizard.cpp:307 src/slic3r/GUI/Preferences.cpp:69
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1489
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."
+"\n"
+"\n"
+"has the following unsaved changes:"
msgstr ""
-"Si activé, Slic3r télécharge les mises à jours des préréglages système "
-"intégrés en arrière-plan. Ces mises à jour sont téléchargées dans un "
-"répertoire temporaire séparé. Lorsqu'une nouvelle version de préréglages est "
-"disponible, elle est proposée au démarrage de l'application."
+"\n"
+"\n"
+"a les changements suivants non-enregistrés :"
-#: src/slic3r/GUI/ConfigWizard.cpp:308
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1488
msgid ""
-"Updates are never applied without user's consent and never overwrite user's "
-"customized settings."
+"\n"
+"\n"
+"is not compatible with printer\n"
msgstr ""
-"Les mises à jour ne sont jamais appliquées sans l'accord de l'utilisateur et "
-"n'annulent jamais les réglages personnalisés de l'utilisateur."
+"\n"
+"\n"
+"n'est pas compatible avec l'imprimante\n"
-#: src/slic3r/GUI/ConfigWizard.cpp:313
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:34
msgid ""
-"Additionally a backup snapshot of the whole configuration is created before "
-"an update is applied."
-msgstr ""
-"De plus, un instantané de sauvegarde de l'ensemble de la configuration est "
-"créé avant qu'une mise à jour ne soit appliquée."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:320
-msgid "Other Vendors"
-msgstr "Autres Fabriquants"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:322
-msgid "Pick another vendor supported by Slic3r PE:"
-msgstr "Choisissez un autre fabriquant supporté par Slic3r PE :"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:381
-msgid "Firmware Type"
-msgstr "Type de Firmware"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:381 src/slic3r/GUI/Tab.cpp:1820
-msgid "Firmware"
-msgstr "Firmware"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:385
-msgid "Choose the type of firmware used by your printer."
-msgstr "Choisissez le type de firmware utilisé par votre imprimante."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:419
-msgid "Bed Shape and Size"
-msgstr "Forme du Plateau et Taille"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:422
-msgid "Set the shape of your printer's bed."
-msgstr "Réglez la forme du plateau de votre imprimante."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:436
-msgid "Filament and Nozzle Diameters"
-msgstr "Diamètres du Filament et de la Buse"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:436
-msgid "Print Diameters"
-msgstr "Diamètres d'Impression"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:452
-msgid "Enter the diameter of your printer's hot end nozzle."
+"\n"
+"During the other layers, fan "
msgstr ""
-"Entrez le diamètre de la buse de la tête d'impression de votre imprimante."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:455
-msgid "Nozzle Diameter:"
-msgstr "Diamètre de la Buse :"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:465
-msgid "Enter the diameter of your filament."
-msgstr "Entrez le diamètre de votre filament."
+"\n"
+"Pendant les autres couches, le ventilateur "
-#: src/slic3r/GUI/ConfigWizard.cpp:466
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:30
+#, c-format
msgid ""
-"Good precision is required, so use a caliper and do multiple measurements "
-"along the filament, then compute the average."
-msgstr ""
-"Une bonne précision est requise, utilisez un pied à coulisse et calculez la "
-"moyenne de plusieurs mesures le long du filament."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:469
-msgid "Filament Diameter:"
-msgstr "Diamètre du Filament :"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:487
-msgid "Extruder and Bed Temperatures"
-msgstr "Températures de l'Extrudeur et du Lit"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:487
-msgid "Temperatures"
-msgstr "Températures"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:503
-msgid "Enter the temperature needed for extruding your filament."
-msgstr "Entrez la température nécessaire pour extruder votre filament."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:504
-msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS."
+"\n"
+"If estimated layer time is greater, but still below ~%ds, fan will run at a proportionally decreasing speed between %d%% and %d%%."
msgstr ""
-"La règle générale est 160 à 230 °C pour le PLA et 215 à 250 °C pour l'ABS."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:507
-msgid "Extrusion Temperature:"
-msgstr "Température d'Extrusion :"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:508 src/slic3r/GUI/ConfigWizard.cpp:522
-msgid "°C"
-msgstr "°C"
+"\n"
+"Si le temps estimé pour la couche est supérieur, mais cependant inférieur à ~%ds, le ventilateur tournera à une vitesse proportionnellement décroissante entre %d%% et %d%%."
-#: src/slic3r/GUI/ConfigWizard.cpp:517
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:927
msgid ""
-"Enter the bed temperature needed for getting your filament to stick to your "
-"heated bed."
+"\n"
+"Non-positive value."
msgstr ""
-"Entrez la température du lit nécessaire pour que votre filament colle à "
-"votre lit chauffant."
+"\n"
+"Valeur non-positive."
-#: src/slic3r/GUI/ConfigWizard.cpp:518
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:928
msgid ""
-"A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have "
-"no heated bed."
-msgstr ""
-"La règle générale est 60 °C pour le PLA et 110 °C pour l'ABS. Laissez à zéro "
-"si vous n'avez pas de lit chauffant."
-
-#: src/slic3r/GUI/ConfigWizard.cpp:521
-msgid "Bed Temperature:"
-msgstr "Température du Plateau :"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:833
-msgid "< &Back"
-msgstr ""
-
-#: src/slic3r/GUI/ConfigWizard.cpp:834
-msgid "&Next >"
+"\n"
+"Not a numeric value."
msgstr ""
+"\n"
+"Valeur non-numérique."
-#: src/slic3r/GUI/ConfigWizard.cpp:835
-msgid "&Finish"
-msgstr "&Fin"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:906
-msgid "Configuration Wizard"
-msgstr "Assistant de Configuration"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:907
-msgid "Configuration &Wizard"
-msgstr "&Assistant de Configuration"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:909
-msgid "Configuration Assistant"
-msgstr "Assistant de Configuration"
-
-#: src/slic3r/GUI/ConfigWizard.cpp:910
-msgid "Configuration &Assistant"
-msgstr "&Assistant de Configuration"
-
-#: src/slic3r/GUI/Field.cpp:109
-msgid "default value"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:66
+msgid " - Remember to check for updates at http://github.com/supermerill/slic3r/releases"
+msgstr " - Pensez à vérifier les mises à jours sur http://github.com/supermerill/slic3r/releases"
-#: src/slic3r/GUI/Field.cpp:112
-msgid "parameter name"
-msgstr ""
+# Used in this context: _("Save ") + title + _(" as:")
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1751
+msgid " as:"
+msgstr " sous :"
-#: src/slic3r/GUI/Field.cpp:140
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:226
#, c-format
-msgid "%s doesn't support percentage"
-msgstr "%s ne supporte pas un pourcentage"
+msgid " at filament speed %3.2f mm/s."
+msgstr " à une vitesse de filament de %3.2f mm/s."
-#: src/slic3r/GUI/Field.cpp:148 src/slic3r/GUI/Field.cpp:168
-msgid ""
-"Input value contains incorrect symbol(s).\n"
-"Use, please, only digits"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1035
+msgid " Browse "
+msgstr " Parcourir "
-#: src/slic3r/GUI/Field.cpp:153
-msgid "Input value is out of range"
-msgstr "La valeur entrée est hors plage"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:215
+msgid " flow rate is maximized "
+msgstr " le débit est maximisé "
-#: src/slic3r/GUI/Field.cpp:176
-#, c-format
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:662
+#, no-c-format
msgid ""
-"Do you mean %d%% instead of %d %s?\n"
-"Select YES if you want to change this value to %d%%, \n"
-"or NO if you are sure that %d %s is a correct value."
+" infill pattern is not supposed to work at 100% density.\n"
+"\n"
+"Shall I switch to rectilinear fill pattern?"
msgstr ""
+" le motif de remplissage n'est pas supposé fonctionner à une densité de 100%.\n"
+"\n"
+"Dois-je passer au motif de remplissage rectiligne ?"
-#: src/slic3r/GUI/Field.cpp:179
-msgid "Parameter validation"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1470
+msgid " preset\n"
+msgstr " préréglage\n"
-#: src/slic3r/GUI/FirmwareDialog.cpp:133
-msgid "Flash!"
-msgstr "Flash !"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1469
+msgid " preset"
+msgstr " préréglage"
-#: src/slic3r/GUI/FirmwareDialog.cpp:134 src/slic3r/GUI/GLGizmo.cpp:2270
-msgid "Cancel"
-msgstr "Annuler"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1583
+msgid " Preset"
+msgstr " Préréglage"
-#: src/slic3r/GUI/FirmwareDialog.cpp:135
-msgid "Flashing in progress. Please do not disconnect the printer!"
-msgstr ""
-"Processus de flash en cours. Veuillez ne pas déconnecter l'imprimante !"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:942
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1637
+msgid " Set "
+msgstr " Appliquer "
-#: src/slic3r/GUI/FirmwareDialog.cpp:245
-msgid "Flashing succeeded!"
-msgstr "Flash effectué avec succès !"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1581
+msgid " the selected preset?"
+msgstr " le préréglage sélectionné ?"
-#: src/slic3r/GUI/FirmwareDialog.cpp:246
-msgid "Flashing failed. Please see the avrdude log below."
-msgstr ""
-"Le processus de flash a échoué. Veuillez consulter le journal avrdude ci-"
-"dessous."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:548
+msgid " was successfully sliced."
+msgstr " a été découpé avec succès."
-#: src/slic3r/GUI/FirmwareDialog.cpp:247
-msgid "Flashing cancelled."
-msgstr "Processus de flash annulé."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:220
+msgid " with a volumetric rate "
+msgstr " avec un débit volumétrique "
-#: src/slic3r/GUI/FirmwareDialog.cpp:279
-#, c-format
-msgid "Flashing failed: %s"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:99
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:504
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:789
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:850
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1060
+msgid "%"
+msgstr "%"
-#: src/slic3r/GUI/FirmwareDialog.cpp:293
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:224
#, c-format
-msgid ""
-"This firmware hex file does not match the printer model.\n"
-"The hex file is intended for: %s\n"
-"Printer reported: %s\n"
-"\n"
-"Do you want to continue and flash this hex file anyway?\n"
-"Please only continue if you are sure this is the right thing to do."
-msgstr ""
+msgid "%3.2f mm³/s"
+msgstr "%3.2f mm³/s"
-#: src/slic3r/GUI/FirmwareDialog.cpp:380 src/slic3r/GUI/FirmwareDialog.cpp:414
-msgid ""
-"Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at "
-"a time for flashing."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1958
+#, perl-format
+msgid "%d (%d shells)"
+msgstr "%d (%d coques)"
-#: src/slic3r/GUI/FirmwareDialog.cpp:508
-msgid "The device could not have been found"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1965
+#, perl-format
+msgid "%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d facets reversed, %d backwards edges"
+msgstr "%d faces invalides, %d arrêtes corrigées, %d faces retirées, %d faces ajoutées, %d faces inversées, %d arrêtes à l'envers"
-#: src/slic3r/GUI/FirmwareDialog.cpp:581
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:269
#, c-format
-msgid "Error accessing port at %s: %s"
-msgstr ""
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:690
-msgid "Firmware flasher"
-msgstr "Outil de flash du firmware"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:712
-msgid "Firmware image:"
-msgstr "Image du firmware :"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:716
-msgid "Serial port:"
-msgstr "Port série :"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:718
-msgid "Autodetected"
-msgstr ""
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:719
-msgid "Rescan"
-msgstr "Scanner à nouveau"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:726
-msgid "Progress:"
-msgstr "Progression :"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:729
-msgid "Status:"
-msgstr "État :"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:730
-msgid "Ready"
-msgstr "Prêt"
-
-#: src/slic3r/GUI/FirmwareDialog.cpp:750
-msgid "Advanced: avrdude output log"
-msgstr "Avancé : journal de sortie avrdude"
+msgid "%d lines: %.2lf mm"
+msgstr "%d lignes : %.2lf mm"
-#: src/slic3r/GUI/FirmwareDialog.cpp:809
-msgid ""
-"Are you sure you want to cancel firmware flashing?\n"
-"This could leave your printer in an unusable state!"
-msgstr ""
-"Êtes-vous certain de vouloir annuler le processus de flash du firmware ?\n"
-"Cela pourrait rendre votre imprimante inutilisable !"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:687
+#, perl-format
+msgid "%d presets successfully imported."
+msgstr "%d préréglages importés avec succès."
-#: src/slic3r/GUI/FirmwareDialog.cpp:810
-msgid "Confirmation"
-msgstr "Confirmation"
+#: xs/src/slic3r/GUI/Field.cpp:102
+#, c-format
+msgid "%s doesn't support percentage"
+msgstr "%s ne supporte pas un pourcentage"
-#: src/slic3r/GUI/FirmwareDialog.cpp:813
-msgid "Cancelling..."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:408
+msgid "&About Slic3r"
+msgstr "&A propos de Slic3r"
-#: src/slic3r/GUI/GLCanvas3D.cpp:4640
-msgid "Detected object outside print volume"
-msgstr ""
+#: xs/src/slic3r/GUI/GUI.cpp:466
+msgid "&Configuration"
+msgstr "&Configuration"
-#: src/slic3r/GUI/GLCanvas3D.cpp:7962
-msgid "Detected toolpath outside print volume"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:263
+msgid "&Export Config Bundle…"
+msgstr "&Exporter le Lot de Configurations…"
-#: src/slic3r/GUI/GLGizmo.cpp:751 src/slic3r/GUI/GUI_ObjectManipulation.cpp:300
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:322
-#: src/libslic3r/PrintConfig.cpp:3087
-msgid "Rotate"
-msgstr "Pivoter"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:257
+msgid "&Export Config…\tCtrl+E"
+msgstr "&Exporter la configuration…\tCtrl+E"
-#: src/slic3r/GUI/GLGizmo.cpp:785
-msgid "Rotation (deg)"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:418
+msgid "&File"
+msgstr "&Fichier"
-#: src/slic3r/GUI/GLGizmo.cpp:841 src/slic3r/GUI/GUI_ObjectManipulation.cpp:206
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:301
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:323
-#: src/libslic3r/PrintConfig.cpp:3111
-msgid "Scale"
-msgstr "Redimensionner"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:791
+msgid "&Finish"
+msgstr "&Fin"
-#: src/slic3r/GUI/GLGizmo.cpp:1072
-msgid "Scale (%)"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:426
+msgid "&Help"
+msgstr "&Aide"
-#: src/slic3r/GUI/GLGizmo.cpp:1200
-msgid "Move"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:260
+msgid "&Load Config Bundle…"
+msgstr "&Charger le Lot de Configurations…"
-#: src/slic3r/GUI/GLGizmo.cpp:1326
-msgid "Position (mm)"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:254
+msgid "&Load Config…\tCtrl+L"
+msgstr "&Charger la configuration…\tCtrl+L"
-#: src/slic3r/GUI/GLGizmo.cpp:1326
-msgid "Displacement (mm)"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:420
+msgid "&Object"
+msgstr "&Objet"
-#: src/slic3r/GUI/GLGizmo.cpp:1430
-msgid "Place on face"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:419
+msgid "&Plater"
+msgstr "&Plateau"
-#: src/slic3r/GUI/GLGizmo.cpp:2207
-msgid "Left mouse click - add point"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:304
+msgid "&Quit"
+msgstr "&Quitter"
-#: src/slic3r/GUI/GLGizmo.cpp:2208
-msgid "Right mouse click - remove point"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:280
+msgid "&Repeat Last Quick Slice\tCtrl+Shift+U"
+msgstr "&Répéter la dernière découpe rapide\tCtrl+Shift+U"
-#: src/slic3r/GUI/GLGizmo.cpp:2211
-msgid "Generate points automatically"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:422
+msgid "&View"
+msgstr "&Vue"
-#: src/slic3r/GUI/GLGizmo.cpp:2212
-msgid "Remove all points"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:421
+msgid "&Window"
+msgstr "&Fenêtre"
-#: src/slic3r/GUI/GLGizmo.cpp:2245
-msgid "SLA Support Points"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:291
+msgid "(&Re)Slice Now\tCtrl+S"
+msgstr "(&Re)Découper maintenant\tCtrl+S"
-#: src/slic3r/GUI/GLGizmo.cpp:2268 src/slic3r/GUI/GLGizmo.cpp:2468
-msgid "Rotate lower part upwards"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:994
+msgid "(minimum)"
+msgstr "(minimum)"
-#: src/slic3r/GUI/GLGizmo.cpp:2269 src/slic3r/GUI/GLGizmo.cpp:2470
-msgid "Perform cut"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:474
+msgid ") not found."
+msgstr ") non trouvé."
-#: src/slic3r/GUI/GLGizmo.cpp:2276
-msgid "Cut object:"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:749
+msgid ". Discard changes and continue anyway?"
+msgstr ". Annuler les changements et continuer malgré tout ?"
-#: src/slic3r/GUI/GLGizmo.cpp:2356 src/slic3r/GUI/GLGizmo.cpp:2461
-#: src/libslic3r/PrintConfig.cpp:3016
-msgid "Cut"
-msgstr "Couper"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:63
+msgid "1 Layer"
+msgstr "1 Couche"
-#: src/slic3r/GUI/GLGizmo.cpp:2466
-msgid "Keep upper part"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:138
+msgid "2D"
+msgstr "2D"
-#: src/slic3r/GUI/GLGizmo.cpp:2467
-msgid "Keep lower part"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:104
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2124
+msgid "3D"
+msgstr "3D"
-#: src/slic3r/GUI/GUI.cpp:242
-msgid "Notice"
-msgstr "Remarque"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1608
+msgid "3MF file exported to "
+msgstr "Fichier 3MF exporté vers "
-#: src/slic3r/GUI/GUI.cpp:248
-msgid "Attempt to free unreferenced scalar"
-msgstr "Tentative de libération d'un scalaire non référencé"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:185
+msgid "45° ccw"
+msgstr "45° ccw"
-#: src/slic3r/GUI/GUI.cpp:250 src/slic3r/GUI/WipeTowerDialog.cpp:40
-#: src/slic3r/GUI/WipeTowerDialog.cpp:322
-msgid "Warning"
-msgstr "Alerte"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:186
+msgid "45° cw"
+msgstr "45° cw"
-#: src/slic3r/GUI/GUI_App.cpp:377
-msgid "Choose one file (3MF):"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:148
+msgid "A boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile."
+msgstr "Une expression booléenne utilisant les valeurs de configuration d'un profil d'imprimante actif. Si cette expression est évaluée comme vraie, ce profil est considéré comme compatible avec le profil d'imprimante actif."
-#: src/slic3r/GUI/GUI_App.cpp:389
-msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"
-msgstr "Choisir un ou plusieurs fichiers (STL/OBJ/AMF/3MF/PRUSA) :"
+#: 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 "La règle générale est 160 à 230 °C pour le PLA et 215 à 250 °C pour l'ABS."
-#: src/slic3r/GUI/GUI_App.cpp:451
-msgid "Array of language names and identifiers should have the same size."
-msgstr ""
-"Les tableaux de noms et d'identifiants de langue doivent avoir la même "
-"taille."
+#: 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 "La règle générale est 60 °C pour le PLA et 110 °C pour l'ABS. Laissez à zéro si vous n'avez pas de lit chauffant."
-#: src/slic3r/GUI/GUI_App.cpp:461
-msgid "Select the language"
-msgstr "Sélectionner la langue"
+#: xs/src/slic3r/GUI/AboutDialog.cpp:32
+msgid "About Slic3r"
+msgstr "A propos de Slic3r"
-#: src/slic3r/GUI/GUI_App.cpp:461
-msgid "Language"
-msgstr "Langue"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1099
+msgid "Above Z"
+msgstr "Au-delà de Z"
-#: src/slic3r/GUI/GUI_App.cpp:529 src/libslic3r/PrintConfig.cpp:270
-msgid "Default"
-msgstr "Défaut"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:417
+msgid "Acceleration control (advanced)"
+msgstr "Contrôle de l'accélération (avancé)"
-#: src/slic3r/GUI/GUI_App.cpp:609
-msgid "&Configuration Snapshots"
-msgstr "Instantanés de &Configuration"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:70
+msgid "Activate"
+msgstr "Activer"
-#: src/slic3r/GUI/GUI_App.cpp:609
-msgid "Inspect / activate configuration snapshots"
-msgstr "Inspecter / activer les instantanés de configuration"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:36
+msgid "Active: "
+msgstr "Actif : "
-#: src/slic3r/GUI/GUI_App.cpp:610
-msgid "Take Configuration &Snapshot"
-msgstr "Prendre un &snapshot de la configuration"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1566
+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 "Ajouter une enveloppe (une ligne unique de périmètre) autour de la base du support. Ceci rend le support plus fiable, mais aussi plus difficile à retirer."
-#: src/slic3r/GUI/GUI_App.cpp:610
-msgid "Capture a configuration snapshot"
-msgstr "Capturer un instantané de la configuration"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:299
+#, 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 "Ajouter plus de périmètres si nécessaire pour éviter des trous dans les parois inclinées. Slic3r ajoute des périmètres, jusqu'à ce que plus de 70% de la boucle immédiatement au-dessus soit supportée."
-#: src/slic3r/GUI/GUI_App.cpp:613
-msgid "&Preferences"
-msgstr "&Préférences"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:240
+msgid "Add solid infill near sloping surfaces to guarantee the vertical shell thickness (top+bottom solid layers)."
+msgstr "Ajouter un remplissage plein à proximité des surfaces inclinées pour garantir une épaisseur de coque verticale (couches pleines supérieures+inférieures)."
-#: src/slic3r/GUI/GUI_App.cpp:613
-msgid "Application preferences"
-msgstr "Préférences de l'application"
+#: xs/src/slic3r/GUI/Tab.cpp:754
+msgid "Additional information:"
+msgstr "Informations complémentaires :"
-#: src/slic3r/GUI/GUI_App.cpp:616
-msgid "Simple"
-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 "De plus, un instantané de sauvegarde de l'ensemble de la configuration est créé avant qu'une mise à jour ne soit appliquée."
-#: src/slic3r/GUI/GUI_App.cpp:616
-msgid "Simple View Mode"
-msgstr ""
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:66
+msgid "Address"
+msgstr "Adresse"
-#: src/slic3r/GUI/GUI_App.cpp:617 src/slic3r/GUI/GUI_ObjectList.cpp:39
-#: src/slic3r/GUI/Tab.cpp:948 src/slic3r/GUI/Tab.cpp:962
-#: src/slic3r/GUI/Tab.cpp:1058 src/slic3r/GUI/Tab.cpp:1061
-#: src/slic3r/GUI/Tab.cpp:1425 src/slic3r/GUI/Tab.cpp:1840
-#: src/libslic3r/PrintConfig.cpp:156 src/libslic3r/PrintConfig.cpp:323
-#: src/libslic3r/PrintConfig.cpp:999 src/libslic3r/PrintConfig.cpp:2298
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:177
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:195
+msgid "Add…"
+msgstr "Ajouter…"
+
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:342
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:356
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:449
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:452
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:831
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1113
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:107
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:208
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:736
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1733
msgid "Advanced"
msgstr "Avancé"
-#: src/slic3r/GUI/GUI_App.cpp:617
-msgid "Advanced View Mode"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_App.cpp:618
-msgid "Expert"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_App.cpp:618
-msgid "Expert View Mode"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_App.cpp:620
-msgid "Mode"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:319
+msgid "Advanced: avrdude output log"
+msgstr "Avancé : journal de sortie avrdude"
-#: src/slic3r/GUI/GUI_App.cpp:620
-msgid "Slic3r View Mode"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1138
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:766
+msgid "After layer change G-code"
+msgstr "G-Code après changement de couche"
-#: src/slic3r/GUI/GUI_App.cpp:622
-msgid "Change Application &Language"
-msgstr "Changer la &langue de l'application"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1636
+msgid "All"
+msgstr "Tous"
-#: src/slic3r/GUI/GUI_App.cpp:624
-msgid "Flash printer &firmware"
-msgstr "Flasher le &firmware de l'imprimante"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2057
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2073
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2089
+msgid "Along X axis…"
+msgstr "Le long de l'axe X…"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2060
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2076
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2092
+msgid "Along Y axis…"
+msgstr "Le long de l'axe Y…"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2063
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2079
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2095
+msgid "Along Z axis…"
+msgstr "Le long de l'axe Z…"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1592
+msgid "AMF file exported to "
+msgstr "Fichier AMF exporté vers "
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1300
+msgid "Another export job is currently running."
+msgstr "Une autre tâche d'export est actuellement en cours."
-#: src/slic3r/GUI/GUI_App.cpp:624
-msgid "Upload a firmware image into an Arduino based printer"
-msgstr "Charger un firmware dans une imprimante basée sur un Arduino"
+#: xs/src/slic3r/GUI/Tab.cpp:749
+msgid "Any modifications should be saved as a new preset inherited from this one. "
+msgstr "Toute modification doit être enregistrée comme un nouveau préréglage hérité de celui-ci. "
-#: src/slic3r/GUI/GUI_App.cpp:636
-msgid "Taking configuration snapshot"
-msgstr "Snapshot de la configuration en cours"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:901
+msgid "API Key"
+msgstr "Clé API"
-#: src/slic3r/GUI/GUI_App.cpp:636
-msgid "Snapshot name"
-msgstr "Nom du snapshot"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:299
+msgid "Application preferences"
+msgstr "Préférences de l'application"
-#: src/slic3r/GUI/GUI_App.cpp:674
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:332
msgid "Application will be restarted"
msgstr "L'application va être redémarrée"
-#: src/slic3r/GUI/GUI_App.cpp:674 src/slic3r/GUI/Tab.cpp:2606
-msgid "Attention!"
-msgstr "Attention !"
-
-#: src/slic3r/GUI/GUI_App.cpp:691
-msgid "&Configuration"
-msgstr "&Configuration"
-
-#: src/slic3r/GUI/GUI_App.cpp:711
-msgid "You have unsaved changes "
-msgstr "Les modifications n'ont pas été sauvegardées "
-
-#: src/slic3r/GUI/GUI_App.cpp:711
-msgid ". Discard changes and continue anyway?"
-msgstr ". Annuler les changements et continuer malgré tout ?"
-
-#: src/slic3r/GUI/GUI_App.cpp:712
-msgid "Unsaved Presets"
-msgstr "Préréglages Non Sauvegardés"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:31 src/libslic3r/PrintConfig.cpp:47
-#: src/libslic3r/PrintConfig.cpp:115 src/libslic3r/PrintConfig.cpp:357
-#: src/libslic3r/PrintConfig.cpp:410 src/libslic3r/PrintConfig.cpp:419
-#: src/libslic3r/PrintConfig.cpp:849 src/libslic3r/PrintConfig.cpp:1037
-#: src/libslic3r/PrintConfig.cpp:1354 src/libslic3r/PrintConfig.cpp:1426
-#: src/libslic3r/PrintConfig.cpp:1618 src/libslic3r/PrintConfig.cpp:2091
-#: src/libslic3r/PrintConfig.cpp:2150
-msgid "Layers and Perimeters"
-msgstr "Couches et Périmètres"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:32 src/slic3r/GUI/Tab.cpp:952
-#: src/slic3r/GUI/Tab.cpp:953 src/slic3r/GUI/Tab.cpp:1274
-#: src/libslic3r/PrintConfig.cpp:134 src/libslic3r/PrintConfig.cpp:366
-#: src/libslic3r/PrintConfig.cpp:730 src/libslic3r/PrintConfig.cpp:745
-#: src/libslic3r/PrintConfig.cpp:783 src/libslic3r/PrintConfig.cpp:938
-#: src/libslic3r/PrintConfig.cpp:949 src/libslic3r/PrintConfig.cpp:969
-#: src/libslic3r/PrintConfig.cpp:989 src/libslic3r/PrintConfig.cpp:1010
-#: src/libslic3r/PrintConfig.cpp:1733 src/libslic3r/PrintConfig.cpp:1752
-msgid "Infill"
-msgstr "Remplissage"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:33 src/slic3r/GUI/GUI_Preview.cpp:262
-#: src/slic3r/GUI/Tab.cpp:980 src/slic3r/GUI/Tab.cpp:981
-#: src/libslic3r/PrintConfig.cpp:305 src/libslic3r/PrintConfig.cpp:1484
-#: src/libslic3r/PrintConfig.cpp:1865 src/libslic3r/PrintConfig.cpp:1872
-#: src/libslic3r/PrintConfig.cpp:1881 src/libslic3r/PrintConfig.cpp:1894
-#: src/libslic3r/PrintConfig.cpp:1905 src/libslic3r/PrintConfig.cpp:1914
-#: src/libslic3r/PrintConfig.cpp:1930 src/libslic3r/PrintConfig.cpp:1953
-#: src/libslic3r/PrintConfig.cpp:1965 src/libslic3r/PrintConfig.cpp:1983
-#: src/libslic3r/PrintConfig.cpp:1993 src/libslic3r/PrintConfig.cpp:2003
-#: src/libslic3r/PrintConfig.cpp:2014 src/libslic3r/PrintConfig.cpp:2029
-#: src/libslic3r/PrintConfig.cpp:2038 src/libslic3r/PrintConfig.cpp:2039
-#: src/libslic3r/PrintConfig.cpp:2048 src/libslic3r/PrintConfig.cpp:2057
-#: src/libslic3r/PrintConfig.cpp:2072 src/libslic3r/GCode/PreviewData.cpp:172
-msgid "Support material"
-msgstr "Support"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:34 src/slic3r/GUI/GUI_Preview.cpp:241
-#: src/slic3r/GUI/Tab.cpp:1005 src/libslic3r/PrintConfig.cpp:169
-#: src/libslic3r/PrintConfig.cpp:398 src/libslic3r/PrintConfig.cpp:881
-#: src/libslic3r/PrintConfig.cpp:1011 src/libslic3r/PrintConfig.cpp:1416
-#: src/libslic3r/PrintConfig.cpp:1668 src/libslic3r/PrintConfig.cpp:1721
-#: src/libslic3r/PrintConfig.cpp:1776 src/libslic3r/PrintConfig.cpp:2136
-msgid "Speed"
-msgstr "Vitesse"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/Tab.cpp:1038
-#: src/slic3r/GUI/Tab.cpp:1744 src/libslic3r/PrintConfig.cpp:430
-#: src/libslic3r/PrintConfig.cpp:961 src/libslic3r/PrintConfig.cpp:1393
-#: src/libslic3r/PrintConfig.cpp:1743 src/libslic3r/PrintConfig.cpp:1944
-#: src/libslic3r/PrintConfig.cpp:1973 src/libslic3r/PrintConfig.cpp:2271
-#: src/libslic3r/PrintConfig.cpp:2280
-msgid "Extruders"
-msgstr "Extrudeurs"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:36 src/libslic3r/PrintConfig.cpp:387
-#: src/libslic3r/PrintConfig.cpp:504 src/libslic3r/PrintConfig.cpp:836
-#: src/libslic3r/PrintConfig.cpp:970 src/libslic3r/PrintConfig.cpp:1403
-#: src/libslic3r/PrintConfig.cpp:1765 src/libslic3r/PrintConfig.cpp:1954
-#: src/libslic3r/PrintConfig.cpp:2124
-msgid "Extrusion Width"
-msgstr "Largeur d'Extrusion"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:41 src/slic3r/GUI/Tab.cpp:3179
-#: src/slic3r/GUI/Tab.cpp:3180 src/libslic3r/PrintConfig.cpp:2488
-#: src/libslic3r/PrintConfig.cpp:2495 src/libslic3r/PrintConfig.cpp:2504
-#: src/libslic3r/PrintConfig.cpp:2513 src/libslic3r/PrintConfig.cpp:2522
-#: src/libslic3r/PrintConfig.cpp:2547 src/libslic3r/PrintConfig.cpp:2558
-#: src/libslic3r/PrintConfig.cpp:2567 src/libslic3r/PrintConfig.cpp:2576
-#: src/libslic3r/PrintConfig.cpp:2585 src/libslic3r/PrintConfig.cpp:2594
-#: src/libslic3r/PrintConfig.cpp:2603 src/libslic3r/PrintConfig.cpp:2612
-#: src/libslic3r/PrintConfig.cpp:2621
-msgid "Supports"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:42 src/slic3r/GUI/Tab.cpp:3205
-#: src/slic3r/GUI/Tab.cpp:3206 src/libslic3r/PrintConfig.cpp:2630
-#: src/libslic3r/PrintConfig.cpp:2637 src/libslic3r/PrintConfig.cpp:2646
-#: src/libslic3r/PrintConfig.cpp:2655 src/libslic3r/PrintConfig.cpp:2664
-msgid "Pad"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:115
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:129
-msgid "Name"
-msgstr "Nom"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:134
-msgid "Right button click the icon to change the object settings"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:142
-#, c-format
-msgid "Auto-repaired (%d errors):\n"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:145
-msgid "degenerate facets"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:146
-msgid "edges fixed"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:147
-msgid "facets removed"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:148
-msgid "facets added"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:149
-msgid "facets reversed"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:150
-msgid "backwards edges"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:164
-msgid "Right button click the icon to fix STL through Netfabb"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:196 src/slic3r/GUI/Tab.cpp:1389
-#: src/libslic3r/PrintConfig.cpp:429
-msgid "Extruder"
-msgstr "Extrudeur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:397
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1242
+msgid "approximate seconds"
+msgstr "secondes approximatives"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:615
-msgid "Select showing settings"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1581
+msgid "Are you sure you want to "
+msgstr "Êtes-vous sûr de vouloir "
-#: src/slic3r/GUI/GUI_ObjectList.cpp:655
-msgid "Load"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:365
+msgid ""
+"Are you sure you want to cancel firmware flashing?\n"
+"This could leave your printer in an unusable state!"
msgstr ""
+"Êtes-vous certain de vouloir annuler le processus de flash du firmware ?\n"
+"Cela pourrait rendre votre imprimante inutilisable !"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:659 src/slic3r/GUI/GUI_ObjectList.cpp:688
-#: src/slic3r/GUI/GUI_ObjectList.cpp:691
-msgid "Box"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2044
+msgid "Around X axis…"
+msgstr "Autour de l'axe X…"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:659
-msgid "Cylinder"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2047
+msgid "Around Y axis…"
+msgstr "Autour de l'axe Y…"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:659
-msgid "Sphere"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2050
+msgid "Around Z axis…"
+msgstr "Autour de l'axe Z…"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:659
-msgid "Slab"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:180
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:198
+msgid "Arrange"
+msgstr "Agencer"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:671 src/slic3r/GUI/GUI_ObjectList.cpp:685
-msgid "Add part"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:224
+msgid "Array of language names and identifiers should have the same size."
+msgstr "Les tableaux de noms et d'identifiants de langue doivent avoir la même taille."
-#: src/slic3r/GUI/GUI_ObjectList.cpp:672
-msgid "Add modifier"
-msgstr ""
+#: xs/src/slic3r/GUI/GUI.cpp:688
+msgid "Attempt to free unreferenced scalar"
+msgstr "Tentative de libération d'un scalaire non référencé"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:673 src/slic3r/GUI/GUI_ObjectList.cpp:687
-msgid "Add support enforcer"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:332
+msgid "Attention!"
+msgstr "Attention !"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:674 src/slic3r/GUI/GUI_ObjectList.cpp:690
-msgid "Add support blocker"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:35
+msgid "Auto-center parts"
+msgstr "Centrer automatiquement les pièces"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:711
-msgid "Split to parts"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1960
+#, perl-format
+msgid "Auto-repaired (%d errors)"
+msgstr "Réparé automatiquement (%d erreurs)"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:725
-msgid "Add settings"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:264
+msgid "Automatic updates"
+msgstr "Mises à jour automatiques"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:739
-msgid "Change type"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:294
+msgid "Automatically repair an STL file"
+msgstr "Réparer automatiquement un fichier STL"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1009
-msgid "You can't delete the last solid part from object."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:424
+msgid "Autospeed (advanced)"
+msgstr "Vitesse automatique (avancé)"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1017
-msgid "You can't delete the last intance from object."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:26
+msgid "Avoid crossing perimeters"
+msgstr "Éviter de traverser les périmètres"
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1044 src/slic3r/GUI/Plater.cpp:1825
+#: xs/src/slic3r/GUI/Tab.cpp:2491
msgid ""
-"The selected object couldn't be split because it contains only one part."
-msgstr ""
-"L'objet sélectionné n'a pu être scindé car il ne contient qu'une seule pièce."
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1138
-msgid "Group manipulation"
+"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 ""
+"L'icône FLÈCHE ARRIÈRE indique que les paramètres ont été changés et qu'ils ne sont pas identiques au dernier préréglage enregistré du groupe d'options en cours.\n"
+"Cliquez pour restaurer tous les paramètres du groupe d'options en cours avec les valeurs du dernier préréglage enregistré."
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1149
-msgid "Object manipulation"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1159
-msgid "Object Settings to modify"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1163
-msgid "Part Settings to modify"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1173
-msgid "Part manipulation"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1180
-msgid "Instance manipulation"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1655
-msgid "You can't change a type of the last solid part of the object."
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1662
-msgid "Select type of part"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1744 src/slic3r/GUI/Tab.cpp:3070
-#: src/slic3r/GUI/Tab.cpp:3074
-msgid "The supplied name is not valid;"
-msgstr "The supplied name is not valid;"
-
-#: src/slic3r/GUI/GUI_ObjectList.cpp:1745 src/slic3r/GUI/Tab.cpp:3071
-msgid "the following characters are not allowed:"
-msgstr "the following characters are not allowed:"
-
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:21
-msgid "Object Manipulation"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:132
-msgid "Object name"
-msgstr ""
-
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:204
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:252
-msgid "Position"
+#: 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 ""
+"L'icône FLÈCHE ARRIÈRE indique que la valeur a été changée et qu'elle n'est pas identique au dernier préréglage enregistré.\n"
+"Cliquez pour restaurer la valeur à celle du dernier préréglage enregistré."
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:205
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:253
-msgid "Rotation"
+#: 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 ""
+"FLÈCHE ARRIÈRE;indique que les paramètres ont été changés et qu'ils ne sont pas identiques au dernier préréglage enregistré du groupe d'options en cours.\n"
+"Cliquez sur l'icône FLÈCHE ARRIÈRE pour restaurer tous les paramètres du groupe d'options en cours avec les valeurs du dernier préréglage enregistré."
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:254
-msgid "Scale factors"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:43
+msgid "Background processing"
+msgstr "Tâche en arrière plan"
-#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:321
-msgid "Translate"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:800
+msgid "Bed"
+msgstr "Plateau"
-#: src/slic3r/GUI/GUI_Preview.cpp:235
-msgid "View"
-msgstr "Vue"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:940
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:34
+msgid "Bed shape"
+msgstr "Forme du plateau"
-#: src/slic3r/GUI/GUI_Preview.cpp:238 src/slic3r/GUI/GUI_Preview.cpp:550
-#: src/libslic3r/GCode/PreviewData.cpp:394
-msgid "Feature type"
-msgstr "Type de fonctionnalité"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.hpp:42
+msgid "Bed Shape"
+msgstr "Forme du plateau"
-#: src/slic3r/GUI/GUI_Preview.cpp:239 src/libslic3r/PrintConfig.cpp:443
-msgid "Height"
-msgstr "Hauteur"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:395
+msgid "Bed Shape and Size"
+msgstr "Forme du Plateau et Taille"
-#: src/slic3r/GUI/GUI_Preview.cpp:240 src/libslic3r/PrintConfig.cpp:2255
-msgid "Width"
-msgstr "Largeur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:42
+msgid "Bed temperature"
+msgstr "Température du plateau"
-#: src/slic3r/GUI/GUI_Preview.cpp:242
-msgid "Volumetric flow rate"
-msgstr "Débit volumétrique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:39
+msgid "Bed temperature for layers after the first one. Set this to zero to disable bed temperature control commands in the output."
+msgstr "Température du plateau pour les couches après la première. Mettez ceci à zéro pour désactiver les commandes de contrôle de température du plateau dans la sortie."
-#: src/slic3r/GUI/GUI_Preview.cpp:243 src/slic3r/GUI/GUI_Preview.cpp:347
-#: src/slic3r/GUI/GUI_Preview.cpp:496 src/slic3r/GUI/GUI_Preview.cpp:718
-#: src/libslic3r/GCode/PreviewData.cpp:404
-msgid "Tool"
-msgstr "Outil"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:497
+msgid "Bed Temperature:"
+msgstr "Température du Plateau :"
-#: src/slic3r/GUI/GUI_Preview.cpp:244 src/slic3r/GUI/GUI_Preview.cpp:550
-#: src/libslic3r/GCode/PreviewData.cpp:406
-msgid "Color Print"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1132
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:48
+msgid "Before layer change G-code"
+msgstr "G-Code avant changement de couche"
-#: src/slic3r/GUI/GUI_Preview.cpp:247
-msgid "Show"
-msgstr "Afficher"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:19
+msgid "Before roll back"
+msgstr "Avant le retour en arrière"
-#: src/slic3r/GUI/GUI_Preview.cpp:250 src/slic3r/GUI/GUI_Preview.cpp:251
-msgid "Feature types"
-msgstr "Types de fonctionnalité"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1108
+msgid "Below Z"
+msgstr "En-deçà de Z"
-#: src/slic3r/GUI/GUI_Preview.cpp:253 src/libslic3r/GCode/PreviewData.cpp:163
-msgid "Perimeter"
-msgstr "Périmètre"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:59
+msgid "Between objects G-code"
+msgstr "Entre le G-code des objets"
-#: src/slic3r/GUI/GUI_Preview.cpp:254 src/libslic3r/GCode/PreviewData.cpp:164
-msgid "External perimeter"
-msgstr "Périmètre externe"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1150
+msgid "Between objects G-code (for sequential printing)"
+msgstr "Entre le G-code des objets (pour une impression séquentielle)"
-#: src/slic3r/GUI/GUI_Preview.cpp:255 src/libslic3r/GCode/PreviewData.cpp:165
-msgid "Overhang perimeter"
-msgstr "Périmètre en surplomb"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:68
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:370
+msgid "Bottom"
+msgstr "Dessous"
-#: src/slic3r/GUI/GUI_Preview.cpp:256 src/libslic3r/GCode/PreviewData.cpp:166
-msgid "Internal infill"
-msgstr "Remplissage interne"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:72
+msgid "Bottom solid layers"
+msgstr "Couches pleines inférieures"
-#: src/slic3r/GUI/GUI_Preview.cpp:257 src/libslic3r/PrintConfig.cpp:1764
-#: src/libslic3r/PrintConfig.cpp:1775 src/libslic3r/GCode/PreviewData.cpp:167
-msgid "Solid infill"
-msgstr "Remplissage solide"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:370
+msgid "Bottom View"
+msgstr "Vue du Dessous"
-#: src/slic3r/GUI/GUI_Preview.cpp:258 src/libslic3r/PrintConfig.cpp:2123
-#: src/libslic3r/PrintConfig.cpp:2135 src/libslic3r/GCode/PreviewData.cpp:168
-msgid "Top solid infill"
-msgstr "Remplissage solide supérieur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:77
+msgid "Bridge"
+msgstr "Ponts"
-#: src/slic3r/GUI/GUI_Preview.cpp:259 src/libslic3r/GCode/PreviewData.cpp:169
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:144
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:86
msgid "Bridge infill"
msgstr "Remplissage du pont"
-#: src/slic3r/GUI/GUI_Preview.cpp:260 src/libslic3r/PrintConfig.cpp:880
-#: src/libslic3r/GCode/PreviewData.cpp:170
-msgid "Gap fill"
-msgstr "Remplissage des trous"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:261 src/slic3r/GUI/Tab.cpp:971
-#: src/libslic3r/GCode/PreviewData.cpp:171
-msgid "Skirt"
-msgstr "Jupe"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:263 src/libslic3r/PrintConfig.cpp:2002
-#: src/libslic3r/GCode/PreviewData.cpp:173
-msgid "Support material interface"
-msgstr "Interface des supports"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:264 src/slic3r/GUI/Tab.cpp:1049
-#: src/libslic3r/GCode/PreviewData.cpp:174
-msgid "Wipe tower"
-msgstr "Tour de nettoyage"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:269 src/libslic3r/PrintConfig.cpp:2158
-msgid "Travel"
-msgstr "Déplacement"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:270
-msgid "Retractions"
-msgstr "Rétractations"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:271
-msgid "Unretractions"
-msgstr "Dérétractation"
-
-#: src/slic3r/GUI/GUI_Preview.cpp:272
-msgid "Shells"
-msgstr "Coques"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:12
-msgid "Slic3r Prusa Edition - Keyboard Shortcuts"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:47
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:126
-msgid "Main Shortcuts"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:101
-msgid "Open project STL/OBJ/AMF/3MF with config, delete bed"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:102
-msgid "Import STL/OBJ/AMF/3MF without config, keep bed"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:103
-msgid "Load Config from .ini/amf/3mf/gcode"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:104 src/slic3r/GUI/Plater.cpp:605
-msgid "Export G-code"
-msgstr "Exporter le G-code"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:105
-msgid "Save project (3MF)"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:106
-msgid "Load Config from .ini/amf/3mf/gcode and merge"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:107
-msgid "(Re)slice"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:108
-msgid "Quick slice"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:109 src/slic3r/GUI/MainFrame.cpp:289
-msgid "Repeat last quick slice"
-msgstr "Répéter le dernier découpage rapide"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:110
-msgid "Select Plater Tab"
-msgstr "Sélectionner l'Onglet du Plateau"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:111
-msgid "Quick slice and Save as"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:112
-msgid "Select Print Settings Tab"
-msgstr "Sélectionner l'Onglet des Réglages d'Impression"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:113
-msgid "Select Filament Settings Tab"
-msgstr "Sélectionner l'Onglet des Réglages du Filament"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:114
-msgid "Select Printer Settings Tab"
-msgstr "Sélectionner l'Onglet des Réglages de l'Imprimante"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:115
-msgid "Switch to 3D"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:116
-msgid "Switch to Preview"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:117 src/slic3r/GUI/Preferences.cpp:10
-msgid "Preferences"
-msgstr "Préférences"
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:118
-#: src/slic3r/GUI/PrintHostDialogs.cpp:89
-msgid "Print host upload queue"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:119
-msgid "Camera view "
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:120
-msgid "Add Instance to selected object "
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:121
-msgid "Remove Instance from selected object"
-msgstr ""
-
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:122
-msgid "Show keyboard shortcuts list"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:117
+msgid "Bridges"
+msgstr "Ponts"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:123
-msgid "Switch between 3D and Preview"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:97
+msgid "Bridges fan speed"
+msgstr "Vitesse du ventilateur pour les ponts"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:124
-msgid "Select multiple object/Move multiple object"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:86
+msgid "Bridging"
+msgstr "Pont"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:132
-msgid "Arrange"
-msgstr "Agencer"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:88
+msgid "Bridging angle override. If left to zero, the bridging angle will be calculated automatically. Otherwise the provided angle will be used for all bridges. Use 180° for zero angle."
+msgstr "Ecraser l'angle des ponts. Si laissé à zéro, l'angle des ponts sera calculé automatiquement. Sinon, l'angle fourni sera utilisé pour tous les ponts. Utilisez 180° pour un angle nul."
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:133
-msgid "Select All objects"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214
+msgid "Bridging volumetric"
+msgstr "Volumétrie des ponts"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:134
-msgid "Delete selected"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:371
+msgid "Brim"
+msgstr "Jupe"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:135
-msgid "Delete All"
-msgstr "Tout Supprimer"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:127
+msgid "Brim width"
+msgstr "Largeur de la jupe"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:136
-msgid "Gizmo move"
-msgstr ""
+#: xs/src/slic3r/GUI/ButtonsDescription.cpp:13
+msgid "Buttons And Text Colors Description"
+msgstr "Description des Boutons et des Couleurs de Texte"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:137
-msgid "Gizmo scale"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:218
+msgid "by the print profile maximum"
+msgstr "par le maximum du profil de l'imprimante"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:138
-msgid "Gizmo rotate"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:85
+msgid "Cancel"
+msgstr "Annuler"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:139
-msgid "Gizmo cut"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:213
+msgid "Cancelling..."
+msgstr "Annulation..."
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:140
-msgid "Gizmo Place face on bed"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:2124
+msgid "Cannot overwrite a system profile."
+msgstr "Impossible d'écraser un profil système."
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:141
-msgid "Gizmo SLA support points"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:2128
+msgid "Cannot overwrite an external profile."
+msgstr "Impossible d'écraser un profil externe."
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:142
-msgid "Zoom to Bed"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:962
+msgid "Capabilities"
+msgstr "Fonctionnalités"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:143
-msgid "Zoom to all objects in scene, if none selected"
-msgstr ""
+#: xs/src/slic3r/GUI/GUI.cpp:403
+msgid "Capture a configuration snapshot"
+msgstr "Capturer un instantané de la configuration"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:144
-msgid "Zoom to selected object"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:1597
+msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"
+msgstr "Fichiers de certificat (*.crt, *.pem)|*.crt;*.pem|Tous les fichiers|*.*"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:145
-msgid "Zoom in"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:325
+msgid "Change Application Language"
+msgstr "Changer la langue de l'application"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:146
-msgid "Zoom out"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2030
+msgid "Change the number of copies of the selected object"
+msgstr "Changer le nombre de copies de l'objet sélectionné"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:147
-msgid "Unselect gizmo, keep object selection"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:272 xs/src/slic3r/GUI/Preferences.cpp:59
+msgid "Check for application updates"
+msgstr "Vérifier les mises à jour de l'application"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:149
-msgid "Plater Shortcuts"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:298
+msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):"
+msgstr "Choisir un fichier à partir duquel importer la forme du plateau (STL/OBJ/AMF/3MF/PRUSA) :"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:155
-msgid "Arrow Up"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:457
+msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):"
+msgstr "Choisir un fichier à découper (STL/OBJ/AMF/3MF/PRUSA) :"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:155
-msgid "Upper Layer"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI.pm:286
+msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"
+msgstr "Choisir un ou plusieurs fichiers (STL/OBJ/AMF/3MF/PRUSA) :"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:156
-msgid "Arrow Down"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:360
+msgid "Choose the type of firmware used by your printer."
+msgstr "Choisissez le type de firmware utilisé par votre imprimante."
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:156
-msgid "Lower Layer"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:62
+msgid "Circular"
+msgstr "Circulaire"
-#: src/slic3r/GUI/KBShortcutsDialog.cpp:158
-msgid "Preview Shortcuts"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:135
+msgid "Clip multi-part objects"
+msgstr "Dissocier les objets multi-pièces"
-#: src/slic3r/GUI/MainFrame.cpp:53
-msgid ""
-" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"
-msgstr ""
-" - Pensez à vérifier les mises à jours sur http://github.com/prusa3d/slic3r/"
-"releases"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:405
+msgid "Color"
+msgstr "Couleur"
-#: src/slic3r/GUI/MainFrame.cpp:130
-msgid "Plater"
-msgstr "Plateau"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:690
+msgid "Combine infill every"
+msgstr "Combiner le remplissage toutes les"
-#: src/slic3r/GUI/MainFrame.cpp:236
-msgid "&Open"
-msgstr "&Ouvrir"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:696
+msgid "Combine infill every n layers"
+msgstr "Combiner le remplissage toutes les n couches"
-#: src/slic3r/GUI/MainFrame.cpp:236
-msgid "Open a project file"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:509
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:869
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1668
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:143
+msgid "Compatible printers"
+msgstr "Imprimantes compatibles"
-#: src/slic3r/GUI/MainFrame.cpp:238
-msgid "&Save"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:147
+msgid "Compatible printers condition"
+msgstr "Condition de compatibilité des imprimantes"
-#: src/slic3r/GUI/MainFrame.cpp:238
-msgid "Save current project file"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:154
+msgid "Complete individual objects"
+msgstr "Compléter les objets individuels"
-#: src/slic3r/GUI/MainFrame.cpp:240
-msgid "Save &as"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:846
+msgid "Configuration Assistant"
+msgstr "Assistant de Configuration"
-#: src/slic3r/GUI/MainFrame.cpp:240
-msgid "Save current project file as"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:884
+msgid "Configuration notes"
+msgstr "Notes de configuration"
-#: src/slic3r/GUI/MainFrame.cpp:246
-msgid "Import STL/OBJ/AM&F/3MF"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:96 xs/src/slic3r/GUI/GUI.cpp:402
+msgid "Configuration Snapshots"
+msgstr "Instantanés de Configuration"
-#: src/slic3r/GUI/MainFrame.cpp:246
-msgid "Load a model"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:69
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:161
+msgid "Configuration update"
+msgstr "Mise à jour de la configuration"
-#: src/slic3r/GUI/MainFrame.cpp:249
-msgid "Import &Config"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:69
+msgid "Configuration update is available"
+msgstr "Une mise à jour de la configuration est disponible"
-#: src/slic3r/GUI/MainFrame.cpp:249
-msgid "Load exported configuration file"
-msgstr "Charger le fichier de configuration exporté"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:844
+msgid "Configuration Wizard"
+msgstr "Assistant de Configuration"
-#: src/slic3r/GUI/MainFrame.cpp:251
-msgid "Import Config from &project"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:366
+msgid "Confirmation"
+msgstr "Confirmation"
-#: src/slic3r/GUI/MainFrame.cpp:251
-msgid "Load configuration from project file"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1020
+msgid "Connection failed."
+msgstr "La connexion a échoué."
-#: src/slic3r/GUI/MainFrame.cpp:254
-msgid "Import Config &Bundle"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:211
+msgid "Connection to OctoPrint works correctly."
+msgstr "La connexion avec OctoPrint fonctionne correctement."
-#: src/slic3r/GUI/MainFrame.cpp:254
-msgid "Load presets from a bundle"
-msgstr "Charger les préréglages à partir d'un lot"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1017
+msgid "Connection to printer works correctly."
+msgstr "La connexion avec l'imprimante fonctionne correctement."
-#: src/slic3r/GUI/MainFrame.cpp:256
-msgid "&Import"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1416
+msgid "Contact Z distance"
+msgstr "Distance de contact Z"
-#: src/slic3r/GUI/MainFrame.cpp:259
-msgid "Export &G-code"
-msgstr "Exporter le &G-code"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:120
+msgid "Controller"
+msgstr "Contrôleur"
-#: src/slic3r/GUI/MainFrame.cpp:259
-msgid "Export current plate as G-code"
-msgstr "Exporter le plateau courant en G-code"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:805
+msgid "Cooling"
+msgstr "Refroidissement"
-#: src/slic3r/GUI/MainFrame.cpp:262
-msgid "Export plate as &STL"
-msgstr "Exporter le plateau en &STL"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:826
+msgid "Cooling thresholds"
+msgstr "Seuils de refroidissement"
-#: src/slic3r/GUI/MainFrame.cpp:262
-msgid "Export current plate as STL"
-msgstr "Exporter le plateau courant en STL"
+#: xs/src/libslic3r/PrintConfig.cpp:178
+msgid "Cooling tube length"
+msgstr "Longueur du tube de refroidissement"
-#: src/slic3r/GUI/MainFrame.cpp:264
-msgid "Export plate as &AMF"
-msgstr "Exporter le plateau en &AMF"
+#: xs/src/libslic3r/PrintConfig.cpp:170
+msgid "Cooling tube position"
+msgstr "Position du tube de refroidissement"
-#: src/slic3r/GUI/MainFrame.cpp:264
-msgid "Export current plate as AMF"
-msgstr "Exporter le plateau courant en AMF"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:221
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:900
+msgid "Copies"
+msgstr "Copies"
-#: src/slic3r/GUI/MainFrame.cpp:267
-msgid "Export &Config"
-msgstr "Exporter la &configuration"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:476
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:450
+msgid "Cost"
+msgstr "Coût"
-#: src/slic3r/GUI/MainFrame.cpp:267
-msgid "Export current configuration to file"
-msgstr "Exporter la configuration actuelle vers un fichier"
+#: xs/src/slic3r/GUI/Tab.cpp:1571
+msgid "Could not connect to OctoPrint"
+msgstr "Impossible de se connecter à OctoPrint"
-#: src/slic3r/GUI/MainFrame.cpp:269
-msgid "Export Config &Bundle"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1465
+msgid "Cover the top contact layer of the supports with loops. Disabled by default."
+msgstr "Recouvrir la couche de contact supérieure des supports avec des boucles. Désactivé par défaut."
-#: src/slic3r/GUI/MainFrame.cpp:269
-msgid "Export all presets to file"
-msgstr "Exporter tous les préréglage vers un fichier"
+#: xs/src/slic3r/GUI/Tab.cpp:743
+msgid "Current preset is inherited from "
+msgstr "Le préréglage en cours a hérité de "
-#: src/slic3r/GUI/MainFrame.cpp:271
-msgid "&Export"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:41
+msgid "Current version:"
+msgstr "Version actuelle :"
-#: src/slic3r/GUI/MainFrame.cpp:277
-msgid "Quick Slice"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:71
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:150
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:92
+msgid "Custom"
+msgstr "Personnalisé"
-#: src/slic3r/GUI/MainFrame.cpp:277
-msgid "Slice a file into a G-code"
-msgstr "Découper un fichier en G-code"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:846
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1119
+msgid "Custom G-code"
+msgstr "G-code personnalisé"
-#: src/slic3r/GUI/MainFrame.cpp:283
-msgid "Quick Slice and Save As"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:240
+msgid "Custom setup"
+msgstr "Configuration personnalisée"
-#: src/slic3r/GUI/MainFrame.cpp:283
-msgid "Slice a file into a G-code, save as"
-msgstr "Découper un fichier en G-code, enregistrer sous"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:189
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:205
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2102
+msgid "Cut…"
+msgstr "Couper…"
-#: src/slic3r/GUI/MainFrame.cpp:289
-msgid "Repeat Last Quick Slice"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2027
+msgid "Decrease copies"
+msgstr "Réduire les copies"
-#: src/slic3r/GUI/MainFrame.cpp:297
-msgid "(Re)Slice &Now"
-msgstr "(Re)Découper mai&ntenant"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:300
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:170
+msgid "Default"
+msgstr "Défaut"
-#: src/slic3r/GUI/MainFrame.cpp:297
-msgid "Start new slicing process"
-msgstr "Démarrer un nouveau processus de découpe"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Field.cpp:42
+msgid "default"
+msgstr "défaut"
-#: src/slic3r/GUI/MainFrame.cpp:300
-msgid "&Repair STL file"
-msgstr "&Réparer le fichier STL"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1469
+msgid "Default "
+msgstr "Défaut "
-#: src/slic3r/GUI/MainFrame.cpp:300
-msgid "Automatically repair an STL file"
-msgstr "Réparer automatiquement un fichier STL"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:489
+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 "Angle de base par défaut pour l'orientation du remplissage. Des croisements seront appliqués à cette valeur. Les ponts seront remplis avec la meilleure direction que Slic3r peut détecter, ce réglage ne les affecteront donc pas."
-#: src/slic3r/GUI/MainFrame.cpp:303
-msgid "&Quit"
-msgstr "&Quitter"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:376
+msgid "Default extrusion width"
+msgstr "Largeur d'extrusion par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:303
-msgid "Quit Slic3r"
-msgstr "Quitter Slic3r"
+#: xs/src/slic3r/GUI/Tab.cpp:767
+msgid "default filament profile"
+msgstr "profil du filament par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:321
-msgid "&Select all"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:196
+msgid "Default filament profile"
+msgstr "Profil de filament par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:321
-msgid "Selects all objects"
-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 "Profil de filament par défaut associé au profil d'imprimante courant. En sélectionnant le profil d'imprimante courant, ce profil de filament sera activé."
-#: src/slic3r/GUI/MainFrame.cpp:324
-msgid "&Delete selected"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:2287 xs/src/slic3r/GUI/Tab.cpp:2373
+msgid "Default presets"
+msgstr "Préréglages par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:324
-msgid "Deletes the current selection"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:202
+msgid "Default print profile"
+msgstr "Profil de filament par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:326
-msgid "Delete &all"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:764
+msgid "default print profile"
+msgstr "profil d'impression par défaut"
-#: src/slic3r/GUI/MainFrame.cpp:326
-msgid "Deletes all objects"
-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 "Profil de filament par défaut associé au profil d'imprimante courant. En sélectionnant le profil d'imprimante courant, ce profil de filament sera activé."
-#: src/slic3r/GUI/MainFrame.cpp:339
-msgid "&Plater Tab"
-msgstr "L'Onglet du &Plateau"
+#: xs/src/libslic3r/PrintConfig.cpp:1849
+msgid "degrees"
+msgstr "degrés"
-#: src/slic3r/GUI/MainFrame.cpp:339
-msgid "Show the plater"
-msgstr "Afficher le plateau"
+#: xs/src/libslic3r/PrintConfig.cpp:476
+msgid "Delay after unloading"
+msgstr "Délai après le déchargement"
-#: src/slic3r/GUI/MainFrame.cpp:346
-msgid "P&rint Settings Tab"
-msgstr "L'Onglet des Réglages d'&Impression"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1582
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:178
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:196
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2021
+msgid "Delete"
+msgstr "Supprimer"
-#: src/slic3r/GUI/MainFrame.cpp:346
-msgid "Show the print settings"
-msgstr "Afficher les réglages d'impression"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1580
+msgid "delete"
+msgstr "supprimer"
-#: src/slic3r/GUI/MainFrame.cpp:348
-msgid "&Filament Settings Tab"
-msgstr "L'Onglet des Réglages du &Filament"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:179
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:197
+msgid "Delete All"
+msgstr "Tout Supprimer"
-#: src/slic3r/GUI/MainFrame.cpp:348
-msgid "Show the filament settings"
-msgstr "Afficher les réglages de filament"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:51
+msgid "Delete this preset"
+msgstr "Supprimer ce préréglage"
-#: src/slic3r/GUI/MainFrame.cpp:350
-msgid "Print&er Settings Tab"
-msgstr "L'Onglet des Réglages de l'Impri&mante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:440
+msgid "Density"
+msgstr "Densité"
-#: src/slic3r/GUI/MainFrame.cpp:350
-msgid "Show the printer settings"
-msgstr "Afficher les réglages de l'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:503
+#, no-c-format
+msgid "Density of internal infill, expressed in the range 0% - 100%."
+msgstr "Densité du remplissage interne, exprimée en pourcentage de 0% à 100%."
-#: src/slic3r/GUI/MainFrame.cpp:354
-msgid "3&D"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:507
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:867
+msgid "Dependencies"
+msgstr "Dépendances"
-#: src/slic3r/GUI/MainFrame.cpp:354
-msgid "Show the 3D editing view"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1142
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1143
+msgid "Deretraction Speed"
+msgstr "Vitesse de Réinsertion"
-#: src/slic3r/GUI/MainFrame.cpp:356
-msgid "Pre&view"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:940
+msgid "Detect bridging perimeters"
+msgstr "Détecter les périmètres faisant des ponts"
-#: src/slic3r/GUI/MainFrame.cpp:356
-msgid "Show the 3D slices preview"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1584
+msgid "Detect single-width walls (parts where two extrusions don't fit and we need to collapse them into a single trace)."
+msgstr "Détecter les parois de largeur unique (où deux extrusions côte à côte ne rentrent pas et doivent êtres fusionnées en un seul trait)."
-#: src/slic3r/GUI/MainFrame.cpp:377
-msgid "Print &Host Upload Queue"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1582
+msgid "Detect thin walls"
+msgstr "Détecter les parois fines"
-#: src/slic3r/GUI/MainFrame.cpp:377
-msgid "Display the Print Host Upload Queue window"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:66
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:431
+msgid "Diameter"
+msgstr "Diamètre"
-#: src/slic3r/GUI/MainFrame.cpp:388
-msgid "&Iso"
-msgstr "&Isométrique"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:67
+msgid "Diameter of the print bed. It is assumed that origin (0,0) is located in the center."
+msgstr "Diamètre du plateau d'impression. Il est supposé que l'origine (0,0) est située au centre."
-#: src/slic3r/GUI/MainFrame.cpp:388
-msgid "Iso View"
-msgstr "Vue Isométrique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1169
+msgid "Direction"
+msgstr "Direction"
-#: src/slic3r/GUI/MainFrame.cpp:390
-msgid "&Top"
-msgstr "du Dess&us"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:53
+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 "Désactiver la communication avec l'imprimante via un câble série / USB. Ceci simplifie l'interface utilisateur dans le cas où l'imprimante n'est jamais connectée à l'ordinateur."
-#: src/slic3r/GUI/MainFrame.cpp:390
-msgid "Top View"
-msgstr "Vue du Dessus"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:180
+msgid "Disable fan for the first"
+msgstr "Désactiver le ventilateur pour le(s) première(s)"
-#: src/slic3r/GUI/MainFrame.cpp:391
-msgid "&Bottom"
-msgstr "du Dess&ous"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:51
+msgid "Disable USB/serial connection"
+msgstr "Désactiver la connexion USB/série"
-#: src/slic3r/GUI/MainFrame.cpp:391
-msgid "Bottom View"
-msgstr "Vue du Dessous"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:916
+msgid "Disables retraction when the travel path does not exceed the upper layer's perimeters (and thus any ooze will be probably invisible)."
+msgstr "Désactiver la rétraction lorsque le chemin de déplacement ne franchit pas les périmètres des couches supérieures (et donc les coulures seront probablement invisibles)."
-#: src/slic3r/GUI/MainFrame.cpp:392
-msgid "&Front"
-msgstr "&Avant"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:198
+msgid "Distance between copies"
+msgstr "Distance entre les copies"
-#: src/slic3r/GUI/MainFrame.cpp:392
-msgid "Front View"
-msgstr "Vue Avant"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1213
+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 "Distance entre le ou les objet(s) et la clôture. Mettez zéro pour attacher la clôture a(ux) objet(s) et obtenir une jupe, mais dans ce cas préférez l'utilisation du paramètre de la taille de jupe."
-#: src/slic3r/GUI/MainFrame.cpp:393
-msgid "R&ear"
-msgstr "A&rrière"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1212
+msgid "Distance from object"
+msgstr "Distance de l'objet"
-#: src/slic3r/GUI/MainFrame.cpp:393
-msgid "Rear View"
-msgstr "Vue Arrière"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:58
+msgid "Distance of the 0,0 G-code coordinate from the front left corner of the rectangle."
+msgstr "Distance des coordonnées 0,0 du G-code depuis le coin avant gauche du rectangle."
-#: src/slic3r/GUI/MainFrame.cpp:394
-msgid "&Left"
-msgstr "&Gauche"
+#: xs/src/libslic3r/PrintConfig.cpp:171
+msgid "Distance of the center-point of the cooling tube from the extruder tip "
+msgstr "Distance entre le point central du tube de refroidissement et la pointe de l'extrudeur. "
-#: src/slic3r/GUI/MainFrame.cpp:394
-msgid "Left View"
-msgstr "Vue Gauche"
+#: 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 "Distance entre la pointe de l'extrudeur et la position où le filament est positionné en attente lorsqu'il est déchargé. Cela doit correspondre à la valeur dans le firmware de l'imprimante. "
-#: src/slic3r/GUI/MainFrame.cpp:395
-msgid "&Right"
-msgstr "&Droite"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:199
+msgid "Distance used for the auto-arrange feature of the plater."
+msgstr "Distance utilisée par la fonction d'agencement automatique du plateau."
-#: src/slic3r/GUI/MainFrame.cpp:395
-msgid "Right View"
-msgstr "Vue Droite"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:51
+msgid "Don't notify about new releases any more"
+msgstr "Ne plus me notifier au sujet des nouvelles publications"
-#: src/slic3r/GUI/MainFrame.cpp:409
-msgid "Prusa 3D &Drivers"
-msgstr "&Drivers Prusa 3D"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:190
+msgid "Don't support bridges"
+msgstr "Ne pas supporter les ponts"
-#: src/slic3r/GUI/MainFrame.cpp:409
-msgid "Open the Prusa3D drivers download page in your browser"
-msgstr ""
-"Ouvrir la page de téléchargement des drivers Prusa3D dans votre navigateur"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:17
+msgid "Downgrade"
+msgstr "Rétrograder"
-#: src/slic3r/GUI/MainFrame.cpp:411
-msgid "Prusa Edition &Releases"
-msgstr "&Publication de la Prusa Edition"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\2D.pm:132
+msgid "Drag your objects here"
+msgstr "Glissez vos objets ici"
-#: src/slic3r/GUI/MainFrame.cpp:411
-msgid "Open the Prusa Edition releases page in your browser"
-msgstr ""
-"Ouvrir la page des publications de la Prusa Edition dans votre navigateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:207
+msgid "Elephant foot compensation"
+msgstr "Compensation de l'effet patte d'éléphant"
-#: src/slic3r/GUI/MainFrame.cpp:417
-msgid "Slic3r &Website"
-msgstr "Site &Web de Slic3r"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:806
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:922
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1695
+msgid "Enable"
+msgstr "Activer"
-#: src/slic3r/GUI/MainFrame.cpp:417
-msgid "Open the Slic3r website in your browser"
-msgstr "Ouvrir le site web de Slic3r dans votre navigateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:163
+msgid "Enable auto cooling"
+msgstr "Activer le refroidissement automatique"
-#: src/slic3r/GUI/MainFrame.cpp:419
-msgid "Slic3r &Manual"
-msgstr "&Manuel de Slic3r"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:394
+msgid "Enable fan if layer print time is below"
+msgstr "Activer le ventilateur si le temps d'impression de la couche est inférieur à"
-#: src/slic3r/GUI/MainFrame.cpp:419
-msgid "Open the Slic3r manual in your browser"
-msgstr "Ouvrir la manuel de Slic3r dans votre navigateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1381
+msgid "Enable support material generation."
+msgstr "Activer la génération des supports."
-#: src/slic3r/GUI/MainFrame.cpp:422
-msgid "System &Info"
-msgstr "&Informations sur le Système"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:645
+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 "Activez ceci pour obtenir un fichier G-code commenté, avec chaque ligne expliquée par un texte descriptif. Si vous imprimez depuis une carte SD, le poids supplémentaire du fichier pourrait ralentir le firmware de votre imprimante."
-#: src/slic3r/GUI/MainFrame.cpp:422
-msgid "Show system information"
-msgstr "Afficher les informations système"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1681
+msgid "Enable variable layer height feature"
+msgstr "Activer la fonction de hauteur de couche variable"
-#: src/slic3r/GUI/MainFrame.cpp:424
-msgid "Show &Configuration Folder"
-msgstr "Afficher le Répertoire de &Configuration"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:853
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1126
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:217
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:227
+msgid "End G-code"
+msgstr "G-code de fin"
-#: src/slic3r/GUI/MainFrame.cpp:424
-msgid "Show user configuration folder (datadir)"
-msgstr "Afficher le répertoire de configuration utilisateur (datadir)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1431
+msgid "Enforce support for the first"
+msgstr "Renforcer le support sur le(s) première(s)"
-#: src/slic3r/GUI/MainFrame.cpp:426
-msgid "Report an I&ssue"
-msgstr "Signaler un p&roblème"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1439
+msgid "Enforce support for the first n layers"
+msgstr "Renforcer le support pour les n premières couches"
-#: src/slic3r/GUI/MainFrame.cpp:426
-msgid "Report an issue on the Slic3r Prusa Edition"
-msgstr "Signaler un problème sur la Prusa Edition de Slic3r"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:238
+msgid "Ensure vertical shell thickness"
+msgstr "S'assurer de l'épaisseur de la coque verticale"
-#: src/slic3r/GUI/MainFrame.cpp:428
-msgid "&About Slic3r"
-msgstr "&A propos de Slic3r"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:493
+msgid "Enter the bed temperature needed for getting your filament to stick to your heated bed."
+msgstr "Entrez la température du lit nécessaire pour que votre filament colle à votre lit chauffant."
-#: src/slic3r/GUI/MainFrame.cpp:428
-msgid "Show about dialog"
-msgstr "Afficher la boîte de dialogue à propos"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:441
+msgid "Enter the diameter of your filament."
+msgstr "Entrez le diamètre de votre filament."
-#: src/slic3r/GUI/MainFrame.cpp:431
-msgid "&Keyboard Shortcuts"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:428
+msgid "Enter the diameter of your printer's hot end nozzle."
+msgstr "Entrez le diamètre de la buse de la tête d'impression de votre imprimante."
-#: src/slic3r/GUI/MainFrame.cpp:431
-msgid "Show the list of the keyboard shortcuts"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1056
+msgid "Enter the new max size for the selected object:"
+msgstr "Entrez la nouvelle taille maximale pour l'objet sélectionné :"
-#: src/slic3r/GUI/MainFrame.cpp:439
-msgid "&File"
-msgstr "&Fichier"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1030
+#, perl-format
+msgid "Enter the new size for the selected object (print bed: %smm):"
+msgstr "Entrez la nouvelle taille pour l'objet sélectionné (plateau d'impression : %s mm) :"
-#: src/slic3r/GUI/MainFrame.cpp:440
-msgid "&Edit"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:900
+msgid "Enter the number of copies of the selected object:"
+msgstr "Entrez le nombre de copies de l'objet sélectionné :"
-#: src/slic3r/GUI/MainFrame.cpp:441
-msgid "&Window"
-msgstr "Fe&nêtre"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1035
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1061
+#, no-perl-format
+msgid "Enter the scale % for the selected object:"
+msgstr "Entrez l'échelle en % pour l'objet sélectionné :"
-#: src/slic3r/GUI/MainFrame.cpp:442
-msgid "&View"
-msgstr "&Vue"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:479
+msgid "Enter the temperature needed for extruding your filament."
+msgstr "Entrez la température nécessaire pour extruder votre filament."
-#: src/slic3r/GUI/MainFrame.cpp:445
-msgid "&Help"
-msgstr "&Aide"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:477
+msgid "Enter your filament cost per kg here. This is only for statistical information."
+msgstr "Entrez le coût par Kg de votre filament. Ceci est uniquement pour l'information statistique."
-#: src/slic3r/GUI/MainFrame.cpp:472
-msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):"
-msgstr "Choisir un fichier à découper (STL/OBJ/AMF/3MF/PRUSA) :"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:441
+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 the length to volume. Better is to calculate the volume directly through displacement."
+msgstr "Entrez ici la densité de votre filament. Ceci est uniquement pour des informations statistiques. Un bon moyen d'obtenir cette valeur est de peser un morceau de filament d'une longueur connue et de calculer le rapport de sa longueur par son poids. Le mieux est de calculer le volume directement par déplacement."
-#: src/slic3r/GUI/MainFrame.cpp:486
-msgid "No previously sliced file."
-msgstr "Aucun fichier précédemment découpé."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:432
+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 "Entrez le diamètre de votre filament ici. Une bonne précision est requise, utilisez un pied à coulisse et calculez la moyenne de plusieurs mesures le long du filament."
-#: src/slic3r/GUI/MainFrame.cpp:487 src/slic3r/GUI/PrintHostDialogs.cpp:173
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:488
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:470
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1300
msgid "Error"
msgstr "Erreur"
-#: src/slic3r/GUI/MainFrame.cpp:492
-msgid "Previously sliced file ("
-msgstr "Fichier précédemment découpé ("
-
-#: src/slic3r/GUI/MainFrame.cpp:492
-msgid ") not found."
-msgstr ") non trouvé."
-
-#: src/slic3r/GUI/MainFrame.cpp:493
-msgid "File Not Found"
-msgstr "Fichier non trouvé"
-
-#: src/slic3r/GUI/MainFrame.cpp:531 src/slic3r/GUI/Tab.cpp:3031
-msgid "Save "
-msgstr "Enregistrer "
-
-#: src/slic3r/GUI/MainFrame.cpp:531
-msgid "SVG"
-msgstr "SVG"
-
-#: src/slic3r/GUI/MainFrame.cpp:531
-msgid "G-code"
-msgstr "G-code"
-
-#: src/slic3r/GUI/MainFrame.cpp:531
-msgid " file as:"
-msgstr ""
-
-#: src/slic3r/GUI/MainFrame.cpp:548
-msgid "Save zip file as:"
-msgstr ""
-
-#: src/slic3r/GUI/MainFrame.cpp:560
-msgid "Slicing"
-msgstr "Découpe en cours"
-
-#: src/slic3r/GUI/MainFrame.cpp:560
-msgid "Processing "
-msgstr "Traitement "
-
-#: src/slic3r/GUI/MainFrame.cpp:583
-msgid " was successfully sliced."
-msgstr " a été découpé avec succès."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1612
+msgid "Error exporting 3MF file "
+msgstr "Erreur d'export du fichier 3MF "
-#: src/slic3r/GUI/MainFrame.cpp:585
-msgid "Slicing Done!"
-msgstr "Découpe Effectuée !"
-
-#: src/slic3r/GUI/MainFrame.cpp:600
-msgid "Select the STL file to repair:"
-msgstr "Sélectionner le fichier STL à réparer :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1596
+msgid "Error exporting AMF file "
+msgstr "Erreur d'export du fichier AMF "
-#: src/slic3r/GUI/MainFrame.cpp:614
-msgid "Save OBJ file (less prone to coordinate errors than STL) as:"
-msgstr ""
-"Enregistrer le fichier OBJ (moins enclin aux erreurs de coordonnées que le "
-"STL) sous :"
+#: xs/src/slic3r/Utils/OctoPrint.cpp:47
+msgid "Error while uploading to the OctoPrint server"
+msgstr "Erreur lors du téléchargement vers le serveur OctoPrint"
-#: src/slic3r/GUI/MainFrame.cpp:629
-msgid "Your file was repaired."
-msgstr "Votre fichier a été réparé."
-
-#: src/slic3r/GUI/MainFrame.cpp:629
-msgid "Repair"
-msgstr "Réparer"
-
-#: src/slic3r/GUI/MainFrame.cpp:643
-msgid "Save configuration as:"
-msgstr "Enregistrer la configuration sous :"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:315
+msgid "Error! "
+msgstr "Erreur ! "
-#: src/slic3r/GUI/MainFrame.cpp:663 src/slic3r/GUI/MainFrame.cpp:727
-msgid "Select configuration to load:"
-msgstr "Sélectionner la configuration à charger :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:451
+msgid "Estimated printing time"
+msgstr "Temps d'impression estimé"
-#: src/slic3r/GUI/MainFrame.cpp:700
-msgid "Save presets bundle as:"
-msgstr "Enregistrer le lot de préréglages sous :"
+#: xs/src/slic3r/GUI/GUI.cpp:885
+msgid "Everywhere"
+msgstr "Partout"
-#: src/slic3r/GUI/MainFrame.cpp:751
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:44
#, c-format
-msgid "%d presets successfully imported."
-msgstr "%d préréglages importés avec succès."
-
-#: src/slic3r/GUI/MsgDialog.cpp:66
-msgid "Slic3r error"
-msgstr "Erreur de Slic3r"
-
-#: src/slic3r/GUI/MsgDialog.cpp:66
-msgid "Slic3r has encountered an error"
-msgstr "Slic3r a rencontré une erreur"
-
-#: src/slic3r/GUI/MsgDialog.cpp:84
-msgid "Copy to clipboard"
-msgstr ""
+msgid "except for the first %d layers"
+msgstr "sauf pour les %d première couches"
-#: src/slic3r/GUI/Plater.cpp:107
-msgid "Info"
-msgstr "Info"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:48
+msgid "except for the first layer"
+msgstr "sauf pour la première couche"
-#: src/slic3r/GUI/Plater.cpp:126
-msgid "Volume"
-msgstr "Volume"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:141
+msgid "Exit Slic3r"
+msgstr "Quitter Slic3r"
-#: src/slic3r/GUI/Plater.cpp:127
-msgid "Facets"
-msgstr "Faces"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:192
+msgid "Experimental option for preventing support material from being generated under bridged areas."
+msgstr "Option expérimentale pour empêcher la génération de support sous les ponts."
-#: src/slic3r/GUI/Plater.cpp:128
-msgid "Materials"
-msgstr "Matériaux"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:942
+msgid "Experimental option to adjust flow for overhangs (bridge flow will be used), to apply bridge speed to them and enable fan."
+msgstr "Option expérimentale qui ajuste le flux pour les surplombs (le flux pour les ponts sera utilisé), leur applique la vitesse pour les ponts et active le ventilateur."
-#: src/slic3r/GUI/Plater.cpp:131
-msgid "Manifold"
-msgstr "Variété"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:263
+msgid "Export all presets to file"
+msgstr "Exporter tous les préréglage vers un fichier"
-#: src/slic3r/GUI/Plater.cpp:174
-msgid "Sliced Info"
-msgstr "Informations de découpage"
+#: lib/Slic3r/GUI/Plater.pm:1416
+msgid "Export cancelled"
+msgstr "Exportation annulée"
-#: src/slic3r/GUI/Plater.cpp:193 src/slic3r/GUI/Plater.cpp:823
-msgid "Used Filament (m)"
-msgstr "Filament Utilisé (m)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:257
+msgid "Export current configuration to file"
+msgstr "Exporter la configuration actuelle vers un fichier"
-#: src/slic3r/GUI/Plater.cpp:194
-msgid "Used Filament (mm³)"
-msgstr "Filament Utilisé (mm³)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:323
+msgid "Export current plate as 3MF"
+msgstr "Exporter le plateau courant en 3MF"
-#: src/slic3r/GUI/Plater.cpp:195
-msgid "Used Filament (g)"
-msgstr "Filament Utilisé (g)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:320
+msgid "Export current plate as AMF"
+msgstr "Exporter le plateau courant en AMF"
-#: src/slic3r/GUI/Plater.cpp:196 src/slic3r/GUI/Plater.cpp:838
-#: src/libslic3r/PrintConfig.cpp:718
-msgid "Cost"
-msgstr "Coût"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:314
+msgid "Export current plate as G-code"
+msgstr "Exporter le plateau courant en G-code"
-#: src/slic3r/GUI/Plater.cpp:197 src/slic3r/GUI/Plater.cpp:852
-msgid "Estimated printing time"
-msgstr "Temps d'impression estimé"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:317
+msgid "Export current plate as STL"
+msgstr "Exporter le plateau courant en STL"
-#: src/slic3r/GUI/Plater.cpp:198
-msgid "Number of tool changes"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1454
+msgid "Export failed"
+msgstr "L'export a échoué"
-#: src/slic3r/GUI/Plater.cpp:361
-msgid "Support"
-msgstr "Support"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:314
+msgid "Export G-code..."
+msgstr "Exporter le G-code..."
-#: src/slic3r/GUI/Plater.cpp:364
-msgid "Select what kind of support do you need"
-msgstr "Choisissez le type de support dont vous avez besoin"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:236
+msgid "Export G-code…"
+msgstr "Exporter le G-code…"
-#: src/slic3r/GUI/Plater.cpp:365 src/libslic3r/GCode/PreviewData.cpp:162
-msgid "None"
-msgstr "Aucun"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2113
+msgid "Export object as STL…"
+msgstr "Exporter l'objet en STL…"
-#: src/slic3r/GUI/Plater.cpp:366 src/libslic3r/PrintConfig.cpp:1904
-msgid "Support on build plate only"
-msgstr "Support sur le plateau uniquement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:323
+msgid "Export plate as 3MF..."
+msgstr "Exporter le plateau en 3MF..."
-#: src/slic3r/GUI/Plater.cpp:367
-msgid "Everywhere"
-msgstr "Partout"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:320
+msgid "Export plate as AMF..."
+msgstr "Exporter le plateau en AMF..."
-#: src/slic3r/GUI/Plater.cpp:379 src/slic3r/GUI/Tab.cpp:977
-msgid "Brim"
-msgstr "Bordure"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:317
+msgid "Export plate as STL..."
+msgstr "Exporter le plateau en STL..."
-#: src/slic3r/GUI/Plater.cpp:381
-msgid ""
-"This flag enables the brim that will be printed around each object on the "
-"first layer."
-msgstr ""
-"Cette option permet l'impression de la bordure qui entoure chaque objet lors "
-"de la première couche."
+#: xs/src/slic3r/GUI/GUI.cpp:950
+msgid "Export print config"
+msgstr "Exporter la configuration d'impression"
-#: src/slic3r/GUI/Plater.cpp:390
-msgid "Purging volumes"
-msgstr "Volumes de purge"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:240
+msgid "Export STL…"
+msgstr "Exporter le STL…"
-#: src/slic3r/GUI/Plater.cpp:556
-msgid "Print settings"
-msgstr "Réglages d'impression"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2113
+msgid "Export this single object as STL file"
+msgstr "Exporter cet unique objet en fichier STL"
-#: src/slic3r/GUI/Plater.cpp:557 src/slic3r/GUI/Tab.cpp:1380
-#: src/slic3r/GUI/Tab.cpp:1381
-msgid "Filament"
-msgstr "Filament"
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:139
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:81
+msgid "External perimeter"
+msgstr "Périmètre externe"
-#: src/slic3r/GUI/Plater.cpp:558 src/slic3r/GUI/Preset.cpp:1158
-msgid "SLA print"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:267
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:277
+msgid "External perimeters"
+msgstr "Périmètres externes"
-#: src/slic3r/GUI/Plater.cpp:559 src/slic3r/GUI/Preset.cpp:1159
-msgid "SLA material"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:151
+msgid "external perimeters"
+msgstr "périmètres externes"
-#: src/slic3r/GUI/Plater.cpp:560
-msgid "Printer"
-msgstr "Imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:289
+msgid "External perimeters first"
+msgstr "Périmètres externes en premier"
-#: src/slic3r/GUI/Plater.cpp:588
-msgid "Send to printer"
-msgstr "Envoyer à l'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1118
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1126
+msgid "Extra length on restart"
+msgstr "Longueur supplémentaire à la reprise"
-#: src/slic3r/GUI/Plater.cpp:607
-msgid "Slice now"
-msgstr "Découper maintenant"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:297
+msgid "Extra perimeters if needed"
+msgstr "Périmètres supplémentaires si nécessaire"
-#: src/slic3r/GUI/Plater.cpp:787
-#, c-format
-msgid "%d (%d shells)"
-msgstr "%d (%d coques)"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:795
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1234
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:307
+msgid "Extruder"
+msgstr "Extrudeur"
-#: src/slic3r/GUI/Plater.cpp:792
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1187
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:400
#, c-format
-msgid "Auto-repaired (%d errors)"
-msgstr "Réparé automatiquement (%d erreurs)"
+msgid "Extruder %d"
+msgstr "Extrudeur %d"
-#: src/slic3r/GUI/Plater.cpp:795
-#, c-format
-msgid ""
-"%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d "
-"facets reversed, %d backwards edges"
-msgstr ""
-"%d faces invalides, %d arrêtes corrigées, %d faces retirées, %d faces "
-"ajoutées, %d faces inversées, %d arrêtes à l'envers"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:463
+msgid "Extruder and Bed Temperatures"
+msgstr "Températures de l'Extrudeur et du Lit"
-#: src/slic3r/GUI/Plater.cpp:805
-msgid "Yes"
-msgstr "Oui"
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:224
+msgid "Extruder changed to"
+msgstr "Extrudeur changé à"
-#: src/slic3r/GUI/Plater.cpp:825 src/slic3r/GUI/Plater.cpp:840
-msgid "objects"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:479
+msgid "Extruder clearance (mm)"
+msgstr "Dégagement de l'extrudeur (mm)"
-#: src/slic3r/GUI/Plater.cpp:825 src/slic3r/GUI/Plater.cpp:840
-msgid "wipe tower"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:342
+msgid "Extruder Color"
+msgstr "Couleur de l'extrudeur"
-#: src/slic3r/GUI/Plater.cpp:855
-msgid "normal mode"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:350
+msgid "Extruder offset"
+msgstr "Décalage de l'extrudeur"
-#: src/slic3r/GUI/Plater.cpp:859
-msgid "silent mode"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:626
+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 "Température de l’extrudeur pour la première couche. Si vous voulez contrôler manuellement la température au cours de l’impression, mettez à zéro pour désactiver les commandes de contrôle de température dans le fichier de sortie."
+
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1573
+msgid "Extruder temperature for layers after the first one. Set this to zero to disable temperature control commands in the output."
+msgstr "Température de l'extrudeur pour les couches après la première. Mettez zéro pour désactiver les commandes de contrôle de la température dans le fichier de sortie."
+
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:431
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:966
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:308
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:702
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:958
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1272
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1445
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1471
+msgid "Extruders"
+msgstr "Extrudeurs"
-#: src/slic3r/GUI/Plater.cpp:1304
-msgid "Loading"
-msgstr "Chargement"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:360
+msgid "Extrusion axis"
+msgstr "Axe d'extrusion"
-#: src/slic3r/GUI/Plater.cpp:1314
-#, c-format
-msgid "Processing input file %s\n"
-msgstr "Traitement du fichier d'entrée %s\n"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:367
+msgid "Extrusion multiplier"
+msgstr "Multiplicateur d'extrusion"
-#: src/slic3r/GUI/Plater.cpp:1366
-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 ""
-"Ce fichier contient plusieurs objets positionnés à différentes hauteurs. Au "
-"lieu de les considérer comme des objets distincts, voulez-vous que je "
-"considère\n"
-"ce fichier comme un seul objet en plusieurs parties?\n"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:483
+msgid "Extrusion Temperature:"
+msgstr "Température d'Extrusion :"
-#: src/slic3r/GUI/Plater.cpp:1369 src/slic3r/GUI/Plater.cpp:1411
-msgid "Multi-part object detected"
-msgstr "Objet multi-pièces détecté"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:268
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:377
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:592
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:710
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:967
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1292
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1454
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1614
+msgid "Extrusion Width"
+msgstr "Largeur d'Extrusion"
-#: src/slic3r/GUI/Plater.cpp:1388
-#, c-format
-msgid ""
-"You can't to add the object(s) from %s because of one or some of them "
-"is(are) multi-part"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:453
+msgid "Extrusion width"
+msgstr "Largeur d'extrusion"
-#: src/slic3r/GUI/Plater.cpp:1408
-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 ""
-"Plusieurs objets ont été chargés pour une imprimante multi-matériaux.\n"
-"Au lieu de les considérer comme plusieurs objets, dois-je considérer\n"
-"ces fichiers comment représentant un objets ayant plusieurs pièces ?\n"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:410
+msgid "Facets"
+msgstr "Faces"
-#: src/slic3r/GUI/Plater.cpp:1424
-msgid "Loaded"
-msgstr "Chargé"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:36
+msgid "Fan "
+msgstr "Ventilateur "
-#: src/slic3r/GUI/Plater.cpp:1492
-msgid ""
-"Your object appears to be too large, so it was automatically scaled down to "
-"fit your print bed."
-msgstr ""
-"Votre objet semble être trop grand, il a donc été automatiquement réduit "
-"afin de l'adapter à votre plateau d'impression."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:817
+msgid "Fan settings"
+msgstr "Réglages du ventilateur"
-#: src/slic3r/GUI/Plater.cpp:1493
-msgid "Object too large?"
-msgstr "Objet trop grand ?"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:818
+msgid "Fan speed"
+msgstr "Vitesse du ventilateur"
-#: src/slic3r/GUI/Plater.cpp:1536
-msgid "Export print config"
-msgstr "Exporter la configuration d'impression"
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:330
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:68
+msgid "Feature type"
+msgstr "Type de fonctionnalité"
-#: src/slic3r/GUI/Plater.cpp:1538
-msgid "Save file as:"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:78
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:79
+msgid "Feature types"
+msgstr "Types de fonctionnalité"
-#: src/slic3r/GUI/Plater.cpp:1702
-msgid "Arranging canceled"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:183
+msgid "Fewer"
+msgstr "Moins"
-#: src/slic3r/GUI/Plater.cpp:1705
-msgid "Arranging"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:786
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:787
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:368
+msgid "Filament"
+msgstr "Filament"
-#: src/slic3r/GUI/Plater.cpp:1736
-msgid "Could not arrange model objects! Some geometries may be invalid."
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:412
+msgid "Filament and Nozzle Diameters"
+msgstr "Diamètres du Filament et de la Buse"
-#: src/slic3r/GUI/Plater.cpp:1740
-msgid "Arranging done."
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:445
+msgid "Filament Diameter:"
+msgstr "Diamètre du Filament :"
-#: src/slic3r/GUI/Plater.cpp:1782
-msgid "Orientation search canceled"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:412
+msgid "Filament notes"
+msgstr "Notes du filament"
-#: src/slic3r/GUI/Plater.cpp:1787
-msgid "Searching for optimal orientation"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:1031
+msgid "Filament parking position"
+msgstr "Position d'attente du filament"
-#: src/slic3r/GUI/Plater.cpp:1797
-msgid "Orientation found."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:832
+msgid "Filament properties"
+msgstr "Propriétés du filament"
-#: src/slic3r/GUI/Plater.cpp:1818
-msgid ""
-"The selected object can't be split because it contains more than one volume/"
-"material."
-msgstr ""
-"L'objet sélectionné ne peut être scindé car il contient plus d'un volume/"
-"matériau."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:202
+msgid "Filament Settings"
+msgstr "Réglages du filament"
-#: src/slic3r/GUI/Plater.cpp:1945 src/slic3r/GUI/PrintHostDialogs.cpp:174
-msgid "Cancelling"
-msgstr "Annulation"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:450
+msgid "Filament type"
+msgstr "Type de filament"
-#: src/slic3r/GUI/Plater.cpp:1962
-msgid "Another export job is currently running."
-msgstr "Une autre tâche d'export est actuellement en cours."
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:44
+msgid "filaments"
+msgstr "filaments"
-#: src/slic3r/GUI/Plater.cpp:2215
-msgid "Export failed"
-msgstr "L'export a échoué"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1445
+msgid "File added to print queue"
+msgstr "Fichier ajouté à la file d'impression"
-#: src/slic3r/GUI/Plater.cpp:2219 src/slic3r/GUI/PrintHostDialogs.cpp:175
-msgid "Cancelled"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:475
+msgid "File Not Found"
+msgstr "Fichier non trouvé"
-#: src/slic3r/GUI/Plater.cpp:2346 src/slic3r/GUI/Tab.cpp:2736
-msgid "Delete"
-msgstr "Supprimer"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:487
+msgid "Fill angle"
+msgstr "Angle du remplissage"
-#: src/slic3r/GUI/Plater.cpp:2346
-msgid "Remove the selected object"
-msgstr "Retirer l'objet sélectionné"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:501
+msgid "Fill density"
+msgstr "Densité du remplissage"
-#: src/slic3r/GUI/Plater.cpp:2349
-msgid "Increase copies"
-msgstr "Augmenter les copies"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:539
+msgid "Fill pattern"
+msgstr "Motif de remplissage"
-#: src/slic3r/GUI/Plater.cpp:2349
-msgid "Place one more copy of the selected object"
-msgstr "Placer une copie supplémentaire de l'objet sélectionné"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:541
+msgid "Fill pattern for general low-density infill."
+msgstr "Motif pour les remplissages de faible densité."
-#: src/slic3r/GUI/Plater.cpp:2351
-msgid "Decrease copies"
-msgstr "Réduire les copies"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:248
+msgid "Fill pattern for top/bottom infill. This only affects the external visible layer, and not its adjacent solid shells."
+msgstr "Motif pour les surfaces supérieurs/inférieurs. Ceci affecte seulement la couche externe visible, et non les replissages plein adjacents."
-#: src/slic3r/GUI/Plater.cpp:2351
-msgid "Remove one copy of the selected object"
-msgstr "Retirer une copie de l'objet sélectionné"
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:194
+msgid "Finished"
+msgstr "Terminé"
-#: src/slic3r/GUI/Plater.cpp:2353
-msgid "Set number of copies"
-msgstr "Choisir le nombre de copies"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1110
+msgid "Firmware"
+msgstr "Firmware"
-#: src/slic3r/GUI/Plater.cpp:2353
-msgid "Change the number of copies of the selected object"
-msgstr "Changer le nombre de copies de l'objet sélectionné"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:266
+msgid "Firmware flasher"
+msgstr "Outil de flash du firmware"
-#: src/slic3r/GUI/Plater.cpp:2363
-msgid "Reload from Disk"
-msgstr "Recharger depuis le Disque"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:293
+msgid "Firmware image:"
+msgstr "Image du firmware :"
-#: src/slic3r/GUI/Plater.cpp:2363
-msgid "Reload the selected file from Disk"
-msgstr "Recharger le fichier sélectionné depuis le Disque"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1314
+msgid "Firmware Retraction"
+msgstr "Rétraction du Firmware"
-#: src/slic3r/GUI/Plater.cpp:2366
-msgid "Export object as STL"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:356
+msgid "Firmware Type"
+msgstr "Type de Firmware"
-#: src/slic3r/GUI/Plater.cpp:2366
-msgid "Export this single object as STL file"
-msgstr "Exporter cet unique objet en fichier STL"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:573
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:582
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:591
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:625
+msgid "First layer"
+msgstr "Première couche"
-#: src/slic3r/GUI/Plater.cpp:2375
-msgid "Along X axis"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:603
+msgid "First layer height"
+msgstr "Hauteur de la première couche"
-#: src/slic3r/GUI/Plater.cpp:2375
-msgid "Mirror the selected object along the X axis"
-msgstr "Symétriser l'objet sélectionné selon l'axe X"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:615
+msgid "First layer speed"
+msgstr "Vitesse de la première couche"
-#: src/slic3r/GUI/Plater.cpp:2377
-msgid "Along Y axis"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214
+msgid "First layer volumetric"
+msgstr "Volume de la première couche"
-#: src/slic3r/GUI/Plater.cpp:2377
-msgid "Mirror the selected object along the Y axis"
-msgstr "Symétriser l'objet sélectionné selon l'axe Y"
+#: xs/src/slic3r/GUI/GUI.cpp:326
+msgid "Flash printer firmware"
+msgstr "Flasher le firmware de l'imprimante"
-#: src/slic3r/GUI/Plater.cpp:2379
-msgid "Along Z axis"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:84
+msgid "Flash!"
+msgstr "Flash !"
-#: src/slic3r/GUI/Plater.cpp:2379
-msgid "Mirror the selected object along the Z axis"
-msgstr "Symétriser l'objet sélectionné selon l'axe Z"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:147
+msgid "Flashing cancelled."
+msgstr "Processus de flash annulé."
-#: src/slic3r/GUI/Plater.cpp:2382
-msgid "Mirror"
-msgstr "Symétrie"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:146
+msgid "Flashing failed. Please see the avrdude log below."
+msgstr "Le processus de flash a échoué. Veuillez consulter le journal avrdude ci-dessous."
-#: src/slic3r/GUI/Plater.cpp:2382
-msgid "Mirror the selected object"
-msgstr "Symétriser l'objet sélectionné"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:123
+msgid "Flashing in progress. Please do not disconnect the printer!"
+msgstr "Processus de flash en cours. Veuillez ne pas déconnecter l'imprimante !"
-#: src/slic3r/GUI/Plater.cpp:2400
-msgid "To objects"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:145
+msgid "Flashing succeeded!"
+msgstr "Flash effectué avec succès !"
-#: src/slic3r/GUI/Plater.cpp:2400 src/slic3r/GUI/Plater.cpp:2431
-msgid "Split the selected object into individual objects"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:466
+msgid "Flow"
+msgstr "Flux"
-#: src/slic3r/GUI/Plater.cpp:2402
-msgid "To parts"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:181
+msgid "For more information please visit our wiki page:"
+msgstr "Pour plus d'informations, merci de visiter notre page wiki :"
-#: src/slic3r/GUI/Plater.cpp:2402 src/slic3r/GUI/Plater.cpp:2451
-msgid "Split the selected object into individual sub-parts"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:599
+msgid ""
+"For the Wipe Tower to work with the soluble supports, the support layers\n"
+"need to be synchronized with the object layers.\n"
+"\n"
+"Shall I synchronize support layers in order to enable the Wipe Tower?"
msgstr ""
+"Pour que la tour de nettoyage fonctionne avec des supports solubles, les couches de support\n"
+"doivent être synchronisées avec les couches de l'objet.\n"
+"\n"
+"Dois-je synchroniser les couches de support pour pouvoir activer la tour de nettoyage ?"
-#: src/slic3r/GUI/Plater.cpp:2405 src/slic3r/GUI/Plater.cpp:2431
-#: src/slic3r/GUI/Plater.cpp:2451
-msgid "Split"
-msgstr "Scinder"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1264
+msgid "Force solid infill for regions having a smaller area than the specified threshold."
+msgstr "Forcer un remplissage plein pour les zones ayant une surface plus petite que la valeur indiquée."
-#: src/slic3r/GUI/Plater.cpp:2405
-msgid "Split the selected object"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:758
+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 "Force la génération de coques pleines entre des volumes/matériaux adjacents. Utile pour des impressions multi-extrudeurs avec des matériaux translucides ou avec un support manuel soluble."
-#: src/slic3r/GUI/Plater.cpp:2435
-msgid "Optimize orientation"
-msgstr ""
-
-#: src/slic3r/GUI/Plater.cpp:2435
-msgid "Optimize the rotation of the object for better print results."
-msgstr ""
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:260
+msgid "From"
+msgstr "De"
-#: src/slic3r/GUI/Plater.cpp:2795
-msgid "Save G-code file as:"
-msgstr "Sauvegarder le fichier G-code en tant que :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:371
+msgid "Front"
+msgstr "Avant"
-#: src/slic3r/GUI/Plater.cpp:2795
-msgid "Save Zip file as:"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:371
+msgid "Front View"
+msgstr "Vue Avant"
-#: src/slic3r/GUI/Plater.cpp:2845
-#, c-format
-msgid "STL file exported to %s"
-msgstr "Fichier STL exporté vers %s"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:514
+msgid "G-code"
+msgstr "G-code"
-#: src/slic3r/GUI/Plater.cpp:2861
-#, c-format
-msgid "AMF file exported to %s"
-msgstr "Fichier AMF exporté vers %s"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1451
+msgid "G-code file exported to "
+msgstr "Fichier G-code exporté vers "
-#: src/slic3r/GUI/Plater.cpp:2864
-#, c-format
-msgid "Error exporting AMF file %s"
-msgstr "Erreur d'export du fichier AMF %s"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:652
+msgid "G-code flavor"
+msgstr "Version du G-code"
-#: src/slic3r/GUI/Plater.cpp:2891
-#, c-format
-msgid "3MF file exported to %s"
-msgstr "Fichier 3MF exporté vers %s"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:444
+msgid "g/cm³"
+msgstr "g/cm³"
-#: src/slic3r/GUI/Plater.cpp:2894
-#, c-format
-msgid "Error exporting 3MF file %s"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:634
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:145
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:87
+msgid "Gap fill"
+msgstr "Remplissage des trous"
-#: src/slic3r/GUI/Preferences.cpp:17 src/slic3r/GUI/Tab.cpp:1712
-#: src/slic3r/GUI/Tab.cpp:1911
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:937
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:11
msgid "General"
msgstr "Général"
-#: src/slic3r/GUI/Preferences.cpp:34
-msgid "Remember output directory"
-msgstr "Se souvenir du répertoire de sortie"
-
-#: 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 ""
-"Si ceci est activé, Slic3r affichera le dernier répertoire de sortie au lieu "
-"de celui contenant les fichiers d'entrée."
-
-#: src/slic3r/GUI/Preferences.cpp:42
-msgid "Auto-center parts"
-msgstr "Centrer automatiquement les pièces"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:875
+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 "Nombre minimum de clôtures à générer afin de consommer la quantité de filament spécifiée sur la couche inférieure. Pour les machines multi-extrudeurs, ce minimum s'applique à chaque extrudeur."
-#: src/slic3r/GUI/Preferences.cpp:44
-msgid ""
-"If this is enabled, Slic3r will auto-center objects around the print bed "
-"center."
-msgstr ""
-"Si ceci est activé, Slic3r centrera automatique les objets autour du centre "
-"du plateau d'impression."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1379
+msgid "Generate support material"
+msgstr "Générer des supports"
-#: src/slic3r/GUI/Preferences.cpp:50
-msgid "Background processing"
-msgstr "Tâche en arrière plan"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1433
+msgid "Generate support material for the specified number of layers counting from bottom, regardless of whether normal support material is enabled or not and regardless of any angle threshold. This is useful for getting more adhesion of objects having a very thin or poor footprint on the build plate."
+msgstr "Générer des supports pour le nombre de couches spécifié à partir du bas, que les supports normaux soient activés ou non et sans tenir compte de seuils d'inclinaison. Ceci est utile pour obtenir une meilleure adhésion pour des objets ayant une surface de contact très fine ou limitée sur le plateau."
-#: 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 ""
-"Si ceci est activé, Slic3r va pré-calculer les objets dès qu'ils sont "
-"chargés pour gagner du temps lors de l'export du G-code."
+#: 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 "Une bonne précision est requise, utilisez un pied à coulisse et calculez la moyenne de plusieurs mesures le long du filament."
-#: src/slic3r/GUI/Preferences.cpp:74
-msgid "Suppress \" - default - \" presets"
-msgstr "Supprimer les préréglages \" - par défaut - \""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:583
+msgid "Heated build plate temperature for the first layer. Set this to zero to disable bed temperature control commands in the output."
+msgstr "Température du plateau chauffant pour la première couche. Mettez ceci à zéro pour désactiver les commandes de contrôle de température du plateau dans la sortie."
-#: src/slic3r/GUI/Preferences.cpp:76
-msgid ""
-"Suppress \" - default - \" presets in the Print / Filament / Printer "
-"selections once there are any other valid presets available."
-msgstr ""
-"Supprimer les préréglages \" - par défaut - \" dans les choix Impression / "
-"Filament / Imprimante une fois qu'il y a d'autres préréglages valides "
-"disponibles."
-
-#: src/slic3r/GUI/Preferences.cpp:82
-msgid "Show incompatible print and filament presets"
-msgstr "Afficher les préréglages d'impression et de filament incompatibles"
-
-#: src/slic3r/GUI/Preferences.cpp:84
-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 ""
-"Lorsqu'ils sont sélectionnés, les préréglages de l'imprimante et du filament "
-"sont visibles dans l'éditeur de préréglage même s'ils sont désignés comme "
-"incompatibles avec l'imprimante en cours d'utilisation"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:320
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:69
+msgid "Height"
+msgstr "Hauteur"
-#: src/slic3r/GUI/Preferences.cpp:90
-msgid "Use legacy OpenGL 1.1 rendering"
-msgstr "Utiliser le rendu de legacy OpenGL 1.1"
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:332
+msgid "Height (mm)"
+msgstr "Hauteur (mm)"
-#: src/slic3r/GUI/Preferences.cpp:92
-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 ""
-"Si vous avez des soucis de rendu causés par un driver OpenGL 2.0 bogué, vous "
-"pouvez essayer de cocher cette case. Ceci désactivera l'édition de la "
-"hauteur de couche et l'anti-aliasing, vous avez donc intérêt à mettre à jour "
-"vos drivers graphiques."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1222
+msgid "Height of skirt expressed in layers. Set this to a tall value to use skirt as a shield against drafts."
+msgstr "Hauteur de la clôture exprimée en couches. Mettez une valeur élevée pour utiliser la clôture comme un bouclier contre les flux d'airs."
-#: src/slic3r/GUI/Preferences.cpp:115
-msgid "You need to restart Slic3r to make the changes effective."
-msgstr ""
-"Vous devez redémarrer Slic3r afin que les modifications soient appliquées."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:213
+#, c-format
+msgid "Hello, welcome to Slic3r Slic3r++! This %s helps you with the initial configuration; just a few settings and you will be ready to print."
+msgstr "Bonjour, bienvenu dans Slic3r Slic3r++ ! Ce %s vous aide à la configuration initiale ; juste quelques paramètres et vous serez prêt à imprimer."
-#: src/slic3r/GUI/Preset.cpp:170
-msgid "modified"
-msgstr ""
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:218
+msgid "Here you can adjust required purging volume (mm³) for any given pair of tools."
+msgstr "Ici vous pouvez ajuster le volume de purge nécessaire (mm³) pour une paire d'outils donnée."
-#: src/slic3r/GUI/Preset.cpp:862 src/slic3r/GUI/Preset.cpp:902
-#: src/slic3r/GUI/Preset.cpp:930 src/slic3r/GUI/Preset.cpp:962
-#: src/slic3r/GUI/PresetBundle.cpp:1459 src/slic3r/GUI/PresetBundle.cpp:1512
-msgid "System presets"
-msgstr "Préréglages système"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:329
+msgid "Horizontal shells"
+msgstr "Coques horizontales"
-#: src/slic3r/GUI/Preset.cpp:906 src/slic3r/GUI/Preset.cpp:966
-#: src/slic3r/GUI/PresetBundle.cpp:1517
-msgid "User presets"
-msgstr "Préréglages utilisateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:128
+msgid "Horizontal width of the brim that will be printed around each object on the first layer."
+msgstr "Largeur horizontale de la jupe qui sera imprimée autour de chaque objet sur la première couche."
-#: src/slic3r/GUI/Preset.cpp:1157
-msgid "filament"
-msgstr ""
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:67
+msgid "Hostname"
+msgstr "Nom d'hôte"
-#: src/slic3r/GUI/PresetHints.cpp:28
-#, c-format
-msgid ""
-"If estimated layer time is below ~%ds, fan will run at %d%% and print speed "
-"will be reduced so that no less than %ds are spent on that layer (however, "
-"speed will never be reduced below %dmm/s)."
-msgstr ""
-"Si le temps de couche estimé est inférieur à ~%d s, le ventilateur tournera "
-"à %d%% et la vitesse d'impression sera réduite pour qu'au moins %d s soient "
-"passées sur cette couche (cependant, la vitesse ne sera jamais réduite en-"
-"dessous de %d mm/s)."
+#: xs/src/libslic3r/PrintConfig.cpp:991
+msgid "Hostname, IP or URL"
+msgstr "Nom d'hôte, IP ou URL"
-#: src/slic3r/GUI/PresetHints.cpp:32
-#, c-format
+#: xs/src/slic3r/GUI/Tab.cpp:113
msgid ""
-"\n"
-"If estimated layer time is greater, but still below ~%ds, fan will run at a "
-"proportionally decreasing speed between %d%% and %d%%."
+"Hover the cursor over buttons to find more information \n"
+"or click this button."
msgstr ""
-"\n"
-"Si le temps estimé pour la couche est supérieur, mais cependant inférieur à ~"
-"%ds, le ventilateur tournera à une vitesse proportionnellement décroissante "
-"entre %d%% et %d%%."
+"Passez le curseur au dessus des boutons pour obtenir plus d'informations\n"
+"ou cliquez sur ce bouton."
-#: src/slic3r/GUI/PresetHints.cpp:36
-msgid ""
-"\n"
-"During the other layers, fan "
-msgstr ""
-"\n"
-"Pendant les autres couches, le ventilateur "
+#: 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 "Le fichier HTTPS CA est optionnel. Il est uniquement requis si vous utilisez le HTTPS avec un certificat auto-signé."
-#: src/slic3r/GUI/PresetHints.cpp:38
-msgid "Fan "
-msgstr "Ventilateur "
+#: 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 "Si activé, Slic3r vérifie en ligne l'existence de nouvelles versions de Slic3r PE. Lorsqu'une nouvelle version est disponible, une notification est affichée au démarrage suivant de l'application (jamais pendant l'utilisation du programme). Ceci est uniquement un mécanisme de notification, aucune installation automatique n'est faite."
-#: src/slic3r/GUI/PresetHints.cpp:43
-#, c-format
-msgid "will always run at %d%% "
-msgstr "fonctionnera toujours à %d%% "
+#: 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 "Si activé, Slic3r télécharge les mises à jours des préréglages système intégrés en arrière-plan. Ces mises à jour sont téléchargées dans un répertoire temporaire séparé. Lorsqu'une nouvelle version de préréglages est disponible, elle est proposée au démarrage de l'application."
-#: src/slic3r/GUI/PresetHints.cpp:46
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:26
#, c-format
-msgid "except for the first %d layers"
-msgstr "sauf pour les %d première couches"
-
-#: src/slic3r/GUI/PresetHints.cpp:50
-msgid "except for the first layer"
-msgstr "sauf pour la première couche"
-
-#: src/slic3r/GUI/PresetHints.cpp:52
-msgid "will be turned off."
-msgstr "sera désactivé."
-
-#: src/slic3r/GUI/PresetHints.cpp:153
-msgid "external perimeters"
-msgstr "périmètres externes"
-
-#: src/slic3r/GUI/PresetHints.cpp:162
-msgid "perimeters"
-msgstr "périmètres"
-
-#: src/slic3r/GUI/PresetHints.cpp:171
-msgid "infill"
-msgstr "remplissage"
+msgid "If estimated layer time is below ~%ds, fan will run at %d%% and print speed will be reduced so that no less than %ds are spent on that layer (however, speed will never be reduced below %dmm/s)."
+msgstr "Si le temps de couche estimé est inférieur à ~%d s, le ventilateur tournera à %d%% et la vitesse d'impression sera réduite pour qu'au moins %d s soient passées sur cette couche (cependant, la vitesse ne sera jamais réduite en-dessous de %d mm/s)."
-#: src/slic3r/GUI/PresetHints.cpp:181
-msgid "solid infill"
-msgstr "remplissage solide"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:616
+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 "Si exprimée avec une valeur absolue en mm/s, cette vitesse sera appliquée à tous les déplacements d'impression de la première couche, quel que soit leur type. Si exprimée comme un pourcentage (par exemple 40%), cela modulera la vitesse par défaut."
-#: src/slic3r/GUI/PresetHints.cpp:189
-msgid "top solid infill"
-msgstr "remplissage solide supérieur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:395
+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 "Si le temps d'impression estimé de la couche est inférieur à ce nombre de secondes, le ventilateur sera activé et sa vitesse calculée par interpolation des vitesses minimum et maximum."
-#: src/slic3r/GUI/PresetHints.cpp:200
-msgid "support"
-msgstr "support"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1240
+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 "Si le temps d'impression estimé de la couche est inférieur à ce nombre de secondes, la vitesse des déplacements d'impression sera réduite afin d'atteindre cette valeur."
-#: src/slic3r/GUI/PresetHints.cpp:210
-msgid "support interface"
-msgstr "interface du support"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:388
+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 "Si ceci est activé, le ventilateur ne sera jamais désactivé et sera maintenu au moins à sa vitesse minimum. Utile pour le PLA, mais risqué pour l'ABS."
-#: src/slic3r/GUI/PresetHints.cpp:216
-msgid "First layer volumetric"
-msgstr "Volume de la première couche"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:37
+msgid "If this is enabled, Slic3r will auto-center objects around the print bed center."
+msgstr "Si ceci est activé, Slic3r centrera automatique les objets autour du centre du plateau d'impression."
-#: src/slic3r/GUI/PresetHints.cpp:216
-msgid "Bridging volumetric"
-msgstr "Volumétrie des ponts"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:45
+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 "Si ceci est activé, Slic3r va pré-calculer les objets dès qu'ils sont chargés pour gagner du temps lors de l'export du G-code."
-#: src/slic3r/GUI/PresetHints.cpp:216
-msgid "Volumetric"
-msgstr "Volumétrique"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:29
+msgid "If this is enabled, Slic3r will prompt the last output directory instead of the one containing the input files."
+msgstr "Si ceci est activé, Slic3r affichera le dernier répertoire de sortie au lieu de celui contenant les fichiers d'entrée."
-#: src/slic3r/GUI/PresetHints.cpp:217
-msgid " flow rate is maximized "
-msgstr " le débit est maximisé "
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:77
+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 "Si vous avez des soucis de rendu causés par un driver OpenGL 2.0 bogué, vous pouvez essayer de cocher cette case. Ceci désactivera l'édition de la hauteur de couche et l'anti-aliasing, vous avez donc intérêt à mettre à jour vos drivers graphiques."
-#: src/slic3r/GUI/PresetHints.cpp:220
-msgid "by the print profile maximum"
-msgstr "par le maximum du profil de l'imprimante"
-
-#: src/slic3r/GUI/PresetHints.cpp:221
-msgid "when printing "
-msgstr "pendant l'impression des "
-
-#: src/slic3r/GUI/PresetHints.cpp:222
-msgid " with a volumetric rate "
-msgstr " avec un débit volumétrique "
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1091
+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 "Si vous indiquez une valeur positive, l'axe Z est rapidement élevé à chaque rétraction. Lorsque vous utilisez plusieurs extrudeurs, seul le réglage du premier extrudeur sera pris en compte."
-#: src/slic3r/GUI/PresetHints.cpp:226
-#, c-format
-msgid "%3.2f mm³/s"
-msgstr "%3.2f mm³/s"
-
-#: src/slic3r/GUI/PresetHints.cpp:228
-#, c-format
-msgid " at filament speed %3.2f mm/s."
-msgstr " à une vitesse de filament de %3.2f mm/s."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1101
+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 "Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché qu'à partir de la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier ce réglage pour éviter le levage de l'axe Z sur les premières couches."
-#: src/slic3r/GUI/PresetHints.cpp:247
-msgid ""
-"Recommended object thin wall thickness: Not available due to invalid layer "
-"height."
-msgstr ""
-"Épaisseur des parois fines de l'objet recommandée : Non disponible car la "
-"hauteur de couche est invalide."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1110
+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 "Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché que jusqu'à la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier ce réglage pour limiter le levage de l'axe Z aux premières couches."
-#: src/slic3r/GUI/PresetHints.cpp:264
-#, c-format
-msgid "Recommended object thin wall thickness for layer height %.2f and "
-msgstr ""
-"Épaisseur des parois fines de l'objet recommandée pour la hauteur de couche "
-"%.2f et "
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:451
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1002
+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. Scripts will be passed the absolute path to the G-code file as the first argument, and they can access the Slic3r config settings by reading environment variables."
+msgstr "Si vous voulez traiter le G-code de sortie à l'aide de scripts personnalisés, listez simplement leurs chemins absolus ici. Séparez les divers scripts avec un point virgule. Les scripts vont recevoir en premier argument le chemin absolu du fichier G-code, et ils peuvent accéder aux réglages de configuration de Slic3r en lisant des variables d'environnement."
-#: src/slic3r/GUI/PresetHints.cpp:271
-#, c-format
-msgid "%d lines: %.2lf mm"
-msgstr "%d lignes : %.2lf mm"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:351
+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 of each extruder with respect to the first one. It expects positive coordinates (they will be subtracted from the XY coordinate)."
+msgstr "Si le firmware de votre imprimante ne gère pas le décalage de l'extrudeur, c'est au G-code d'en tenir compte. Cette option vous permet de spécifier le décalage de chaque extrudeur par rapport au premier. Des valeurs positives sont attendues (elles seront soustraites des coordonnées XY)."
-#: src/slic3r/GUI/PrintHostDialogs.cpp:29
-msgid "Send G-Code to printer host"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1664
+msgid "If your firmware requires relative E values, check this, otherwise leave it unchecked. Most firmwares use absolute values."
+msgstr "Si votre firmware requiert des valeurs relatives pour E, cochez cette case, sinon laissez-la décochée. La plupart des firmwares utilisent des valeurs absolues."
-#: src/slic3r/GUI/PrintHostDialogs.cpp:29
-msgid "Upload to Printer Host with the following filename:"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:125
+msgid "Incompatible bundles:"
+msgstr "Lots incompatibles :"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:31
-msgid "Start printing after upload"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:67
+msgid "Incompatible with this Slic3r"
+msgstr "Incompatible avec ce Slic3r"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:33
-msgid "Use forward slashes ( / ) as a directory separator if needed."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2024
+msgid "Increase copies"
+msgstr "Augmenter les copies"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:111
-msgid "Cancel selected"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:346
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:347
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:664
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:87
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:247
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:488
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:502
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:540
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:681
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:691
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:709
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:727
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:746
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1263
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1280
+msgid "Infill"
+msgstr "Remplissage"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:113
-msgid "Show error message"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:169
+msgid "infill"
+msgstr "remplissage"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:115
-msgid "Close"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:720
+msgid "Infill before perimeters"
+msgstr "Remplissage avant les périmètres"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:152
-#: src/slic3r/GUI/PrintHostDialogs.cpp:171
-msgid "Enqueued"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:701
+msgid "Infill extruder"
+msgstr "Extrudeur pour le remplissage"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:172
-msgid "Uploading"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:735
+msgid "Infill/perimeters overlap"
+msgstr "Chevauchement remplissage/périmètres"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:176
-msgid "Completed"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:398
+msgid "Info"
+msgstr "Info"
-#: src/slic3r/GUI/PrintHostDialogs.cpp:214
-msgid "Error uploading to print host:"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:819
+msgid "Inherits profile"
+msgstr "Hérite du profil"
-#: src/slic3r/GUI/RammingChart.cpp:23
-msgid "NO RAMMING AT ALL"
-msgstr "PAS D'EXPULSION DU TOUT"
+#: xs/src/slic3r/GUI/Field.cpp:111
+msgid "Input value is out of range"
+msgstr "La valeur entrée est hors plage"
-#: src/slic3r/GUI/RammingChart.cpp:76
-msgid "Time"
-msgstr "Durée"
+#: xs/src/slic3r/GUI/GUI.cpp:402
+msgid "Inspect / activate configuration snapshots"
+msgstr "Inspecter / activer les instantanés de configuration"
-#: src/slic3r/GUI/RammingChart.cpp:76 src/slic3r/GUI/RammingChart.cpp:81
-#: src/slic3r/GUI/WipeTowerDialog.cpp:78 src/libslic3r/PrintConfig.cpp:603
-#: src/libslic3r/PrintConfig.cpp:653 src/libslic3r/PrintConfig.cpp:670
-#: src/libslic3r/PrintConfig.cpp:2352 src/libslic3r/PrintConfig.cpp:2360
-#: src/libslic3r/PrintConfig.cpp:2432 src/libslic3r/PrintConfig.cpp:2440
-msgid "s"
-msgstr "s"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1479
+msgid "Interface layers"
+msgstr "Couches d'interface"
-#: src/slic3r/GUI/RammingChart.cpp:81
-msgid "Volumetric speed"
-msgstr "Vitesse volumétrique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1463
+msgid "Interface loops"
+msgstr "Boucles d'interface"
-#: src/slic3r/GUI/SysInfoDialog.cpp:40
-msgid "Slic3r Prusa Edition - System Information"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1488
+msgid "Interface pattern spacing"
+msgstr "Espacement du motif d'interface"
-#: src/slic3r/GUI/Tab.cpp:49 src/libslic3r/PrintConfig.cpp:202
-msgid "Compatible printers"
-msgstr "Imprimantes compatibles"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:757
+msgid "Interface shells"
+msgstr "Coques d'interface"
-#: src/slic3r/GUI/Tab.cpp:50
-msgid "Select the printers this profile is compatible with."
-msgstr "Sélectionner les imprimantes avec lesquelles ce profil est compatible."
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:141
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:83
+msgid "Internal infill"
+msgstr "Remplissage interne"
-#: src/slic3r/GUI/Tab.cpp:55 src/libslic3r/PrintConfig.cpp:215
-msgid "Compatible print profiles"
-msgstr ""
+#: xs/src/slic3r/Utils/OctoPrint.cpp:120
+msgid "Invalid API key"
+msgstr "Clé API invalide"
-#: src/slic3r/GUI/Tab.cpp:56
-msgid "Select the print profiles this profile is compatible with."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1031
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1035
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1056
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1061
+msgid "Invalid scaling value entered"
+msgstr "Valeur de mise à l'échelle entrée invalide"
-#: src/slic3r/GUI/Tab.cpp:118
-msgid "Save current "
-msgstr "Enregistrer l'état actuel "
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:368
+msgid "Iso"
+msgstr "Isométrique"
-#: src/slic3r/GUI/Tab.cpp:119
-msgid "Delete this preset"
-msgstr "Supprimer ce préréglage"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:368
+msgid "Iso View"
+msgstr "Vue Isométrique"
-#: src/slic3r/GUI/Tab.cpp:131
-msgid ""
-"Hover the cursor over buttons to find more information \n"
-"or click this button."
-msgstr ""
-"Passez le curseur au dessus des boutons pour obtenir plus d'informations\n"
-"ou cliquez sur ce bouton."
+#: xs/src/slic3r/GUI/Tab.cpp:748
+msgid "It can't be deleted or modified. "
+msgstr "Il ne peut être supprimé ou modifié. "
-#: src/slic3r/GUI/Tab.cpp:824
+#: xs/src/slic3r/GUI/Tab.cpp:741
msgid "It's a default preset."
msgstr "C'est un préréglage par défaut."
-#: src/slic3r/GUI/Tab.cpp:825
+#: xs/src/slic3r/GUI/Tab.cpp:742
msgid "It's a system preset."
msgstr "C'est un préréglage système."
-#: src/slic3r/GUI/Tab.cpp:826
-msgid "Current preset is inherited from "
-msgstr "Le préréglage en cours a hérité de "
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1180
+msgid "Jitter"
+msgstr "Gigue"
-#: src/slic3r/GUI/Tab.cpp:831
-msgid "It can't be deleted or modified. "
-msgstr "Il ne peut être supprimé ou modifié. "
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:387
+msgid "Keep fan always on"
+msgstr "Garder le ventilateur toujours actif"
-#: src/slic3r/GUI/Tab.cpp:832
-msgid ""
-"Any modifications should be saved as a new preset inherited from this one. "
-msgstr ""
-"Toute modification doit être enregistrée comme un nouveau préréglage hérité "
-"de celui-ci. "
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:235
+msgid "Language"
+msgstr "Langue"
-#: src/slic3r/GUI/Tab.cpp:833
-msgid "To do that please specify a new name for the preset."
-msgstr "Pour faire cela veuillez spécifier un nouveau nom pour le préréglage."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:192
+msgid "Layer Editing"
+msgstr "Édition de Couche"
-#: src/slic3r/GUI/Tab.cpp:837
-msgid "Additional information:"
-msgstr "Informations complémentaires :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:207
+msgid "Layer editing"
+msgstr "Édition de couche"
-#: src/slic3r/GUI/Tab.cpp:843
-msgid "printer model"
-msgstr "modèle de l'imprimante"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:314
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:777
+msgid "Layer height"
+msgstr "Hauteur de couche"
-#: src/slic3r/GUI/Tab.cpp:851
-msgid "default print profile"
-msgstr "profil d'impression par défaut"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1194
+msgid "Layer height limits"
+msgstr "Limites de hauteur de couche"
-#: src/slic3r/GUI/Tab.cpp:854
-msgid "default filament profile"
-msgstr "profil du filament par défaut"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:183
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:694
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1033
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1224
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1285
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1437
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1482
+msgid "layers"
+msgstr "couches"
-#: src/slic3r/GUI/Tab.cpp:868
-msgid "default SLA material profile"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:157
+msgid "Layers"
+msgstr "Couches"
-#: src/slic3r/GUI/Tab.cpp:872
-msgid "default SLA print profile"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:69
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:239
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:290
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:298
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:604
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:762
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:778
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:941
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:989
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1152
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1583
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1639
+msgid "Layers and Perimeters"
+msgstr "Couches et Périmètres"
-#: src/slic3r/GUI/Tab.cpp:919 src/slic3r/GUI/Tab.cpp:3174
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:313
msgid "Layers and perimeters"
msgstr "Couches et périmètres"
-#: src/slic3r/GUI/Tab.cpp:920 src/libslic3r/PrintConfig.cpp:46
-msgid "Layer height"
-msgstr "Hauteur de couche"
-
-#: src/slic3r/GUI/Tab.cpp:924
-msgid "Vertical shells"
-msgstr "Parois verticales"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:373
+msgid "Left"
+msgstr "Gauche"
-#: src/slic3r/GUI/Tab.cpp:935
-msgid "Horizontal shells"
-msgstr "Coques horizontales"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:373
+msgid "Left View"
+msgstr "Vue Gauche"
-#: src/slic3r/GUI/Tab.cpp:936 src/libslic3r/PrintConfig.cpp:1788
-msgid "Solid layers"
-msgstr "Couches solides"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1071
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1080
+msgid "Length"
+msgstr "Longueur"
-#: src/slic3r/GUI/Tab.cpp:941
-msgid "Quality (slower slicing)"
-msgstr "Qualité (découpage plus lent)"
+#: xs/src/libslic3r/PrintConfig.cpp:179
+msgid "Length of the cooling tube to limit space for cooling moves inside it "
+msgstr "Longueur du tube de refroidissement pour limiter l'espace pour les déplacements de refroidissement à l'intérieur de celui-ci "
-#: src/slic3r/GUI/Tab.cpp:958
-msgid "Reducing printing time"
-msgstr "Réduction du temps d'impression"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1090
+msgid "Lift Z"
+msgstr "Levage de l'axe Z"
-#: src/slic3r/GUI/Tab.cpp:970
-msgid "Skirt and brim"
-msgstr "Jupe et bordure"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:254
+msgid "Load exported configuration file"
+msgstr "Charger le fichier de configuration exporté"
-#: src/slic3r/GUI/Tab.cpp:987
-msgid "Raft"
-msgstr "Radeau"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:260
+msgid "Load presets from a bundle"
+msgstr "Charger les préréglages à partir d'un lot"
-#: src/slic3r/GUI/Tab.cpp:991
-msgid "Options for support material and raft"
-msgstr "Options pour le matériau de support et le radeau"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:75
+msgid "Load shape from STL..."
+msgstr "Charger une forme depuis un STL..."
-#: src/slic3r/GUI/Tab.cpp:1006
-msgid "Speed for print moves"
-msgstr "Vitesse pour les déplacements d'impression"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:692
+msgid "Loaded "
+msgstr "Chargé "
-#: src/slic3r/GUI/Tab.cpp:1018
-msgid "Speed for non-print moves"
-msgstr "Vitesse pour les déplacements sans impression"
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:233
+msgid "loaded"
+msgstr "chargé"
-#: src/slic3r/GUI/Tab.cpp:1021
-msgid "Modifiers"
-msgstr "Modificateurs"
+#: xs/src/libslic3r/PrintConfig.cpp:459
+msgid "Loading speed"
+msgstr "Vitesse de chargement"
-#: src/slic3r/GUI/Tab.cpp:1024
-msgid "Acceleration control (advanced)"
-msgstr "Contrôle de l'accélération (avancé)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:629
+msgid "Loading…"
+msgstr "Chargement…"
-#: src/slic3r/GUI/Tab.cpp:1031
-msgid "Autospeed (advanced)"
-msgstr "Vitesse automatique (avancé)"
+#: 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 "L'icône VERROU VERROUILLE indique que les paramètres sont les mêmes que les valeurs système pour le groupe d'options en cours"
-#: src/slic3r/GUI/Tab.cpp:1037
-msgid "Multiple Extruders"
-msgstr "Extrudeurs Multiples"
+#: xs/src/slic3r/GUI/Tab.cpp:2497
+msgid "LOCKED LOCK icon indicates that the value is the same as the system value."
+msgstr "L'icône VERROU VERROUILLE indique que la valeur est la même que la valeur système."
-#: src/slic3r/GUI/Tab.cpp:1045
-msgid "Ooze prevention"
-msgstr "Prévention des coulures"
+#: 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 "VERROU VERROUILLE;indique que les paramètres sont les mêmes que les valeurs système pour le groupe d'options en cours"
-#: src/slic3r/GUI/Tab.cpp:1062
-msgid "Extrusion width"
-msgstr "Largeur d'extrusion"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1229
+msgid "Loops (minimum)"
+msgstr "Boucles (minimum)"
-#: src/slic3r/GUI/Tab.cpp:1072
-msgid "Overlap"
-msgstr "Chevauchement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:412
+msgid "Manifold"
+msgstr "Variété"
-#: src/slic3r/GUI/Tab.cpp:1075
-msgid "Flow"
-msgstr "Flux"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:411
+msgid "Materials"
+msgstr "Matériaux"
-#: src/slic3r/GUI/Tab.cpp:1078
-msgid "Other"
-msgstr "Autre"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:787
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:796
+msgid "Max"
+msgstr "Maximum"
-#: src/slic3r/GUI/Tab.cpp:1085 src/slic3r/GUI/Tab.cpp:3213
-msgid "Output options"
-msgstr "Options de sortie"
+#: xs/src/libslic3r/PrintConfig.cpp:876
+msgid "Max print height"
+msgstr "Hauteur maximale d'impression"
-#: src/slic3r/GUI/Tab.cpp:1086
-msgid "Sequential printing"
-msgstr "Impression séquentielle"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:807
+msgid "Max print speed"
+msgstr "Vitesse d'impression maximale"
-#: src/slic3r/GUI/Tab.cpp:1088
-msgid "Extruder clearance (mm)"
-msgstr "Dégagement de l'extrudeur (mm)"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:52
+msgid "max slic3r version"
+msgstr "version maximale de slic3r"
-#: src/slic3r/GUI/Tab.cpp:1097 src/slic3r/GUI/Tab.cpp:3214
-msgid "Output file"
-msgstr "Fichier de sortie"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:837
+msgid "Max volumetric slope negative"
+msgstr "Pente volumétrique négative maximum"
-#: src/slic3r/GUI/Tab.cpp:1103 src/libslic3r/PrintConfig.cpp:1438
-msgid "Post-processing scripts"
-msgstr "Scripts de post-traitement"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:826
+msgid "Max volumetric slope positive"
+msgstr "Pente volumétrique positive maximum"
-#: src/slic3r/GUI/Tab.cpp:1109 src/slic3r/GUI/Tab.cpp:1110
-#: src/slic3r/GUI/Tab.cpp:1483 src/slic3r/GUI/Tab.cpp:1484
-#: src/slic3r/GUI/Tab.cpp:1883 src/slic3r/GUI/Tab.cpp:1884
-#: src/slic3r/GUI/Tab.cpp:1964 src/slic3r/GUI/Tab.cpp:1965
-#: src/slic3r/GUI/Tab.cpp:3119 src/slic3r/GUI/Tab.cpp:3120
-msgid "Notes"
-msgstr "Notes"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:421
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:817
+msgid "Max volumetric speed"
+msgstr "Vitesse volumétrique maximale"
-#: src/slic3r/GUI/Tab.cpp:1116 src/slic3r/GUI/Tab.cpp:1491
-#: src/slic3r/GUI/Tab.cpp:1890 src/slic3r/GUI/Tab.cpp:1971
-#: src/slic3r/GUI/Tab.cpp:3127 src/slic3r/GUI/Tab.cpp:3219
-msgid "Dependencies"
-msgstr "Dépendances"
+#: xs/src/libslic3r/PrintConfig.cpp:1854
+msgid "Maximal bridging distance"
+msgstr "Distance maximale de pont"
-#: src/slic3r/GUI/Tab.cpp:1117 src/slic3r/GUI/Tab.cpp:1492
-#: src/slic3r/GUI/Tab.cpp:1891 src/slic3r/GUI/Tab.cpp:1972
-#: src/slic3r/GUI/Tab.cpp:3128 src/slic3r/GUI/Tab.cpp:3220
-msgid "Profile dependencies"
-msgstr "Dépendances du profil"
+#: xs/src/libslic3r/PrintConfig.cpp:1855
+msgid "Maximal distance between supports on sparse infill sections. "
+msgstr "Distance maximale entre les supports sur les sections de remplissage épars. "
-#: src/slic3r/GUI/Tab.cpp:1161
-#, no-c-format
-msgid ""
-"The Spiral Vase mode requires:\n"
-"- one perimeter\n"
-"- no top solid layers\n"
-"- 0% fill density\n"
-"- no support material\n"
-"- no ensure_vertical_shell_thickness\n"
-"\n"
-"Shall I adjust those settings in order to enable Spiral Vase?"
-msgstr ""
-"Le mode Vase Spiral requiert :\n"
-"-Un périmètre\n"
-"-Pas de couches solides supérieures\n"
-"-Une densité de remplissage de 0%\n"
-"-Pas de supports\n"
-"-Pas de ensure_vertical_shell_thickness\n"
-"\n"
-"Voulez-vous que je modifie ces réglages afin d'activer le Vase Spirale?"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:422
+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 "Vitesse volumétrique maximale autorisée pour ce filament. Limite la vitesse volumétrique d'une impression au minimum des vitesses volumétriques d'impression et de filament. Mettez à zéro pour enlever la limite."
-#: src/slic3r/GUI/Tab.cpp:1168
-msgid "Spiral Vase"
-msgstr "Vase Spiral"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:848
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:857
+msgid "Min"
+msgstr "Minimum"
-#: src/slic3r/GUI/Tab.cpp:1191
-msgid ""
-"The Wipe Tower currently supports the non-soluble supports only\n"
-"if they are printed with the current extruder without triggering a tool "
-"change.\n"
-"(both support_material_extruder and support_material_interface_extruder need "
-"to be set to 0).\n"
-"\n"
-"Shall I adjust those settings in order to enable the Wipe Tower?"
-msgstr ""
-"A l'heure actuelle la Tour de Nettoyage ne tolère les supports non-"
-"solubles \n"
-"que s'ils sont imprimés avec l'extrudeur en cours d'utilisation sans "
-"déclencher un changement d'outil.\n"
-"(support_material_extruder de même que support_material_interface_extruder "
-"doivent être réglés sur 0).\n"
-"\n"
-"Voulez-vous que je modifie ces réglages pour activer la Tour de Nettoyage ?"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:866
+msgid "Min print speed"
+msgstr "Vitesse d'impression minimale"
-#: src/slic3r/GUI/Tab.cpp:1195 src/slic3r/GUI/Tab.cpp:1212
-msgid "Wipe Tower"
-msgstr "Tour de Nettoyage"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:50
+msgid "min slic3r version"
+msgstr "version minimale de slic3r"
-#: src/slic3r/GUI/Tab.cpp:1209
-msgid ""
-"For the Wipe Tower to work with the soluble supports, the support layers\n"
-"need to be synchronized with the object layers.\n"
-"\n"
-"Shall I synchronize support layers in order to enable the Wipe Tower?"
-msgstr ""
-"Pour que la tour de nettoyage fonctionne avec des supports solubles, les "
-"couches de support\n"
-"doivent être synchronisées avec les couches de l'objet.\n"
-"\n"
-"Dois-je synchroniser les couches de support pour pouvoir activer la tour de "
-"nettoyage ?"
+#: xs/src/libslic3r/PrintConfig.cpp:951
+msgid "Minimal filament extrusion length"
+msgstr "Longueur minimale d'extrusion de filament"
-#: src/slic3r/GUI/Tab.cpp:1227
-msgid ""
-"Supports work better, if the following feature is enabled:\n"
-"- Detect bridging perimeters\n"
-"\n"
-"Shall I adjust those settings for supports?"
-msgstr ""
-"Les supports sont plus efficaces, si la fonctionnalité suivante est "
-"activée :\n"
-"-Détection des périmètres de pont\n"
-"\n"
-"Voulez-vous que que je modifie les réglages des supports ?"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1040
+msgid "Minimum detail resolution, used to simplify the input file for speeding up the slicing job and reducing memory usage. High-resolution models often carry more detail than printers can render. Set to zero to disable any simplification and use full resolution from input."
+msgstr "Résolution minimale pour les détails, utilisée pour simplifier le fichier d'entrée afin d'accélérer le découpage et de réduire l'utilisation de la mémoire. Les modèles haute-résolution possèdent souvent plus de détails que ce que les imprimantes peuvent produire. Mettez à zéro pour désactiver toute simplification et utiliser la résolution complète de l'entrée."
-#: src/slic3r/GUI/Tab.cpp:1230
-msgid "Support Generator"
-msgstr "Générateur de Support"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1050
+msgid "Minimum travel after retraction"
+msgstr "Trajet minimal après une rétraction"
-# Used in context: _("The ") + str_fill_pattern + _(" infill pattern is not supposed to work at 100% density.\n")
-#: src/slic3r/GUI/Tab.cpp:1272
-msgid "The "
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2055
+msgid "Mirror"
+msgstr "Symétrie"
-#: src/slic3r/GUI/Tab.cpp:1272
-#, no-c-format
-msgid ""
-" infill pattern is not supposed to work at 100% density.\n"
-"\n"
-"Shall I switch to rectilinear fill pattern?"
-msgstr ""
-" le motif de remplissage n'est pas supposé fonctionner à une densité de "
-"100%.\n"
-"\n"
-"Dois-je passer au motif de remplissage rectiligne ?"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2055
+msgid "Mirror the selected object"
+msgstr "Symétriser l'objet sélectionné"
-#: src/slic3r/GUI/Tab.cpp:1388
-msgid "Temperature "
-msgstr "Température "
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2057
+msgid "Mirror the selected object along the X axis"
+msgstr "Symétriser l'objet sélectionné selon l'axe X"
-#: src/slic3r/GUI/Tab.cpp:1394
-msgid "Bed"
-msgstr "Plateau"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2060
+msgid "Mirror the selected object along the Y axis"
+msgstr "Symétriser l'objet sélectionné selon l'axe Y"
-#: src/slic3r/GUI/Tab.cpp:1399
-msgid "Cooling"
-msgstr "Refroidissement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2063
+msgid "Mirror the selected object along the Z axis"
+msgstr "Symétriser l'objet sélectionné selon l'axe Z"
-#: src/slic3r/GUI/Tab.cpp:1400 src/libslic3r/PrintConfig.cpp:1333
-#: src/libslic3r/PrintConfig.cpp:2212
-msgid "Enable"
-msgstr "Activer"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:65
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:129
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:200
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:211
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:325
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:336
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:355
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:434
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:781
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:801
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:860
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:878
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:896
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1044
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1052
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1094
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1103
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1113
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1121
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1129
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1215
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1421
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1491
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1527
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1704
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1711
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1718
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1727
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1737
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1747
+msgid "mm"
+msgstr "mm"
-#: src/slic3r/GUI/Tab.cpp:1411
-msgid "Fan settings"
-msgstr "Réglages du ventilateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1075
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1085
+msgid "mm (zero to disable)"
+msgstr "mm (zéro pour désactiver)"
-#: src/slic3r/GUI/Tab.cpp:1412
-msgid "Fan speed"
-msgstr "Vitesse du ventilateur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:609
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:740
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1390
+msgid "mm or %"
+msgstr "mm ou %"
-#: src/slic3r/GUI/Tab.cpp:1420
-msgid "Cooling thresholds"
-msgstr "Seuils de refroidissement"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:382
+msgid "mm or % (leave 0 for auto)"
+msgstr "mm ou % (laissez à 0 pour le mode automatique)"
-#: src/slic3r/GUI/Tab.cpp:1426
-msgid "Filament properties"
-msgstr "Propriétés du filament"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:272
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:597
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:715
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:972
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1296
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1458
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1619
+msgid "mm or % (leave 0 for default)"
+msgstr "mm ou % (laissez à 0 pour la valeur par défaut)"
-#: src/slic3r/GUI/Tab.cpp:1430
-msgid "Print speed override"
-msgstr "Contournement de la vitesse d'impression"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:120
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:638
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:749
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:811
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:868
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:981
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1137
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1146
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1536
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1649
+msgid "mm/s"
+msgstr "mm/s"
-#: src/slic3r/GUI/Tab.cpp:1440
-msgid "Toolchange parameters with single extruder MM printers"
-msgstr ""
-"Paramètres de changement d'outil pour les imprimantes multi-matériaux mono-"
-"extrudeur"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:282
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:619
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1255
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1306
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1501
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1631
+msgid "mm/s or %"
+msgstr "mm/s ou %"
-#: src/slic3r/GUI/Tab.cpp:1455
-msgid "Ramming settings"
-msgstr "Réglages de l'expulsion"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:80
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:174
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:576
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:684
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:952
+msgid "mm/s²"
+msgstr "mm/s²"
-#: src/slic3r/GUI/Tab.cpp:1470 src/slic3r/GUI/Tab.cpp:1846
-msgid "Custom G-code"
-msgstr "G-code personnalisé"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1265
+msgid "mm²"
+msgstr "mm²"
-#: src/slic3r/GUI/Tab.cpp:1471 src/slic3r/GUI/Tab.cpp:1847
-#: src/libslic3r/PrintConfig.cpp:1817 src/libslic3r/PrintConfig.cpp:1833
-msgid "Start G-code"
-msgstr "G-code de début"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:425
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:820
+msgid "mm³/s"
+msgstr "mm³/s"
-#: src/slic3r/GUI/Tab.cpp:1477 src/slic3r/GUI/Tab.cpp:1853
-#: src/libslic3r/PrintConfig.cpp:333 src/libslic3r/PrintConfig.cpp:344
-msgid "End G-code"
-msgstr "G-code de fin"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:831
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:842
+msgid "mm³/s²"
+msgstr "mm³/s²"
-#: src/slic3r/GUI/Tab.cpp:1588 src/slic3r/GUI/Tab.cpp:1642
-msgid " Browse "
-msgstr " Parcourir "
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:55
+msgid "model"
+msgstr "modèle"
-#: src/slic3r/GUI/Tab.cpp:1605 src/slic3r/GUI/Tab.cpp:1788
-msgid "Test"
-msgstr "Test"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:414
+msgid "Modifiers"
+msgstr "Modificateurs"
-#: src/slic3r/GUI/Tab.cpp:1615
-msgid "Could not get a valid Printer Host reference"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:478
+msgid "money/kg"
+msgstr "€/kg"
-#: src/slic3r/GUI/Tab.cpp:1621 src/slic3r/GUI/Tab.cpp:1801
-msgid "Success!"
-msgstr "Réussi !"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:182
+msgid "More"
+msgstr "Plus"
-#: src/slic3r/GUI/Tab.cpp:1636
-msgid ""
-"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-"
-"signed certificate."
-msgstr ""
-"Le fichier HTTPS CA est optionnel. Il est uniquement requis si vous utilisez "
-"le HTTPS avec un certificat auto-signé."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1696
+msgid "Multi material printers may need to prime or purge extruders on tool changes. Extrude the excess material into the wipe tower."
+msgstr "Les imprimantes multi-matériaux peuvent avoir besoin de préparer ou de purger leurs extrudeurs lors d'un changement d'outil. Extruder le matériau en excès dans la tour de nettoyage."
-#: src/slic3r/GUI/Tab.cpp:1648
-msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"
-msgstr ""
-"Fichiers de certificat (*.crt, *.pem)|*.crt;*.pem|Tous les fichiers|*.*"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:666
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:683
+msgid "Multi-part object detected"
+msgstr "Objet multi-pièces détecté"
-#: src/slic3r/GUI/Tab.cpp:1649
-msgid "Open CA certificate file"
-msgstr "Ouvrir le fichier de certificat CA"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:430
+msgid "Multiple Extruders"
+msgstr "Extrudeurs Multiples"
-#: src/slic3r/GUI/Tab.cpp:1676
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:680
msgid ""
-"HTTPS CA File:\n"
-"\tOn this system, Slic3r uses HTTPS certificates from the system Certificate "
-"Store or Keychain.\n"
-"\tTo use a custom CA file, please import your CA file into Certificate "
-"Store / Keychain."
+"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 ""
+"Plusieurs objets ont été chargés pour une imprimante multi-matériaux.\n"
+"Au lieu de les considérer comme plusieurs objets, dois-je considérer\n"
+"ces fichiers comment représentant un objets ayant plusieurs pièces ?\n"
-#: src/slic3r/GUI/Tab.cpp:1713 src/slic3r/GUI/Tab.cpp:1912
-msgid "Size and coordinates"
-msgstr "Taille et coordonnées"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:220
+msgid "Name"
+msgstr "Nom"
-#: src/slic3r/GUI/Tab.cpp:1717 src/slic3r/GUI/Tab.cpp:1916
-#: src/slic3r/GUI/Tab.cpp:2792
-msgid " Set "
-msgstr " Appliquer "
+#: 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 "Nom de la variante d'imprimante. Par exemple, la variante d'imprimante peut être différenciée par un diamètre de buse."
-#: src/slic3r/GUI/Tab.cpp:1740
-msgid "Capabilities"
-msgstr "Fonctionnalités"
+#: xs/src/libslic3r/PrintConfig.cpp:1121
+msgid "Name of the printer vendor."
+msgstr "Nom du fabriquant de l'imprimante."
-#: src/slic3r/GUI/Tab.cpp:1745
-msgid "Number of extruders of the printer."
-msgstr "Nombre d'extrudeurs de l'imprimante."
+#: xs/src/libslic3r/PrintConfig.cpp:820
+msgid "Name of the profile, from which this profile inherits."
+msgstr "Nom du profil, duquel hérite ce profil."
-#: src/slic3r/GUI/Tab.cpp:1773
-msgid "USB/Serial connection"
-msgstr "Port USB/Série"
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:53
+msgid "Network lookup"
+msgstr "Recherche réseau"
-#: src/slic3r/GUI/Tab.cpp:1774 src/libslic3r/PrintConfig.cpp:1660
-msgid "Serial port"
-msgstr "Port série"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:27
+msgid "New version of Slic3r PE is available"
+msgstr "Une nouvelle version de Slic3r PE est disponible"
-#: src/slic3r/GUI/Tab.cpp:1779
-msgid "Rescan serial ports"
-msgstr "Rescanner les ports série"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:43
+msgid "New version:"
+msgstr "Nouvelle version :"
-#: src/slic3r/GUI/Tab.cpp:1801
-msgid "Connection to printer works correctly."
-msgstr "La connexion avec l'imprimante fonctionne correctement."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:469
+msgid "No previously sliced file."
+msgstr "Aucun fichier précédemment découpé."
-#: src/slic3r/GUI/Tab.cpp:1804
-msgid "Connection failed."
-msgstr "La connexion a échoué."
+#: xs/src/slic3r/GUI/RammingChart.cpp:28
+msgid "NO RAMMING AT ALL"
+msgstr "PAS D'EXPULSION DU TOUT"
-#: src/slic3r/GUI/Tab.cpp:1817 src/slic3r/GUI/Tab.cpp:1961
-msgid "Print Host upload"
-msgstr ""
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:137
+msgid "None"
+msgstr "Aucun"
-#: src/slic3r/GUI/Tab.cpp:1859 src/libslic3r/PrintConfig.cpp:92
-msgid "Before layer change G-code"
-msgstr "G-Code avant changement de couche"
+#: xs/src/slic3r/GUI/Tab.cpp:1571
+msgid "Note: OctoPrint version at least 1.1.0 is required."
+msgstr "Note : une version d'Octoprint supérieure ou égale à 1.1.0 est requise."
+
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:500
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:501
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:859
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:860
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1156
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1157
+msgid "Notes"
+msgstr "Notes"
-#: src/slic3r/GUI/Tab.cpp:1865 src/libslic3r/PrintConfig.cpp:1042
-msgid "After layer change G-code"
-msgstr "G-Code après changement de couche"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:493
+msgid "Notice"
+msgstr "Remarque"
-#: src/slic3r/GUI/Tab.cpp:1871 src/libslic3r/PrintConfig.cpp:2111
-msgid "Tool change G-code"
-msgstr "G-code de changement d'outil"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:85
+msgid "nozzle"
+msgstr "buse"
-#: src/slic3r/GUI/Tab.cpp:1877
-msgid "Between objects G-code (for sequential printing)"
-msgstr "Entre le G-code des objets (pour une impression séquentielle)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:894
+msgid "Nozzle diameter"
+msgstr "Diamètre de la buse"
-#: src/slic3r/GUI/Tab.cpp:1938
-msgid "Display"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:431
+msgid "Nozzle Diameter:"
+msgstr "Diamètre de la Buse :"
-#: src/slic3r/GUI/Tab.cpp:1949 src/slic3r/GUI/Tab.cpp:3102
-msgid "Corrections"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:967
+msgid "Number of extruders of the printer."
+msgstr "Nombre d'extrudeurs de l'imprimante."
-#: src/slic3r/GUI/Tab.cpp:2011 src/slic3r/GUI/Tab.cpp:2073
-#: src/libslic3r/PrintConfig.cpp:1088 src/libslic3r/PrintConfig.cpp:1098
-#: src/libslic3r/PrintConfig.cpp:1108 src/libslic3r/PrintConfig.cpp:1121
-#: src/libslic3r/PrintConfig.cpp:1132 src/libslic3r/PrintConfig.cpp:1143
-#: src/libslic3r/PrintConfig.cpp:1154
-msgid "Machine limits"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1481
+msgid "Number of interface layers to insert between the object(s) and support material."
+msgstr "Nombre de couches d'interface à insérer entre le(s) objet(s) et les supports."
-#: src/slic3r/GUI/Tab.cpp:2025
-msgid "Values in this column are for Full Power mode"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1231
+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 "Nombre de boucles pour la clôture. Si la Longueur Minimale d'Extrusion est paramétrée, le nombre de boucles minimale sera plus grand que celui configuré ici. Mettez à zéro pour désactiver complètement la clôture."
-#: src/slic3r/GUI/Tab.cpp:2026
-msgid "Full Power"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:70
+msgid "Number of solid layers to generate on bottom surfaces."
+msgstr "Nombre de couches pleines à générer sur les surfaces inférieures."
-#: src/slic3r/GUI/Tab.cpp:2031
-msgid "Values in this column are for Silent mode"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1315
+msgid "Number of solid layers to generate on top and bottom surfaces."
+msgstr "Nombre de couches pleines à générer sur les surfaces supérieures et inférieures."
-#: src/slic3r/GUI/Tab.cpp:2032
-msgid "Silent"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1640
+msgid "Number of solid layers to generate on top surfaces."
+msgstr "Nombre de couches pleines à générer sur les surfaces supérieures."
-#: src/slic3r/GUI/Tab.cpp:2040
-msgid "Maximum feedrates"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:745
+msgid "Object too large?"
+msgstr "Objet trop grand ?"
-#: src/slic3r/GUI/Tab.cpp:2045
-msgid "Maximum accelerations"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1032
+msgid "OctoPrint upload"
+msgstr "Envoi vers OctoPrint"
-#: src/slic3r/GUI/Tab.cpp:2052
-msgid "Jerk limits"
-msgstr ""
+#: lib/Slic3r/GUI/Plater.pm:1511
+msgid "OctoPrint upload finished."
+msgstr "Envoi vers OctoPrint terminé."
-#: src/slic3r/GUI/Tab.cpp:2057
-msgid "Minimum feedrates"
-msgstr ""
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:69
+msgid "OctoPrint version"
+msgstr "Version d'OctoPrint"
-#: src/slic3r/GUI/Tab.cpp:2095 src/slic3r/GUI/Tab.cpp:2103
-msgid "Single extruder MM setup"
-msgstr "Réglage MM pour extrudeur unique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1410
+msgid "Only create support if it lies on a build plate. Don't create support on a print."
+msgstr "Créer uniquement des supports reposant sur le plateau. Ne pas créer pas de supports sur une impression."
-#: src/slic3r/GUI/Tab.cpp:2104
-msgid "Single extruder multimaterial parameters"
-msgstr "Paramètres multimatériaux pour extrudeur unique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:726
+msgid "Only infill where needed"
+msgstr "Remplissage seulement où cela est nécessaire"
-#: src/slic3r/GUI/Tab.cpp:2118 src/libslic3r/GCode/PreviewData.cpp:475
-#, c-format
-msgid "Extruder %d"
-msgstr "Extrudeur %d"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1205
+msgid "Only lift Z"
+msgstr "Lever Z seulement"
-#: src/slic3r/GUI/Tab.cpp:2125
-msgid "Layer height limits"
-msgstr "Limites de hauteur de couche"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1100
+msgid "Only lift Z above"
+msgstr "Lever Z seulement au-dessus de"
-#: src/slic3r/GUI/Tab.cpp:2130
-msgid "Position (for multi-extruder printers)"
-msgstr "Position (pour les imprimantes multi-extrudeurs)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1109
+msgid "Only lift Z below"
+msgstr "Lever Z seulement en-dessous de"
-#: src/slic3r/GUI/Tab.cpp:2133
-msgid "Retraction"
-msgstr "Rétraction"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:915
+msgid "Only retract when crossing perimeters"
+msgstr "Rétracter uniquement lors du franchissement de périmètres"
-#: src/slic3r/GUI/Tab.cpp:2136
-msgid "Only lift Z"
-msgstr "Lever Z seulement"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:438
+msgid "Ooze prevention"
+msgstr "Prévention des coulures"
-#: src/slic3r/GUI/Tab.cpp:2149
-msgid ""
-"Retraction when tool is disabled (advanced settings for multi-extruder "
-"setups)"
-msgstr ""
-"Rétractation lorsque l'outil est désactivé (réglages avancés pour les "
-"configurations multi-extrudeurs)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:251
+msgid "Open a model"
+msgstr "Ouvrir un modèle"
-#: src/slic3r/GUI/Tab.cpp:2153
-msgid "Preview"
-msgstr "Aperçu"
+#: xs/src/slic3r/GUI/Tab.cpp:1598
+msgid "Open CA certificate file"
+msgstr "Ouvrir le fichier de certificat CA"
-#: src/slic3r/GUI/Tab.cpp:2284
-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 ""
-"L'option Nettoyage n'est pas disponible lorsque vous utilisez le mode "
-"Rétractation du Firmware.\n"
-"\n"
-"Voulez-vous que je la désactive pour permettre la Rétractation du Firmware ?"
+#: lib/Slic3r/GUI/MainFrame.pm:194
+msgid "Open STL/OBJ/AMF/3MF…\tCtrl+O"
+msgstr "Ouvrir STL/OBJ/AMF/3MF…\tCtrl+O"
-#: src/slic3r/GUI/Tab.cpp:2286
-msgid "Firmware Retraction"
-msgstr "Rétraction du Firmware"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2102
+msgid "Open the 3D cutting tool"
+msgstr "Ouvrir l'outil de coupe 3D"
-#: src/slic3r/GUI/Tab.cpp:2565
-#, c-format
-msgid "Default preset (%s)"
-msgstr "Préréglages par défaut (%s)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2106
+msgid "Open the object editor dialog"
+msgstr "Ouvrir la boîte de dialogue d'édition d'objet"
-#: src/slic3r/GUI/Tab.cpp:2566
-#, c-format
-msgid "Preset (%s)"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:388
+msgid "Open the Slic3r++ releases page in your browser"
+msgstr "Ouvrir la page des publications de la Slic3r++ dans votre navigateur"
-#: src/slic3r/GUI/Tab.cpp:2583
-msgid "has the following unsaved changes:"
-msgstr "a les changements suivants non-enregistrés :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:385
+msgid "Open the Prusa3D drivers download page in your browser"
+msgstr "Ouvrir la page de téléchargement des drivers Prusa3D dans votre navigateur"
-#: src/slic3r/GUI/Tab.cpp:2586
-msgid "is not compatible with printer"
-msgstr "n'est pas compatible avec l'imprimante"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:398
+msgid "Open the Slic3r manual in your browser"
+msgstr "Ouvrir la manuel de Slic3r dans votre navigateur"
-#: src/slic3r/GUI/Tab.cpp:2587
-msgid "is not compatible with print profile"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:395
+msgid "Open the Slic3r website in your browser"
+msgstr "Ouvrir le site web de Slic3r dans votre navigateur"
-#: src/slic3r/GUI/Tab.cpp:2589
-msgid "and it has the following unsaved changes:"
-msgstr "et il y a les changements non sauvegardés suivants :"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:27
+msgid "Optimize travel moves in order to minimize the crossing of perimeters. This is mostly useful with Bowden extruders which suffer from oozing. This feature slows down both the print and the G-code generation."
+msgstr "Optimiser les déplacements afin de minimiser le franchissement de périmètres. Ceci est surtout utile avec les extruder Bowden qui sont sujets aux coulures. Cette fonctionnalité ralentit l'impression et la génération du G-code."
-#: src/slic3r/GUI/Tab.cpp:2592
-msgid "Discard changes and continue anyway?"
-msgstr "Annuler les changements et continuer malgré tout ?"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:384
+msgid "Options for support material and raft"
+msgstr "Options pour le matériau de support et le radeau"
-#: src/slic3r/GUI/Tab.cpp:2593
-msgid "Unsaved Changes"
-msgstr "Changements Non Sauvegardés"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:57
+msgid "Origin"
+msgstr "Origine"
-#: src/slic3r/GUI/Tab.cpp:2604
-msgid "It's impossible to print multi-part object(s) with SLA technology."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:469
+msgid "Other"
+msgstr "Autre"
-#: src/slic3r/GUI/Tab.cpp:2605
-msgid "Please check your object list before preset changing."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:38
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1572
+msgid "Other layers"
+msgstr "Autres couches"
-#: src/slic3r/GUI/Tab.cpp:2699
-msgid "The supplied name is empty. It can't be saved."
-msgstr "Le nom proposé est vide. Sauvegarde impossible."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:295
+msgid "Other Vendors"
+msgstr "Autres Fabriquants"
-#: src/slic3r/GUI/Tab.cpp:2704
-msgid "Cannot overwrite a system profile."
-msgstr "Impossible d'écraser un profil système."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:238
+msgid "Other vendors"
+msgstr "Autres fabriquants"
-#: src/slic3r/GUI/Tab.cpp:2708
-msgid "Cannot overwrite an external profile."
-msgstr "Impossible d'écraser un profil externe."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:488
+msgid "Output file"
+msgstr "Fichier de sortie"
-#: src/slic3r/GUI/Tab.cpp:2734
-msgid "remove"
-msgstr "retirer"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:930
+msgid "Output filename format"
+msgstr "Format du nom de fichier de sortie"
-#: src/slic3r/GUI/Tab.cpp:2734
-msgid "delete"
-msgstr "supprimer"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:476
+msgid "Output options"
+msgstr "Options de sortie"
-#: src/slic3r/GUI/Tab.cpp:2735
-msgid "Are you sure you want to "
-msgstr "Êtes-vous sûr de vouloir "
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:140
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:82
+msgid "Overhang perimeter"
+msgstr "Périmètre en surplomb"
-#: src/slic3r/GUI/Tab.cpp:2735
-msgid " the selected preset?"
-msgstr " le préréglage sélectionné ?"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1550
+msgid "Overhang threshold"
+msgstr "Seuil de surplomb"
-#: src/slic3r/GUI/Tab.cpp:2736
-msgid "Remove"
-msgstr "Retirer"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:463
+msgid "Overlap"
+msgstr "Chevauchement"
-#: src/slic3r/GUI/Tab.cpp:2737
-msgid " Preset"
-msgstr " Préréglage"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1508
+msgid "Pattern"
+msgstr "Motif"
-#: src/slic3r/GUI/Tab.cpp:2791
-msgid "All"
-msgstr "Tous"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1398
+msgid "Pattern angle"
+msgstr "Angle du motif"
-#: src/slic3r/GUI/Tab.cpp:2869
-msgid ""
-"LOCKED LOCK;indicates that the settings are the same as the system values "
-"for the current option group"
-msgstr ""
-"VERROU VERROUILLE;indique que les paramètres sont les mêmes que les valeurs "
-"système pour le groupe d'options en cours"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1524
+msgid "Pattern spacing"
+msgstr "Espacement du motif"
-#: src/slic3r/GUI/Tab.cpp:2872
-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 ""
-"CADENAS OUVERT;indique que certains paramètres ont été modifiés et ne sont "
-"pas égaux aux valeurs du système pour le groupe d'options actuel.\n"
-"Cliquez sur l'icône CADENAS OUVERT pour régler tous les paramètres pour le "
-"groupe d'options actuel sur les valeurs du système."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1510
+msgid "Pattern used to generate support material."
+msgstr "Motif utilisé pour générer les supports."
-#: src/slic3r/GUI/Tab.cpp:2878
-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 ""
-"PUCE BLANCHE;pour le bouton gauche : indique un préréglage non-système, pour "
-"le bouton droit : indique que le réglage n'a pas été modifié."
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:138
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:80
+msgid "Perimeter"
+msgstr "Périmètre"
-#: src/slic3r/GUI/Tab.cpp:2882
-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 ""
-"FLÈCHE ARRIÈRE;indique que les paramètres ont été changés et qu'ils ne sont "
-"pas identiques au dernier préréglage enregistré du groupe d'options en "
-"cours.\n"
-"Cliquez sur l'icône FLÈCHE ARRIÈRE pour restaurer tous les paramètres du "
-"groupe d'options en cours avec les valeurs du dernier préréglage enregistré."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:957
+msgid "Perimeter extruder"
+msgstr "Extrudeur pour les périmètres"
-#: src/slic3r/GUI/Tab.cpp:2908
-msgid ""
-"LOCKED LOCK icon indicates that the settings are the same as the system "
-"values for the current option group"
-msgstr ""
-"L'icône VERROU VERROUILLE indique que les paramètres sont les mêmes que les "
-"valeurs système pour le groupe d'options en cours"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:948
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:966
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:978
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:988
+msgid "Perimeters"
+msgstr "Périmètres"
-#: src/slic3r/GUI/Tab.cpp:2910
-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 ""
-"L'icône CADENAS OUVERT indique que certains paramètres ont été modifiés et "
-"ne sont pas égaux aux valeurs du système pour le groupe d'options actuel.\n"
-"Cliquez pour régler tous les paramètres pour le groupe d'options actuel sur "
-"les valeurs du système."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:160
+msgid "perimeters"
+msgstr "périmètres"
-#: src/slic3r/GUI/Tab.cpp:2913
-msgid "WHITE BULLET icon indicates a non system preset."
-msgstr "L'icône en forme de PUCE BLANCHE indique un préréglage non-système."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:297
+msgid "Pick another vendor supported by Slic3r PE:"
+msgstr "Choisissez un autre fabriquant supporté par Slic3r PE :"
-#: src/slic3r/GUI/Tab.cpp:2916
-msgid ""
-"WHITE BULLET icon indicates that the settings are the same as in the last "
-"saved preset for the current option group."
-msgstr ""
-"L'icône en forme de PUCE BLANCHE indique que les réglages sont identiques au "
-"dernier préréglage sauvegardé pour le groupe d'options actuel."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2024
+msgid "Place one more copy of the selected object"
+msgstr "Placer une copie supplémentaire de l'objet sélectionné"
-#: src/slic3r/GUI/Tab.cpp:2918
-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 ""
-"L'icône FLÈCHE ARRIÈRE indique que les paramètres ont été changés et qu'ils "
-"ne sont pas identiques au dernier préréglage enregistré du groupe d'options "
-"en cours.\n"
-"Cliquez pour restaurer tous les paramètres du groupe d'options en cours avec "
-"les valeurs du dernier préréglage enregistré."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:118
+msgid "Plater"
+msgstr "Plateau"
-#: src/slic3r/GUI/Tab.cpp:2924
-msgid ""
-"LOCKED LOCK icon indicates that the value is the same as the system value."
-msgstr ""
-"L'icône VERROU VERROUILLE indique que la valeur est la même que la valeur "
-"système."
+#: lib/Slic3r/GUI/Plater.pm:1897
+msgid "Please install the OpenGL modules to use this feature (see build instructions)."
+msgstr "Veuillez installer les modules OpenGL pour pouvoir utiliser cette fonctionnalité (voir les instructions de montage)."
-#: src/slic3r/GUI/Tab.cpp:2925
-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 ""
-"L'icône CADENAS OUVERT indique que la valeur a été changée et n'est pas "
-"égale à la valeur du système.\n"
-"Cliquez pour régler la valeur actuelle sur les valeurs du système."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1199
+msgid "Position (for multi-extruder printers)"
+msgstr "Position (pour les imprimantes multi-extrudeurs)"
-#: src/slic3r/GUI/Tab.cpp:2931
-msgid ""
-"WHITE BULLET icon indicates that the value is the same as in the last saved "
-"preset."
-msgstr ""
-"L'icône PUCE BLANCHE indique que la valeur est la même que pour le dernier "
-"préréglage sauvegardé."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1153
+msgid "Position of perimeters starting points."
+msgstr "Position des points de départ des périmètres."
-#: src/slic3r/GUI/Tab.cpp:2932
-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 ""
-"L'icône FLÈCHE ARRIÈRE indique que la valeur a été changée et qu'elle n'est "
-"pas identique au dernier préréglage enregistré.\n"
-"Cliquez pour restaurer la valeur à celle du dernier préréglage enregistré."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1702
+msgid "Position X"
+msgstr "Position X"
-# Used in this context: _("Save ") + title + _(" as:")
-#: src/slic3r/GUI/Tab.cpp:3031
-msgid " as:"
-msgstr " sous :"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1709
+msgid "Position Y"
+msgstr "Position Y"
-#: src/slic3r/GUI/Tab.cpp:3075
-msgid "the following postfix are not allowed:"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:494
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1001
+msgid "Post-processing scripts"
+msgstr "Scripts de post-traitement"
-#: src/slic3r/GUI/Tab.cpp:3079
-msgid "The supplied name is not available."
-msgstr "Le nom proposé n'est pas disponible."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.hpp:17
+msgid "Preferences"
+msgstr "Préférences"
-#: src/slic3r/GUI/Tab.cpp:3092
-msgid "Material"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1171
+msgid "Preferred direction of the seam"
+msgstr "Direction préférée de la jointure"
-#: src/slic3r/GUI/Tab.cpp:3094 src/slic3r/GUI/Tab.cpp:3176
-msgid "Layers"
-msgstr "Couches"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1183
+msgid "Preferred direction of the seam - jitter"
+msgstr "Direction préférée de la jointure - gigue"
-#: src/slic3r/GUI/Tab.cpp:3098
-msgid "Exposure"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1222
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:150
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2125
+msgid "Preview"
+msgstr "Aperçu"
-#: src/slic3r/GUI/Tab.cpp:3183
-msgid "Support head"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:474
+msgid "Previously sliced file ("
+msgstr "Fichier précédemment découpé ("
-#: src/slic3r/GUI/Tab.cpp:3188
-msgid "Support pillar"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:43
+msgid "print"
+msgstr "imprimer"
-#: src/slic3r/GUI/Tab.cpp:3196
-msgid "Connection of the support sticks and junctions"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:291
+msgid "Print contour perimeters from the outermost one to the innermost one instead of the default inverse order."
+msgstr "Imprimer les périmètres de l'extérieur vers l'intérieur au lieu de l'ordre par défaut qui est inversé."
-#: src/slic3r/GUI/Tab.cpp:3200
-msgid "Automatic generation"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:412
+msgid "Print Diameters"
+msgstr "Diamètres d'Impression"
-#: src/slic3r/GUI/Tab.hpp:293 src/slic3r/GUI/Tab.hpp:381
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:182
msgid "Print Settings"
msgstr "Réglages d'Impression"
-#: src/slic3r/GUI/Tab.hpp:311
-msgid "Filament Settings"
-msgstr "Réglages du filament"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:367
+msgid "Print settings"
+msgstr "Réglages d'impression"
+
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:836
+msgid "Print speed override"
+msgstr "Contournement de la vitesse d'impression"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:369
+msgid "Printer"
+msgstr "Imprimante"
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:45
+msgid "printer"
+msgstr "imprimer"
+
+#: xs/src/slic3r/GUI/Tab.cpp:762
+msgid "printer model"
+msgstr "modèle de l'imprimante"
+
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1014
+msgid "Printer notes"
+msgstr "Notes de l'imprimante"
-#: src/slic3r/GUI/Tab.hpp:344
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:228
msgid "Printer Settings"
msgstr "Réglages de l'Imprimante"
-#: src/slic3r/GUI/Tab.hpp:367
-msgid "Material Settings"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:1106
+msgid "Printer type"
+msgstr "Type d'imprimante"
-#: src/slic3r/GUI/Tab.hpp:393
-msgid "Save preset"
-msgstr "Enregistrer le préréglage"
+#: xs/src/libslic3r/PrintConfig.cpp:1125
+msgid "Printer variant"
+msgstr "Variante d'imprimante"
-#: src/slic3r/GUI/UpdateDialogs.cpp:28
-msgid "Update available"
-msgstr "Mise à jour disponible"
+#: xs/src/libslic3r/PrintConfig.cpp:1120
+msgid "Printer vendor"
+msgstr "Fabriquant de l'imprimante"
-#: src/slic3r/GUI/UpdateDialogs.cpp:28
-msgid "New version of Slic3r PE is available"
-msgstr "Une nouvelle version de Slic3r PE est disponible"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:238
+msgid "Print…"
+msgstr "Impression…"
-#: src/slic3r/GUI/UpdateDialogs.cpp:35
-msgid "To download, follow the link below."
-msgstr "Pour télécharger, suivez le lien ci-dessous."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:528
+msgid "Processing "
+msgstr "Traitement "
-#: src/slic3r/GUI/UpdateDialogs.cpp:42
-msgid "Current version:"
-msgstr "Version actuelle :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:629
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:643
+msgid "Processing input file\n"
+msgstr "Traitement du fichier d'entrée\n"
-#: src/slic3r/GUI/UpdateDialogs.cpp:44
-msgid "New version:"
-msgstr "Nouvelle version :"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:508
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:868
+msgid "Profile dependencies"
+msgstr "Dépendances du profil"
-#: src/slic3r/GUI/UpdateDialogs.cpp:52
-msgid "Don't notify about new releases any more"
-msgstr "Ne plus me notifier au sujet des nouvelles publications"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:300
+msgid "Progress:"
+msgstr "Progression :"
-#: src/slic3r/GUI/UpdateDialogs.cpp:70 src/slic3r/GUI/UpdateDialogs.cpp:162
-msgid "Configuration update"
-msgstr "Mise à jour de la configuration"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:385
+msgid "Prusa 3D Drivers"
+msgstr "Drivers Prusa 3D"
-#: src/slic3r/GUI/UpdateDialogs.cpp:70
-msgid "Configuration update is available"
-msgstr "Une mise à jour de la configuration est disponible"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:388
+msgid "Slic3r++ Releases"
+msgstr "Publication de la Slic3r++"
-#: src/slic3r/GUI/UpdateDialogs.cpp:73
-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 ""
-"Voulez-vous l'installer ?\n"
-"\n"
-"Notez qu'un snapshot complet de la configuration sera sauvegardé d'abord. "
-"Elle peut être restaurée à tout moment si vous rencontrez un problème avec "
-"la nouvelle version.\n"
-"\n"
-"Ensembles de configuration mis à jour :"
+#: xs/src/slic3r/GUI/GUI.cpp:908
+msgid "Purging volumes"
+msgstr "Volumes de purge"
-#: src/slic3r/GUI/UpdateDialogs.cpp:109
-msgid "Slic3r incompatibility"
-msgstr "Incompatibilité avec Slic3r"
+#: xs/src/libslic3r/PrintConfig.cpp:1807
+msgid "Purging volumes - load/unload volumes"
+msgstr "Volumes de purge - volumes de chargement/déchargement"
-#: src/slic3r/GUI/UpdateDialogs.cpp:109
-msgid "Slic3r configuration is incompatible"
-msgstr "La configuration de Slic3r n'est pas compatible"
+#: xs/src/libslic3r/PrintConfig.cpp:1815
+msgid "Purging volumes - matrix"
+msgstr "Volumes de purge - matrice"
-#: src/slic3r/GUI/UpdateDialogs.cpp:112
-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 ""
-"Cette version de Slic3r PE n'est pas compatible avec les ensembles de "
-"configuration actuellement installés.\n"
-"Cela survient probablement du fait d'avoir lancé une ancienne version de "
-"Slic3r PE après en avoir utilisé une nouvelle.\n"
-"\n"
-"Vous pouvez soit quitter Slic3r et essayer à nouveau avec une version plus "
-"récente, ou vous pouvez relancer la configuration initiale. Procéder ainsi "
-"permettra de créer une sauvegarde de la configuration existante avant "
-"d'installer les fichiers compatibles avec ce Slic3r.\n"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:268
+msgid "Q&uick Slice…\tCtrl+U"
+msgstr "&Découpage Rapide…\tCtrl+U"
-#: src/slic3r/GUI/UpdateDialogs.cpp:121
-#, c-format
-msgid "This Slic3r PE version: %s"
-msgstr "Version de ce Slic3r PE : %s"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:335
+msgid "Quality (slower slicing)"
+msgstr "Qualité (découpage plus lent)"
-#: src/slic3r/GUI/UpdateDialogs.cpp:126
-msgid "Incompatible bundles:"
-msgstr "Lots incompatibles :"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:274
+msgid "Quick Slice and Save &As…\tCtrl+Alt+U"
+msgstr "Découpage Rapide et &Enregistrer Sous…\tCtrl+Alt+U"
-#: src/slic3r/GUI/UpdateDialogs.cpp:142
-msgid "Exit Slic3r"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:304
+msgid "Quit Slic3r"
msgstr "Quitter Slic3r"
-#: src/slic3r/GUI/UpdateDialogs.cpp:145
-msgid "Re-configure"
-msgstr "Reconfigurer"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:331
+msgid "Radius"
+msgstr "Rayon"
-#: src/slic3r/GUI/UpdateDialogs.cpp:166
-#, 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 ""
-"Slic3r PE utilise à présent une structure de configuration mise à jour.\n"
-"\n"
-"Il existe à présent des \"préréglages Système\", qui intègrent les réglages "
-"par défaut pour les différentes imprimantes. Ces préréglages Système ne "
-"peuvent pas être modifiés, mais les utilisateurs peuvent désormais créer "
-"leurs propres préréglages héritant des paramètres de l'un des préréglages "
-"Système.\n"
-"Un tel préréglage peut ainsi hériter d'une valeur particulière de son parent "
-"ou la remplacer par une valeur personnalisée.\n"
-"\n"
-"Veuillez utiliser les %s qui suivent pour paramétrer les nouveaux réglages "
-"et éventuellement accepter les mises à jour de réglage automatiques."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:380
+msgid "Raft"
+msgstr "Radeau"
-#: src/slic3r/GUI/UpdateDialogs.cpp:182
-msgid "For more information please visit our wiki page:"
-msgstr "Pour plus d'informations, merci de visiter notre page wiki :"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1029
+msgid "Raft layers"
+msgstr "Couches du radeau"
+
+#: xs/src/slic3r/GUI/Tab.cpp:1319
+msgid "Ramming"
+msgstr "Expulsion"
-#: src/slic3r/GUI/WipeTowerDialog.cpp:10
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:14
msgid "Ramming customization"
msgstr "Personnalisation de l'expulsion"
-#: src/slic3r/GUI/WipeTowerDialog.cpp:36
+#: 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"
+"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."
+"This is an expert-level setting, incorrect adjustment will likely lead to jams, extruder wheel grinding into filament etc."
msgstr ""
-"L'Expulsion décrit l'extrusion rapide qui a lieu juste avant un changement "
-"d'outil sur une imprimante MM à extrudeur unique. Le but est de donner une "
-"forme correcte au filament déchargé afin qu'il n'empêche pas l'insertion du "
-"nouveau filament et puisse être réinséré lui-même plus tard. Cette phase est "
-"importante et des matériaux différents peuvent nécessiter des vitesses "
-"d'extrusion différentes pour obtenir la bonne forme. De ce fait, les débits "
-"d'extrusion pendant l'expulsion sont ajustables.\n"
+"L'Expulsion décrit l'extrusion rapide qui a lieu juste avant un changement d'outil sur une imprimante MM à extrudeur unique. Le but est de donner une forme correcte au filament déchargé afin qu'il n'empêche pas l'insertion du nouveau filament et puisse être réinséré lui-même plus tard. Cette phase est importante et des matériaux différents peuvent nécessiter des vitesses d'extrusion différentes pour obtenir la bonne forme. De ce fait, les débits d'extrusion pendant l'expulsion sont ajustables.\n"
"\n"
-"Ceci est un paramétrage de niveau expert, et un mauvais ajustement "
-"provoquera probablement des blocages, des accrochages de la roue de "
-"l'extrudeur sur le filament , etc ..."
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:78
-msgid "Total ramming time"
-msgstr "Durée totale de l'expulsion"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:80
-msgid "Total rammed volume"
-msgstr "Volume total expulsé"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:84
-msgid "Ramming line width"
-msgstr "Largeur de la ligne d'expulsion"
+"Ceci est un paramétrage de niveau expert, et un mauvais ajustement provoquera probablement des blocages, des accrochages de la roue de l'extrudeur sur le filament , etc ..."
-#: src/slic3r/GUI/WipeTowerDialog.cpp:86
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:90
msgid "Ramming line spacing"
msgstr "Espacement de la ligne de ramming"
-#: src/slic3r/GUI/WipeTowerDialog.cpp:138
-msgid "Wipe tower - Purging volume adjustment"
-msgstr "Tour de nettoyage - Ajustement du volume de purge"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:219
-msgid ""
-"Here you can adjust required purging volume (mm³) for any given pair of "
-"tools."
-msgstr ""
-"Ici vous pouvez ajuster le volume de purge nécessaire (mm³) pour une paire "
-"d'outils donnée."
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:220
-msgid "Extruder changed to"
-msgstr "Extrudeur changé à"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:228
-msgid "unloaded"
-msgstr "déchargé"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:229
-msgid "loaded"
-msgstr "chargé"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:234
-msgid "Tool #"
-msgstr "Outil #"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:241
-msgid ""
-"Total purging volume is calculated by summing two values below, depending on "
-"which tools are loaded/unloaded."
-msgstr ""
-"Le volume de purge total est calculé en additionnant les deux valeurs ci-"
-"dessous, en fonction des outils qui sont chargés/déchargés."
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:242
-msgid "Volume to purge (mm³) when the filament is being"
-msgstr "Volume à purger (mm³) lorsque le filament est"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:256
-msgid "From"
-msgstr "De"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:321
-msgid ""
-"Switching to simple settings will discard changes done in the advanced "
-"mode!\n"
-"\n"
-"Do you want to proceed?"
-msgstr ""
-"Basculer vers les réglages simples annulera les changements effectués en "
-"mode avancé !\n"
-"\n"
-"Voulez-vous continuer ?"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:333
-msgid "Show simplified settings"
-msgstr "Afficher les réglages simplifiés"
-
-#: src/slic3r/GUI/WipeTowerDialog.cpp:333
-msgid "Show advanced settings"
-msgstr "Afficher les réglages avancés"
-
-#: src/slic3r/Utils/OctoPrint.cpp:65
-#, c-format
-msgid "Mismatched type of print host: %s"
-msgstr ""
-
-#: src/slic3r/Utils/OctoPrint.cpp:80
-msgid "Connection to OctoPrint works correctly."
-msgstr "La connexion avec OctoPrint fonctionne correctement."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:88
+msgid "Ramming line width"
+msgstr "Largeur de la ligne d'expulsion"
-#: src/slic3r/Utils/OctoPrint.cpp:86
-msgid "Could not connect to OctoPrint"
-msgstr "Impossible de se connecter à OctoPrint"
+#: xs/src/libslic3r/PrintConfig.cpp:486
+msgid "Ramming parameters"
+msgstr "Paramètres de l'expulsion"
-#: src/slic3r/Utils/OctoPrint.cpp:86
-msgid "Note: OctoPrint version at least 1.1.0 is required."
-msgstr ""
-"Note : une version d'Octoprint supérieure ou égale à 1.1.0 est requise."
+#: xs/src/slic3r/GUI/Tab.cpp:1321
+msgid "Ramming settings"
+msgstr "Réglages de l'expulsion"
-#: src/slic3r/Utils/OctoPrint.cpp:181
-msgid "Connection to Prusa SLA works correctly."
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:144
+msgid "Re-configure"
+msgstr "Reconfigurer"
-#: src/slic3r/Utils/OctoPrint.cpp:186
-msgid "Could not connect to Prusa SLA"
-msgstr ""
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:297
+msgid "Ready"
+msgstr "Prêt"
-#: src/slic3r/Utils/PresetUpdater.cpp:571
-#, c-format
-msgid "requires min. %s and max. %s"
-msgstr "nécessite min. %s et max. %s"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:372
+msgid "Rear"
+msgstr "Arrière"
-#: src/slic3r/Utils/PresetUpdater.cpp:576
-#, c-format
-msgid "requires min. %s"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:372
+msgid "Rear View"
+msgstr "Vue Arrière"
-#: src/slic3r/Utils/PresetUpdater.cpp:578
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:262
#, c-format
-msgid "requires max. %s"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:219
-#: src/slic3r/Utils/FixModelByWin10.cpp:349
-msgid "Exporting the source model"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:235
-msgid "Failed loading the input model."
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:242
-msgid "Repairing the model by the Netfabb service"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:248
-msgid "Mesh repair failed."
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:251
-#: src/slic3r/Utils/FixModelByWin10.cpp:367
-msgid "Loading the repaired model"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:263
-#: src/slic3r/Utils/FixModelByWin10.cpp:270
-#: src/slic3r/Utils/FixModelByWin10.cpp:302
-msgid "Saving mesh into the 3MF container failed."
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:334
-msgid "Model fixing"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:335
-msgid "Exporting model..."
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:357
-msgid "Export of a temporary 3mf file failed"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:372
-msgid "Import of the repaired 3mf file failed"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:375
-msgid "Model repair finished"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:379
-msgid "Model repair canceled"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:396
-msgid "Model repaired successfully"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:396
-#: src/slic3r/Utils/FixModelByWin10.cpp:399
-msgid "Model Repair by the Netfabb service"
-msgstr ""
-
-#: src/slic3r/Utils/FixModelByWin10.cpp:399
-msgid "Model repair failed: \n"
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1175
-msgid "All objects are outside of the print volume."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1201
-msgid "Some objects are too close; your extruder will collide with them."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1216
-msgid ""
-"Some objects are too tall and cannot be printed without extruder collisions."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1226
-msgid "The Spiral Vase option can only be used when printing a single object."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1228
-msgid ""
-"The Spiral Vase option can only be used when printing single material "
-"objects."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1234
-msgid ""
-"All extruders must have the same diameter for single extruder multimaterial "
-"printer."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1239
-msgid ""
-"The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter "
-"and Repetier G-code flavors."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1241
-msgid ""
-"The Wipe Tower is currently only supported with the relative extruder "
-"addressing (use_relative_e_distances=1)."
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1253
-msgid ""
-"The Wipe Tower is only supported for multiple objects if they have equal "
-"layer heigths"
-msgstr ""
-
-#: src/libslic3r/Print.cpp:1255
-msgid ""
-"The Wipe Tower is only supported for multiple objects if they are printed "
-"over an equal number of raft layers"
-msgstr ""
+msgid "Recommended object thin wall thickness for layer height %.2f and "
+msgstr "Épaisseur des parois fines de l'objet recommandée pour la hauteur de couche %.2f et "
-#: src/libslic3r/Print.cpp:1257
-msgid ""
-"The Wipe Tower is only supported for multiple objects if they are printed "
-"with the same support_material_contact_distance"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:245
+msgid "Recommended object thin wall thickness: Not available due to invalid layer height."
+msgstr "Épaisseur des parois fines de l'objet recommandée : Non disponible car la hauteur de couche est invalide."
-#: src/libslic3r/Print.cpp:1259
-msgid ""
-"The Wipe Tower is only supported for multiple objects if they are sliced "
-"equally."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:46
+msgid "Rectangular"
+msgstr "Rectangle"
-#: src/libslic3r/Print.cpp:1281
-msgid ""
-"The Wipe tower is only supported if all objects have the same layer height "
-"profile"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:352
+msgid "Reducing printing time"
+msgstr "Réduction du temps d'impression"
-#: src/libslic3r/Print.cpp:1290
-msgid "The supplied settings will cause an empty print."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2110
+msgid "Reload from Disk"
+msgstr "Recharger depuis le Disque"
-#: src/libslic3r/Print.cpp:1307
-msgid ""
-"One or more object were assigned an extruder that the printer does not have."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2110
+msgid "Reload the selected file from Disk"
+msgstr "Recharger le fichier sélectionné depuis le Disque"
-#: src/libslic3r/Print.cpp:1316
-msgid ""
-"Printing with multiple extruders of differing nozzle diameters. If support "
-"is to be printed with the current extruder (support_material_extruder == 0 "
-"or support_material_interface_extruder == 0), all nozzles have to be of the "
-"same diameter."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:27
+msgid "Remember output directory"
+msgstr "Se souvenir du répertoire de sortie"
-#: src/libslic3r/Print.cpp:1324
-msgid ""
-"For the Wipe Tower to work with the soluble supports, the support layers "
-"need to be synchronized with the object layers."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1582
+msgid "Remove"
+msgstr "Retirer"
-#: src/libslic3r/Print.cpp:1328
-msgid ""
-"The Wipe Tower currently supports the non-soluble supports only if they are "
-"printed with the current extruder without triggering a tool change. (both "
-"support_material_extruder and support_material_interface_extruder need to be "
-"set to 0)."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1580
+msgid "remove"
+msgstr "retirer"
-#: src/libslic3r/Print.cpp:1335
-msgid "first_layer_height"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2027
+msgid "Remove one copy of the selected object"
+msgstr "Retirer une copie de l'objet sélectionné"
-#: src/libslic3r/Print.cpp:1350
-msgid "First layer height can't be greater than nozzle diameter"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2021
+msgid "Remove the selected object"
+msgstr "Retirer l'objet sélectionné"
-#: src/libslic3r/Print.cpp:1354
-msgid "Layer height can't be greater than nozzle diameter"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:217
+msgid "Remove user profiles - install from scratch (a snapshot will be taken beforehand)"
+msgstr "Supprimer les profils d'utilisateur - installation à partir de zéro (un snapshot sera fait avant)"
-#: src/libslic3r/PrintConfig.cpp:32 src/libslic3r/PrintConfig.cpp:33
-msgid "Printer technology"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:594
+msgid "Repair"
+msgstr "Réparer"
-#: src/libslic3r/PrintConfig.cpp:41
-msgid "Bed shape"
-msgstr "Forme du plateau"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:294
+msgid "Repair STL file…"
+msgstr "Réparer le fichier STL…"
-#: src/libslic3r/PrintConfig.cpp:48
-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 ""
-"Cette option contrôle l'épaisseur (et donc le nombre total) des couches. Des "
-"couches plus fines donneront une meilleure précision mais l'impression sera "
-"plus longue."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:280
+msgid "Repeat last quick slice"
+msgstr "Répéter le dernier découpage rapide"
-#: src/libslic3r/PrintConfig.cpp:56
-msgid "Max print height"
-msgstr "Hauteur maximale d'impression"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:405
+msgid "Report an Issue"
+msgstr "Signaler un problème"
-#: src/libslic3r/PrintConfig.cpp:57
-msgid ""
-"Set this to the maximum height that can be reached by your extruder while "
-"printing."
-msgstr ""
-"Réglez cette valeur sur la hauteur maximum que peut atteindre votre "
-"extrudeur au cours de l'impression."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:405
+msgid "Report an issue on the Slic3r Slic3r++"
+msgstr "Signaler un problème sur la Slic3r++ de Slic3r"
-#: src/libslic3r/PrintConfig.cpp:73
-msgid "Avoid crossing perimeters"
-msgstr "Éviter de traverser les périmètres"
+#: xs/src/slic3r/Utils/PresetUpdater.cpp:514
+#, c-format
+msgid "requires min. %s and max. %s"
+msgstr "nécessite min. %s et max. %s"
-#: src/libslic3r/PrintConfig.cpp:74
-msgid ""
-"Optimize travel moves in order to minimize the crossing of perimeters. This "
-"is mostly useful with Bowden extruders which suffer from oozing. This "
-"feature slows down both the print and the G-code generation."
-msgstr ""
-"Optimiser les déplacements afin de minimiser le franchissement de "
-"périmètres. Ceci est surtout utile avec les extruder Bowden qui sont sujets "
-"aux coulures. Cette fonctionnalité ralentit l'impression et la génération du "
-"G-code."
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:288
+msgid "Rescan"
+msgstr "Scanner à nouveau"
-#: src/libslic3r/PrintConfig.cpp:82 src/libslic3r/PrintConfig.cpp:2080
-msgid "Other layers"
-msgstr "Autres couches"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:995
+msgid "Rescan serial ports"
+msgstr "Rescanner les ports série"
-#: src/libslic3r/PrintConfig.cpp:83
-msgid ""
-"Bed temperature for layers after the first one. Set this to zero to disable "
-"bed temperature control commands in the output."
-msgstr ""
-"Température du plateau pour les couches après la première. Mettez ceci à "
-"zéro pour désactiver les commandes de contrôle de température du plateau "
-"dans la sortie."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1039
+msgid "Resolution"
+msgstr "Résolution"
-#: src/libslic3r/PrintConfig.cpp:86
-msgid "Bed temperature"
-msgstr "Température du plateau"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1057
+msgid "Retract amount before wipe"
+msgstr "Quantité de rétractation avant essuyage"
-#: src/libslic3r/PrintConfig.cpp:93
-msgid ""
-"This custom code is inserted at every layer change, right before the Z move. "
-"Note that you can use placeholder variables for all Slic3r settings as well "
-"as [layer_num] and [layer_z]."
-msgstr ""
-"Ce code personnalisé est inséré à chaque changement de couche, juste avant "
-"le mouvement en Z. Notez que vous pouvez utiliser des variables génériques "
-"pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1065
+msgid "Retract on layer change"
+msgstr "Rétracter lors des changements de couche"
-#: src/libslic3r/PrintConfig.cpp:104
-msgid "Between objects G-code"
-msgstr "Entre le G-code des objets"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1202
+msgid "Retraction"
+msgstr "Rétraction"
-#: src/libslic3r/PrintConfig.cpp:105
-msgid ""
-"This code is inserted between objects when using sequential printing. By "
-"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."
-msgstr ""
-"Ce code est inséré entre des objets lorsque vous utilisez l'impression "
-"séquentielle. Par défaut la température de l'extrudeur et du plateau est "
-"réinitialisée et utilise la commande sans-attente ; toutefois si des "
-"commandes M104, M109, M140 ou M190 sont détectées dans ce code personnalisé, "
-"Slic3r n'ajoutera pas de commandes de température. Notez que vous pouvez "
-"utiliser des variables génériques pour tous les réglages de Slic3r, donc "
-"vous pouvez entrer une commande \"M109S[first_layer_temperature]\" où vous "
-"le souhaitez."
-
-#: src/libslic3r/PrintConfig.cpp:114
-msgctxt "Layers"
-msgid "Bottom"
-msgstr "Dessous"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1051
+msgid "Retraction is not triggered when travel moves are shorter than this length."
+msgstr "La rétraction n'est pas déclenchée lorsque les déplacements sont plus courts que cette distance."
-#: src/libslic3r/PrintConfig.cpp:116
-msgid "Number of solid layers to generate on bottom surfaces."
-msgstr "Nombre de couches solides à générer sur les surfaces inférieures."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1072
+msgid "Retraction Length"
+msgstr "Longueur de Rétractation"
-#: src/libslic3r/PrintConfig.cpp:118
-msgid "Bottom solid layers"
-msgstr "Couches solides inférieures"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1081
+msgid "Retraction Length (Toolchange)"
+msgstr "Longueur de Rétractation (changement d'outil)"
-#: src/libslic3r/PrintConfig.cpp:123
-msgid "Bridge"
-msgstr "Pont"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1134
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1135
+msgid "Retraction Speed"
+msgstr "Vitesse de Rétractation"
-#: src/libslic3r/PrintConfig.cpp:124
-msgid ""
-"This is the acceleration your printer will use for bridges. Set zero to "
-"disable acceleration control for bridges."
-msgstr ""
-"L'accélération qui sera utilisée par votre imprimante pour les ponts. Régler "
-"sur zéro pour désactiver l'accélération pour les ponts."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1218
+msgid "Retraction when tool is disabled (advanced settings for multi-extruder setups)"
+msgstr "Rétractation lorsque l'outil est désactivé (réglages avancés pour les configurations multi-extrudeurs)"
-#: src/libslic3r/PrintConfig.cpp:126 src/libslic3r/PrintConfig.cpp:274
-#: src/libslic3r/PrintConfig.cpp:819 src/libslic3r/PrintConfig.cpp:941
-#: src/libslic3r/PrintConfig.cpp:1100 src/libslic3r/PrintConfig.cpp:1145
-#: src/libslic3r/PrintConfig.cpp:1156 src/libslic3r/PrintConfig.cpp:1386
-msgid "mm/s²"
-msgstr "mm/s²"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:96
+msgid "Retractions"
+msgstr "Rétractations"
-#: src/libslic3r/PrintConfig.cpp:133
-msgid "Bridging angle"
-msgstr "Angle du pont"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:374
+msgid "Right"
+msgstr "Droite"
-#: src/libslic3r/PrintConfig.cpp:135
-msgid ""
-"Bridging angle override. If left to zero, the bridging angle will be "
-"calculated automatically. Otherwise the provided angle will be used for all "
-"bridges. Use 180° for zero angle."
-msgstr ""
-"Contournement de l'angle du pont. Si laissé à zéro, l'angle du pont sera "
-"calculé automatiquement. Sinon, l'angle fourni sera utilisé pour tous les "
-"ponts. Utilisez 180° pour un angle nul."
-
-#: src/libslic3r/PrintConfig.cpp:138 src/libslic3r/PrintConfig.cpp:734
-#: src/libslic3r/PrintConfig.cpp:1637 src/libslic3r/PrintConfig.cpp:1648
-#: src/libslic3r/PrintConfig.cpp:1896 src/libslic3r/PrintConfig.cpp:2063
-#: src/libslic3r/PrintConfig.cpp:2578
-msgid "°"
-msgstr "°"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:374
+msgid "Right View"
+msgstr "Vue Droite"
-#: src/libslic3r/PrintConfig.cpp:145
-msgid "Bridges fan speed"
-msgstr "Vitesse du ventilateur pour les ponts"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2042
+msgid "Rotate"
+msgstr "Pivoter"
-#: src/libslic3r/PrintConfig.cpp:146
-msgid "This fan speed is enforced during all bridges and overhangs."
-msgstr ""
-"Cette vitesse de ventilateur sera utilisée pour les ponts et les surplombs."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2034
+msgid "Rotate 45° clockwise"
+msgstr "Pivoter de 45° dans le sens des aiguilles d'une montre"
-#: src/libslic3r/PrintConfig.cpp:147 src/libslic3r/PrintConfig.cpp:747
-#: src/libslic3r/PrintConfig.cpp:1165 src/libslic3r/PrintConfig.cpp:1232
-#: src/libslic3r/PrintConfig.cpp:1517
-msgid "%"
-msgstr "%"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2037
+msgid "Rotate 45° counter-clockwise"
+msgstr "Pivoter de 45° dans le sens inverse des aiguilles d'une montre"
-#: src/libslic3r/PrintConfig.cpp:155
-msgid "Bridge flow ratio"
-msgstr "Ratio de flux pour les ponts"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2034
+msgid "Rotate the selected object by 45° clockwise"
+msgstr "Pivoter l'objet sélectionné de 45° dans le sens des aiguilles d'une montre"
-#: src/libslic3r/PrintConfig.cpp:157
-msgid ""
-"This factor affects the amount of plastic for bridging. You can decrease it "
-"slightly to pull the extrudates and prevent sagging, although default "
-"settings are usually good and you should experiment with cooling (use a fan) "
-"before tweaking this."
-msgstr ""
-"Ce facteur affecte la quantité de plastique utilisée pour les ponts. Vous "
-"pouvez le diminuer légèrement pour éviter l'affaissement. La valeur par "
-"défaut est généralement suffisante et vous devriez expérimenter le "
-"refroidissement (utiliser un ventilateur) avant de modifier ceci."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2037
+msgid "Rotate the selected object by 45° counter-clockwise"
+msgstr "Pivoter l'objet sélectionné de 45° dans le sens inverse des aiguilles d'une montre"
-#: src/libslic3r/PrintConfig.cpp:168
-msgid "Bridges"
-msgstr "Ponts"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2042
+msgid "Rotate the selected object by an arbitrary angle"
+msgstr "Pivoter l'objet sélectionnée d'un angle donné"
-#: src/libslic3r/PrintConfig.cpp:170
-msgid "Speed for printing bridges."
-msgstr "Vitesse d'impression des ponts."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2044
+msgid "Rotate the selected object by an arbitrary angle around X axis"
+msgstr "Pivoter l'objet sélectionnée d'un angle donné autour de l'axe X"
-#: src/libslic3r/PrintConfig.cpp:171 src/libslic3r/PrintConfig.cpp:564
-#: src/libslic3r/PrintConfig.cpp:573 src/libslic3r/PrintConfig.cpp:583
-#: src/libslic3r/PrintConfig.cpp:592 src/libslic3r/PrintConfig.cpp:623
-#: src/libslic3r/PrintConfig.cpp:644 src/libslic3r/PrintConfig.cpp:884
-#: src/libslic3r/PrintConfig.cpp:1013 src/libslic3r/PrintConfig.cpp:1090
-#: src/libslic3r/PrintConfig.cpp:1110 src/libslic3r/PrintConfig.cpp:1123
-#: src/libslic3r/PrintConfig.cpp:1134 src/libslic3r/PrintConfig.cpp:1189
-#: src/libslic3r/PrintConfig.cpp:1252 src/libslic3r/PrintConfig.cpp:1418
-#: src/libslic3r/PrintConfig.cpp:1601 src/libslic3r/PrintConfig.cpp:1611
-#: src/libslic3r/PrintConfig.cpp:2041 src/libslic3r/PrintConfig.cpp:2160
-msgid "mm/s"
-msgstr "mm/s"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2047
+msgid "Rotate the selected object by an arbitrary angle around Y axis"
+msgstr "Pivoter l'objet sélectionnée d'un angle donné autour de l'axe Y"
-#: src/libslic3r/PrintConfig.cpp:178
-msgid "Brim width"
-msgstr "Largeur de la bordure"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2050
+msgid "Rotate the selected object by an arbitrary angle around Z axis"
+msgstr "Pivoter l'objet sélectionnée d'un angle donné autour de l'axe Z"
-#: src/libslic3r/PrintConfig.cpp:179
-msgid ""
-"Horizontal width of the brim that will be printed around each object on the "
-"first layer."
-msgstr ""
-"Largeur horizontale de la bordure qui sera imprimée autour de chaque objet "
-"sur la première couche."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:211 xs/src/slic3r/GUI/GUI.cpp:399
+#, c-format
+msgid "Run %s"
+msgstr "Run %s"
-#: src/libslic3r/PrintConfig.cpp:187
-msgid "Clip multi-part objects"
-msgstr "Dissocier les objets multi-pièces"
+#: 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 "s"
-#: src/libslic3r/PrintConfig.cpp:188
-msgid ""
-"When printing multi-material objects, this settings will make slic3r to clip "
-"the overlapping object parts one by the other (2nd part will be clipped by "
-"the 1st, 3rd part will be clipped by the 1st and 2nd etc)."
-msgstr ""
-"Lorsque vous imprimez des objets multi-matériaux, ce réglage fera en sorte "
-"que Slic3r rattache ensemble les parties de l'objet qui se superposent (la "
-"2e partie sera rattachée à la 1ere, la 3e partie sera rattachée à la 1ere et "
-"la 2e, etc...)."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1751
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:514
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1645
+msgid "Save "
+msgstr "Enregistrer "
-#: src/libslic3r/PrintConfig.cpp:196
-msgid "Colorprint height"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:605
+msgid "Save configuration as:"
+msgstr "Enregistrer la configuration sous :"
-#: src/libslic3r/PrintConfig.cpp:197
-msgid "Heights at which a filament change is to occur. "
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:50
+msgid "Save current "
+msgstr "Enregistrer l'état actuel "
-#: src/libslic3r/PrintConfig.cpp:207
-msgid "Compatible printers condition"
-msgstr "Condition de compatibilité des imprimantes"
+#: lib/Slic3r/GUI/Plater.pm:1399
+msgid "Save G-code file as:"
+msgstr "Sauvegarder le fichier G-code en tant que :"
-#: src/libslic3r/PrintConfig.cpp:208
-msgid ""
-"A boolean expression using the configuration values of an active printer "
-"profile. If this expression evaluates to true, this profile is considered "
-"compatible with the active printer profile."
-msgstr ""
-"Une expression booléenne utilisant les valeurs de configuration d'un profil "
-"d'imprimante actif. Si cette expression est évaluée comme vraie, ce profil "
-"est considéré comme compatible avec le profil d'imprimante actif."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:580
+msgid "Save OBJ file (less prone to coordinate errors than STL) as:"
+msgstr "Enregistrer le fichier OBJ (moins enclin aux erreurs de coordonnées que le STL) sous :"
-#: src/libslic3r/PrintConfig.cpp:220
-msgid "Compatible print profiles condition"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:248
+msgid "Save preset"
+msgstr "Enregistrer le préréglage"
-#: src/libslic3r/PrintConfig.cpp:221
-msgid ""
-"A boolean expression using the configuration values of an active print "
-"profile. If this expression evaluates to true, this profile is considered "
-"compatible with the active print profile."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:646
+msgid "Save presets bundle as:"
+msgstr "Enregistrer le lot de préréglages sous :"
-#: src/libslic3r/PrintConfig.cpp:235
-msgid "Complete individual objects"
-msgstr "Compléter les objets individuels"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:222
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1056
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1061
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2068
+msgid "Scale"
+msgstr "Redimensionner"
-#: src/libslic3r/PrintConfig.cpp:236
-msgid ""
-"When printing multiple objects or copies, this feature will complete each "
-"object before moving onto next one (and starting it from its bottom layer). "
-"This feature is useful to avoid the risk of ruined prints. Slic3r should "
-"warn and prevent you from extruder collisions, but beware."
-msgstr ""
-"Lorsque vous imprimez plusieurs objets ou copies, ce réglage permet de "
-"terminer un objet avant de passer au suivant (en repartant de sa première "
-"couche). Cette fonction est utile pour éviter les risques d'impressions "
-"gâchées. Slic3r doit vous avertir et éviter les collisions entre les objets "
-"et l'extrudeur, mais soyez vigilant."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1031
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1035
+msgid "Scale along "
+msgstr "Redimensionner le long de "
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2068
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2084
+msgid "Scale the selected object along a single axis"
+msgstr "Redimensionner l'objet sélectionné le long d'un seul axe"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2073
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2089
+msgid "Scale the selected object along the X axis"
+msgstr "Redimensionner l'objet sélectionné le long de l'axe X"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2070
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2086
+msgid "Scale the selected object along the XYZ axes"
+msgstr "Redimensionner l'objet sélectionné le long des axes XYZ"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2076
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2092
+msgid "Scale the selected object along the Y axis"
+msgstr "Redimensionner l'objet sélectionné le long de l'axe Y"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2079
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2095
+msgid "Scale the selected object along the Z axis"
+msgstr "Redimensionner l'objet sélectionné le long de l'axe Z"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2084
+msgid "Scale to size"
+msgstr "Redimensionner à la taille"
+
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:187
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:203
+msgid "Scale…"
+msgstr "Redimensionner…"
+
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1151
+msgid "Seam position"
+msgstr "Position de la jointure"
-#: src/libslic3r/PrintConfig.cpp:245
-msgid "Enable auto cooling"
-msgstr "Activer le refroidissement automatique"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1172
+msgid "Seam preferred direction"
+msgstr "Direction préférée de la jointure"
-#: src/libslic3r/PrintConfig.cpp:246
-msgid ""
-"This flag enables the automatic cooling logic that adjusts print speed and "
-"fan speed according to layer printing time."
-msgstr ""
-"Cette option active la logique de refroidissement automatique, qui ajuste la "
-"vitesse d'impression et celle du ventilateur en fonction du temps "
-"d'impression de la couche."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1182
+msgid "Seam preferred direction jitter"
+msgstr "Gigue de la direction préférée de la jointure"
-#: src/libslic3r/PrintConfig.cpp:252
-msgid "Cooling tube position"
-msgstr "Position du tube de refroidissement"
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:187
+msgid "Searching for devices"
+msgstr "Recherche des dispositifs"
-#: src/libslic3r/PrintConfig.cpp:253
-msgid "Distance of the center-point of the cooling tube from the extruder tip "
-msgstr ""
-"Distance entre le point central du tube de refroidissement et la pointe de "
-"l'extrudeur. "
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:342
+msgid "Select &Controller Tab\tCtrl+T"
+msgstr "Sélectionner l'Onglet &Contrôleur\tCtrl+T"
-#: src/libslic3r/PrintConfig.cpp:261
-msgid "Cooling tube length"
-msgstr "Longueur du tube de refroidissement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:353
+msgid "Select &Filament Settings Tab\tCtrl+3"
+msgstr "Sélectionner l'Onglet des Réglages du &Filament\tCtrl+3"
-#: src/libslic3r/PrintConfig.cpp:262
-msgid "Length of the cooling tube to limit space for cooling moves inside it "
-msgstr ""
-"Longueur du tube de refroidissement pour limiter l'espace pour les "
-"déplacements de refroidissement à l'intérieur de celui-ci "
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:336
+msgid "Select &Plater Tab\tCtrl+1"
+msgstr "Sélectionner l'Onglet du &Plateau\tCtrl+1"
-#: src/libslic3r/PrintConfig.cpp:271
-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 ""
-"Accélération à laquelle votre imprimante sera réinitialisée suite à une "
-"modification de l'accélération des fonctions spécifiques (périmètre/"
-"remplissage). Régler sur zéro pour ne pas réinitialiser l'accélération."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:103
+msgid "Select all"
+msgstr "Tout sélectionner"
-#: src/libslic3r/PrintConfig.cpp:281
-msgid "Default filament profile"
-msgstr "Profil de filament par défaut"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:623
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:667
+msgid "Select configuration to load:"
+msgstr "Sélectionner la configuration à charger :"
-#: src/libslic3r/PrintConfig.cpp:282
-msgid ""
-"Default filament profile associated with the current printer profile. On "
-"selection of the current printer profile, this filament profile will be "
-"activated."
-msgstr ""
-"Profil de filament par défaut associé au profil d'imprimante courant. En "
-"sélectionnant le profil d'imprimante courant, ce profil de filament sera "
-"activé."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:104
+msgid "Select none"
+msgstr "Ne sélectionner aucun"
-#: src/libslic3r/PrintConfig.cpp:287
-msgid "Default print profile"
-msgstr "Profil de filament par défaut"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:350
+msgid "Select P&rint Settings Tab\tCtrl+2"
+msgstr "Sélectionner l'Onglet des Réglages d'&Impression\tCtrl+2"
-#: src/libslic3r/PrintConfig.cpp:288 src/libslic3r/PrintConfig.cpp:2469
-#: src/libslic3r/PrintConfig.cpp:2479
-msgid ""
-"Default print profile associated with the current printer profile. On "
-"selection of the current printer profile, this print profile will be "
-"activated."
-msgstr ""
-"Profil de filament par défaut associé au profil d'imprimante courant. En "
-"sélectionnant le profil d'imprimante courant, ce profil de filament sera "
-"activé."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:356
+msgid "Select Print&er Settings Tab\tCtrl+4"
+msgstr "Sélectionner l'Onglet des Réglages de l'Impri&mante\tCtrl+4"
-#: src/libslic3r/PrintConfig.cpp:293
-msgid "Disable fan for the first"
-msgstr "Désactiver le ventilateur pour le(s) première(s)"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:235
+msgid "Select the language"
+msgstr "Sélectionner la langue"
-#: src/libslic3r/PrintConfig.cpp:294
-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 ""
-"Vous pouvez régler ce paramètre sur une valeur positive pour désactiver "
-"complètement le ventilateur pendant les premières couches, afin de ne pas "
-"rendre l'adhérence plus difficile."
-
-#: src/libslic3r/PrintConfig.cpp:296 src/libslic3r/PrintConfig.cpp:952
-#: src/libslic3r/PrintConfig.cpp:1487 src/libslic3r/PrintConfig.cpp:1691
-#: src/libslic3r/PrintConfig.cpp:1757 src/libslic3r/PrintConfig.cpp:1935
-#: src/libslic3r/PrintConfig.cpp:1985
-msgid "layers"
-msgstr "couches"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1667
+msgid "Select the printers this profile is compatible with."
+msgstr "Sélectionner les imprimantes avec lesquelles ce profil est compatible."
-#: src/libslic3r/PrintConfig.cpp:304
-msgid "Don't support bridges"
-msgstr "Ne pas supporter les ponts"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:566
+msgid "Select the STL file to repair:"
+msgstr "Sélectionner le fichier STL à réparer :"
-#: src/libslic3r/PrintConfig.cpp:306
-msgid ""
-"Experimental option for preventing support material from being generated "
-"under bridged areas."
-msgstr ""
-"Option expérimentale pour empêcher la génération de support sous les ponts."
+#: xs/src/slic3r/GUI/GUI.cpp:882
+msgid "Select what kind of support do you need"
+msgstr "Choisissez le type de support dont vous avez besoin"
-#: src/libslic3r/PrintConfig.cpp:313
-msgid "Distance between copies"
-msgstr "Distance entre les copies"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:239
+msgid "Send to printer"
+msgstr "Envoyer à l'imprimante"
-#: src/libslic3r/PrintConfig.cpp:314
-msgid "Distance used for the auto-arrange feature of the plater."
-msgstr "Distance utilisée par la fonction d'agencement automatique du plateau."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1448
+msgid "Sending G-code file to the OctoPrint server..."
+msgstr "Envoi du fichier G-code vers le serveur OctoPrint..."
-#: src/libslic3r/PrintConfig.cpp:322
-msgid "Elephant foot compensation"
-msgstr "Compensation de l'effet patte d'éléphant"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:477
+msgid "Sequential printing"
+msgstr "Impression séquentielle"
-#: src/libslic3r/PrintConfig.cpp:324
-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 ""
-"La première couche sera réduite sur le plan XY selon la valeur configurée "
-"afin de compenser l'écrasement de la première couche également connu sous le "
-"nom d'effet Pied d'Éléphant."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:990
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1193
+msgid "Serial port"
+msgstr "Port série"
-#: src/libslic3r/PrintConfig.cpp:334
-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 ""
-"Cette procédure de fin est insérée à la fin du fichier de sortie. Notez que "
-"vous pouvez utiliser des variables génériques pour tous les réglages de "
-"Slic3r."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1202
+msgid "Serial port speed"
+msgstr "Vitesse du port série"
-#: src/libslic3r/PrintConfig.cpp:345
-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 "
-"Slic3r settings. If you have multiple extruders, the gcode is processed in "
-"extruder order."
-msgstr ""
-"Cette procédure de fin est insérée à la fin du fichier de sortie, avant le "
-"gcode de fin de l'imprimante. Notez que vous pouvez utiliser des variables "
-"génériques pour tous les réglages de Slic3r. Si vous avez plusieurs "
-"extrudeurs, le gcode sera traité suivant l'ordre des extrudeurs."
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:286
+msgid "Serial port:"
+msgstr "Port série :"
-#: src/libslic3r/PrintConfig.cpp:356
-msgid "Ensure vertical shell thickness"
-msgstr "S'assurer de l'épaisseur de la coque verticale"
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:68
+msgid "Service name"
+msgstr "Nom du service"
-#: src/libslic3r/PrintConfig.cpp:358
-msgid ""
-"Add solid infill near sloping surfaces to guarantee the vertical shell "
-"thickness (top+bottom solid layers)."
-msgstr ""
-"Ajouter un remplissage plein à proximité des surfaces inclinées pour "
-"garantir une épaisseur de coque verticale (couches solides supérieures"
-"+inférieures)."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2030
+msgid "Set number of copies…"
+msgstr "Choisir le nombre de copies…"
-#: src/libslic3r/PrintConfig.cpp:365
-msgid "Top/bottom fill pattern"
-msgstr "Motif de remplissage supérieur/inférieur"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:398
+msgid "Set the shape of your printer's bed."
+msgstr "Réglez la forme du plateau de votre imprimante."
-#: src/libslic3r/PrintConfig.cpp:367
-msgid ""
-"Fill pattern for top/bottom infill. This only affects the external visible "
-"layer, and not its adjacent solid shells."
-msgstr ""
-"Motif pour les remplissages supérieurs/inférieurs. Ceci affecte seulement la "
-"couche externe visible, et non les coques solides adjacentes."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:378
+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 tooltips for perimeter extrusion width, infill extrusion width etc). If expressed as percentage (for example: 230%), it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion. Si la valeur reste sur zéro, Slic3r calcule la largeur d’extrusion en se basant sur le diamètre de la buse (voir l’info-bulle concernant la largeur d’extrusion du périmètre, la largeur d’extrusion du remplissage, etc…). Si la valeur est exprimée en pourcentage (par exemple : 230%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:376 src/libslic3r/PrintConfig.cpp:800
-#: src/libslic3r/PrintConfig.cpp:2021
-msgid "Rectilinear"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:269
+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, otherwise 1.125 x nozzle diameter will be used. If expressed as percentage (for example 200%), it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour les périmètres extérieurs. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par exemple : 200%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:377 src/libslic3r/PrintConfig.cpp:806
-msgid "Concentric"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:593
+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 expressed as percentage (for example 120%) it will be computed over first layer height. If set to zero, it will use the default extrusion width."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour la première couche. Vous pouvez procéder ainsi pour obtenir des extrudats plus épais afin d’avoir une meilleure adhérence. Si la valeur est exprimée en pourcentage (par exemple : 120%), elle sera calculée par rapport à la hauteur de la première couche. Si elle est réglée sur zéro, elle utilisera la largeur d’extrusion par défaut."
-#: src/libslic3r/PrintConfig.cpp:378 src/libslic3r/PrintConfig.cpp:810
-msgid "Hilbert Curve"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1293
+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, otherwise 1.125 x nozzle diameter will be used. If expressed as percentage (for example 90%) it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour le remplissage ou pour les surfaces pleines. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:379 src/libslic3r/PrintConfig.cpp:811
-msgid "Archimedean Chords"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1615
+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 regions and get a smoother finish. If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. If expressed as percentage (for example 90%) it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour le remplissage ou pour les surfaces supérieures. Vous voudrez peut-être utiliser des extrudats plus fins pour remplir les zones les plus étroites et obtenir des finitions plus lisses. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon le diamètre de la buse sera utilisé. Si la valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:380 src/libslic3r/PrintConfig.cpp:812
-msgid "Octagram Spiral"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:711
+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 nozzle diameter will be used. You may want to use fatter extrudates to speed up the infill and make your parts stronger. If expressed as percentage (for example 90%) it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour le remplissage. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Vous voudrez peut-être utiliser des extrudats plus épais pour accélérer le remplissage et rendre vos pièces plus solides. Si la valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:386 src/libslic3r/PrintConfig.cpp:397
-msgid "External perimeters"
-msgstr "Périmètres externes"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:968
+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 left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. If expressed as percentage (for example 200%) it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement une largeur d’extrusion pour les périmètres. Vous voudrez peut-être utiliser des extrudats plus fin pour obtenir des surfaces plus nettes. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par exemple : 200%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:388
-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, "
-"otherwise 1.125 x nozzle diameter will be used. If expressed as percentage "
-"(for example 200%), it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour les périmètres extérieurs. Si la valeur reste sur "
-"zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la "
-"valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est exprimée "
-"en pourcentage (par exemple : 200%), elle sera calculée par rapport à la "
-"hauteur de couche."
-
-#: src/libslic3r/PrintConfig.cpp:391 src/libslic3r/PrintConfig.cpp:841
-#: src/libslic3r/PrintConfig.cpp:975 src/libslic3r/PrintConfig.cpp:1408
-#: src/libslic3r/PrintConfig.cpp:1769 src/libslic3r/PrintConfig.cpp:1958
-#: src/libslic3r/PrintConfig.cpp:2129
-msgid "mm or % (leave 0 for default)"
-msgstr "mm ou % (laissez à 0 pour la valeur par défaut)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1455
+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, otherwise nozzle diameter will be used. If expressed as percentage (for example 90%) it will be computed over layer height."
+msgstr "Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la largeur d’extrusion pour les supports. Si la valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon le diamètre de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur de couche."
-#: src/libslic3r/PrintConfig.cpp:399
-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 ""
-"Ce réglage distinct affectera la vitesse des périmètres extérieurs (ceux qui "
-"sont visibles). Si cette valeur est exprimée en pourcentage (par exemple: "
-"80%) elle sera calculée d'après le réglage de la vitesse de périmètre "
-"susmentionnée. Réglez sur zéro pour un ajustement automatique."
-
-#: src/libslic3r/PrintConfig.cpp:402 src/libslic3r/PrintConfig.cpp:864
-#: src/libslic3r/PrintConfig.cpp:1725 src/libslic3r/PrintConfig.cpp:1780
-#: src/libslic3r/PrintConfig.cpp:2006 src/libslic3r/PrintConfig.cpp:2142
-msgid "mm/s or %"
-msgstr "mm/s ou %"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:332
+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 "Paramétrez ceci avec le rayon de dégagement autour de l'extrudeur. Si l'extrudeur n'est pas centré, choisissez la plus grande valeur par sécurité. Ce réglage est utilisé pour vérifier les collisions et afficher l'aperçu graphique sur le plateau."
-#: src/libslic3r/PrintConfig.cpp:409
-msgid "External perimeters first"
-msgstr "Périmètres externes en premier"
+#: xs/src/libslic3r/PrintConfig.cpp:877
+msgid "Set this to the maximum height that can be reached by your extruder while printing."
+msgstr "Réglez cette valeur sur la hauteur maximum que peut atteindre votre extrudeur au cours de l'impression."
-#: src/libslic3r/PrintConfig.cpp:411
-msgid ""
-"Print contour perimeters from the outermost one to the innermost one instead "
-"of the default inverse order."
-msgstr ""
-"Imprimer les périmètres de l'extérieur vers l'intérieur au lieu de l'ordre "
-"par défaut qui est inversé."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:321
+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 cylinder around your extruder, and it represents the maximum depth the extruder can peek before colliding with other printed objects."
+msgstr "Paramétrez ceci avec la distance verticale entre la pointe de la buse et (habituellement) les tiges du chariot de l'axe X. En d'autres termes, il s'agit de la hauteur du cylindre de dégagement autour de l'extrudeur, et elle représente la profondeur maximum à laquelle peut descendre l'extrudeur avant d'entrer en collision avec d'autres objets imprimés."
-#: src/libslic3r/PrintConfig.cpp:418
-msgid "Extra perimeters if needed"
-msgstr "Périmètres supplémentaires si nécessaire"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:120
+msgid "Settings"
+msgstr "Réglages"
-#: src/libslic3r/PrintConfig.cpp:420
-#, 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 ""
-"Ajouter plus de périmètres si nécessaire pour éviter des trous dans les "
-"parois inclinées. Slic3r ajoute des périmètres, jusqu'à ce que plus de 70% "
-"de la boucle immédiatement au-dessus soit supportée."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:191
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:206
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2106
+msgid "Settings…"
+msgstr "Réglages…"
-#: src/libslic3r/PrintConfig.cpp:431
-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 ""
-"L'extrudeur à utiliser (à moins que d'autres réglages d'extrudeur plus "
-"spécifiques soient spécifiés). Cette valeur se substitue aux extrudeurs de "
-"périmètre et de remplissage, mais pas aux extrudeurs de support."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:39
+msgid "Shape"
+msgstr "Forme"
-#: src/libslic3r/PrintConfig.cpp:444
-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 "
-"cylinder around your extruder, and it represents the maximum depth the "
-"extruder can peek before colliding with other printed objects."
-msgstr ""
-"Paramétrez ceci avec la distance verticale entre la pointe de la buse et "
-"(habituellement) les tiges du chariot de l'axe X. En d'autres termes, il "
-"s'agit de la hauteur du cylindre de dégagement autour de l'extrudeur, et "
-"elle représente la profondeur maximum à laquelle peut descendre l'extrudeur "
-"avant d'entrer en collision avec d'autres objets imprimés."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:98
+msgid "Shells"
+msgstr "Coques"
-#: src/libslic3r/PrintConfig.cpp:455
-msgid "Radius"
-msgstr "Rayon"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:75
+msgid "Show"
+msgstr "Afficher"
-#: src/libslic3r/PrintConfig.cpp:456
-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 ""
-"Paramétrez ceci avec le rayon de dégagement autour de l'extrudeur. Si "
-"l'extrudeur n'est pas centré, choisissez la plus grande valeur par sécurité. "
-"Ce réglage est utilisé pour vérifier les collisions et afficher l'aperçu "
-"graphique sur le plateau."
+#: lib/Slic3r/GUI/MainFrame.pm:337
+msgid "Show &Configuration Folder"
+msgstr "Afficher le Répertoire de &Configuration"
-#: src/libslic3r/PrintConfig.cpp:467
-msgid "Extruder Color"
-msgstr "Couleur de l'extrudeur"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:408
+msgid "Show about dialog"
+msgstr "Afficher la boîte de dialogue à propos"
-#: src/libslic3r/PrintConfig.cpp:468 src/libslic3r/PrintConfig.cpp:535
-msgid "This is only used in the Slic3r interface as a visual help."
-msgstr ""
-"Ceci est uniquement utilisé dans l'interface de Slic3r comme indication "
-"visuelle."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:337
+msgid "Show advanced settings"
+msgstr "Afficher les réglages avancés"
-#: src/libslic3r/PrintConfig.cpp:475
-msgid "Extruder offset"
-msgstr "Décalage de l'extrudeur"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:67
+msgid "Show incompatible print and filament presets"
+msgstr "Afficher les préréglages d'impression et de filament incompatibles"
-#: src/libslic3r/PrintConfig.cpp:476
-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 "
-"of each extruder with respect to the first one. It expects positive "
-"coordinates (they will be subtracted from the XY coordinate)."
-msgstr ""
-"Si le firmware de votre imprimante ne gère pas le décalage de l'extrudeur, "
-"c'est au G-code d'en tenir compte. Cette option vous permet de spécifier le "
-"décalage de chaque extrudeur par rapport au premier. Des valeurs positives "
-"sont attendues (elles seront soustraites des coordonnées XY)."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:337
+msgid "Show simplified settings"
+msgstr "Afficher les réglages simplifiés"
-#: src/libslic3r/PrintConfig.cpp:486
-msgid "Extrusion axis"
-msgstr "Axe d'extrusion"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:402
+msgid "Show system information"
+msgstr "Afficher les informations système"
-#: src/libslic3r/PrintConfig.cpp:487
-msgid ""
-"Use this option to set the axis letter associated to your printer's extruder "
-"(usually E but some printers use A)."
-msgstr ""
-"Utiliser cette option pour indiquer la lettre utilisée par l'extrudeur de "
-"votre imprimante (habituellement E, mais certaines imprimantes utilisent A)."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:353
+msgid "Show the filament settings"
+msgstr "Afficher les réglages de filament"
-#: src/libslic3r/PrintConfig.cpp:493
-msgid "Extrusion multiplier"
-msgstr "Multiplicateur d'extrusion"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:336
+msgid "Show the plater"
+msgstr "Afficher le plateau"
-#: src/libslic3r/PrintConfig.cpp:494
-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. "
-"Usual values are between 0.9 and 1.1. If you think you need to change this "
-"more, check filament diameter and your firmware E steps."
-msgstr ""
-"Ce facteur modifie proportionnellement le flux d'extrusion. Vous pouvez "
-"avoir besoin de modifier ceci afin d'obtenir un rendu de surface net et une "
-"largeur correcte pour les murs uniques. Les valeurs habituelles vont de 0.9 "
-"à 1.1. Si vous pensez devoir changer davantage cette valeur, vérifiez le "
-"diamètre de votre filament et les E Steps dans le firmware."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:350
+msgid "Show the print settings"
+msgstr "Afficher les réglages d'impression"
-#: src/libslic3r/PrintConfig.cpp:503
-msgid "Default extrusion width"
-msgstr "Largeur d'extrusion par défaut"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:342
+msgid "Show the printer controller"
+msgstr "Afficher le contrôleur de l'imprimante"
-#: src/libslic3r/PrintConfig.cpp:505
-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 "
-"tooltips for perimeter extrusion width, infill extrusion width etc). If "
-"expressed as percentage (for example: 230%), it will be computed over layer "
-"height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion. Si la valeur reste sur zéro, Slic3r calcule la largeur "
-"d’extrusion en se basant sur le diamètre de la buse (voir l’info-bulle "
-"concernant la largeur d’extrusion du périmètre, la largeur d’extrusion du "
-"remplissage, etc…). Si la valeur est exprimée en pourcentage (par exemple : "
-"230%), elle sera calculée par rapport à la hauteur de couche."
-
-#: src/libslic3r/PrintConfig.cpp:509
-msgid "mm or % (leave 0 for auto)"
-msgstr "mm ou % (laissez à 0 pour le mode automatique)"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:356
+msgid "Show the printer settings"
+msgstr "Afficher les réglages de l'imprimante"
-#: src/libslic3r/PrintConfig.cpp:515
-msgid "Keep fan always on"
-msgstr "Garder le ventilateur toujours actif"
+#: lib/Slic3r/GUI/MainFrame.pm:337
+msgid "Show user configuration folder (datadir)"
+msgstr "Afficher le répertoire de configuration utilisateur (datadir)"
-#: src/libslic3r/PrintConfig.cpp:516
-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 ""
-"Si ceci est activé, le ventilateur ne sera jamais désactivé et sera maintenu "
-"au moins à sa vitesse minimum. Utile pour le PLA, mais risqué pour l'ABS."
+#: xs/src/slic3r/GUI/Tab.cpp:1716 xs/src/slic3r/GUI/Tab.cpp:1722
+msgid "Single extruder MM setup"
+msgstr "Réglage MM pour extrudeur unique"
-#: src/libslic3r/PrintConfig.cpp:522
-msgid "Enable fan if layer print time is below"
-msgstr ""
-"Activer le ventilateur si le temps d'impression de la couche est inférieur à"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1373
+msgid "Single Extruder Multi Material"
+msgstr "Extrudeur Unique Multi-Matériaux"
-#: src/libslic3r/PrintConfig.cpp:523
-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 ""
-"Si le temps d'impression estimé de la couche est inférieur à ce nombre de "
-"secondes, le ventilateur sera activé et sa vitesse calculée par "
-"interpolation des vitesses minimum et maximum."
+#: xs/src/slic3r/GUI/Tab.cpp:1723
+msgid "Single extruder multimaterial parameters"
+msgstr "Paramètres multimatériaux pour extrudeur unique"
-#: src/libslic3r/PrintConfig.cpp:525 src/libslic3r/PrintConfig.cpp:1711
-msgid "approximate seconds"
-msgstr "secondes approximatives"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:50
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1191
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:408
+msgid "Size"
+msgstr "Taille"
-#: src/libslic3r/PrintConfig.cpp:534
-msgid "Color"
-msgstr "Couleur"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:938
+msgid "Size and coordinates"
+msgstr "Taille et coordonnées"
-#: src/libslic3r/PrintConfig.cpp:541
-msgid "Filament notes"
-msgstr "Notes du filament"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:51
+msgid "Size in X and Y of the rectangular plate."
+msgstr "Taille en X et Y du plateau rectangulaire."
-#: src/libslic3r/PrintConfig.cpp:542
-msgid "You can put your notes regarding the filament here."
-msgstr "Vous pouvez saisir vos remarques concernant le filament ici."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:365
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:146
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:88
+msgid "Skirt"
+msgstr "Clôture"
-#: src/libslic3r/PrintConfig.cpp:551 src/libslic3r/PrintConfig.cpp:1196
-msgid "Max volumetric speed"
-msgstr "Vitesse volumétrique maximale"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:364
+msgid "Skirt and brim"
+msgstr "Jupe et Clôture"
-#: src/libslic3r/PrintConfig.cpp:552
-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 ""
-"Vitesse volumétrique maximale autorisée pour ce filament. Limite la vitesse "
-"volumétrique d'une impression au minimum des vitesses volumétriques "
-"d'impression et de filament. Mettez à zéro pour enlever la limite."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1221
+msgid "Skirt height"
+msgstr "Hauteur de la clôture"
-#: src/libslic3r/PrintConfig.cpp:555 src/libslic3r/PrintConfig.cpp:1199
-msgid "mm³/s"
-msgstr "mm³/s"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1230
+msgid "Skirt Loops"
+msgstr "Boucles de la clôture"
-#: src/libslic3r/PrintConfig.cpp:562
-msgid "Loading speed"
-msgstr "Vitesse de chargement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:398
+msgid "Slic3r &Manual"
+msgstr "&Manuel de Slic3r"
-#: src/libslic3r/PrintConfig.cpp:563
-msgid "Speed used for loading the filament on the wipe tower. "
-msgstr "Vitesse utilisée pour charger le filament sur la tour de nettoyage. "
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:395
+msgid "Slic3r &Website"
+msgstr "Site &Web de Slic3r"
-#: src/libslic3r/PrintConfig.cpp:571
-msgid "Loading speed at the start"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:902
+msgid "Slic3r can upload G-code files to OctoPrint. This field should contain the API Key required for authentication."
+msgstr "Slic3r peut envoyer des fichiers G-code à OctoPrint. Ce champ doit contenir la clé d'API requise pour l'authentification."
-#: src/libslic3r/PrintConfig.cpp:572
-msgid "Speed used at the very beginning of loading phase. "
-msgstr ""
+#: 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 "Slic3r peut télécharger des fichiers G-code vers OctoPrint. Ce champ doit contenir le nom d'hôte, l'adresse IP ou l'URL de l'instance OctoPrint."
-#: src/libslic3r/PrintConfig.cpp:580
-msgid "Unloading speed"
-msgstr "Vitesse de déchargement"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:108
+msgid "Slic3r configuration is incompatible"
+msgstr "La configuration de Slic3r n'est pas compatible"
-#: src/libslic3r/PrintConfig.cpp:581
-msgid ""
-"Speed used for unloading the filament on the wipe tower (does not affect "
-"initial part of unloading just after ramming). "
-msgstr ""
-"Vitesse utilisée pour décharger le filament sur la tour de nettoyage "
-"(n'affecte pas l'étape initiale de déchargement juste après l'expulsion). "
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:929
+msgid "Slic3r Error"
+msgstr "Erreur de Slic3r"
-#: src/libslic3r/PrintConfig.cpp:590
-msgid "Unloading speed at the start"
-msgstr ""
+#: xs/src/slic3r/GUI/MsgDialog.cpp:64
+msgid "Slic3r error"
+msgstr "Erreur de Slic3r"
-#: src/libslic3r/PrintConfig.cpp:591
-msgid ""
-"Speed used for unloading the tip of the filament immediately after ramming. "
-msgstr ""
+#: xs/src/slic3r/GUI/MsgDialog.cpp:64
+msgid "Slic3r has encountered an error"
+msgstr "Slic3r a rencontré une erreur"
-#: src/libslic3r/PrintConfig.cpp:599
-msgid "Delay after unloading"
-msgstr "Délai après le déchargement"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:108
+msgid "Slic3r incompatibility"
+msgstr "Incompatibilité avec Slic3r"
-#: src/libslic3r/PrintConfig.cpp:600
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:165
+#, c-format
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 ""
-"Temps d'attente nécessaire après que le filament ait été déchargé. Peut "
-"aider à obtenir des changements d'outils fiables avec des matériaux flexible "
-"qui ont besoin de plus de temps pour revenir à leurs dimensions originales. "
-
-#: src/libslic3r/PrintConfig.cpp:610
-msgid "Number of cooling moves"
+"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 ""
+"Slic3r PE utilise à présent une structure de configuration mise à jour.\n"
+"\n"
+"Il existe à présent des \"préréglages Système\", qui intègrent les réglages par défaut pour les différentes imprimantes. Ces préréglages Système ne peuvent pas être modifiés, mais les utilisateurs peuvent désormais créer leurs propres préréglages héritant des paramètres de l'un des préréglages Système.\n"
+"Un tel préréglage peut ainsi hériter d'une valeur particulière de son parent ou la remplacer par une valeur personnalisée.\n"
+"\n"
+"Veuillez utiliser les %s qui suivent pour paramétrer les nouveaux réglages et éventuellement accepter les mises à jour de réglage automatiques."
-#: src/libslic3r/PrintConfig.cpp:611
-msgid ""
-"Filament is cooled by being moved back and forth in the cooling tubes. "
-"Specify desired number of these moves "
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:42
+msgid "slic3r version"
+msgstr "version de slic3r"
-#: src/libslic3r/PrintConfig.cpp:620
-msgid "Speed of the first cooling move"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:867
+msgid "Slic3r will not scale speed down below this speed."
+msgstr "Slic3r ne descendra pas en-dessous de cette vitesse."
-#: src/libslic3r/PrintConfig.cpp:621
-msgid "Cooling moves are gradually accelerating beginning at this speed. "
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:268
+msgid "Slice a file into a G-code"
+msgstr "Découper un fichier en G-code"
-#: src/libslic3r/PrintConfig.cpp:629
-msgid "Minimal purge on wipe tower"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:274
+msgid "Slice a file into a G-code, save as"
+msgstr "Découper un fichier en G-code, enregistrer sous"
-#: src/libslic3r/PrintConfig.cpp:630
-msgid ""
-"After a tool change, the exact position of the newly loaded filament inside "
-"the nozzle may not be known, and the filament pressure is likely not yet "
-"stable. Before purging the print head into an infill or a sacrificial "
-"object, Slic3r will always prime this amount of material into the wipe tower "
-"to produce successive infill or sacrificial object extrusions reliably."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:287
+msgid "Slice file to a multi-layer SVG"
+msgstr "Découper un fichier en un SVG multi-couches"
-#: src/libslic3r/PrintConfig.cpp:635
-msgid "mm³"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:237
+msgid "Slice now"
+msgstr "Découper maintenant"
-#: src/libslic3r/PrintConfig.cpp:641
-msgid "Speed of the last cooling move"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:287
+msgid "Slice to SV&G…\tCtrl+G"
+msgstr "Découper vers SV&G...\tCtrl+G"
-#: src/libslic3r/PrintConfig.cpp:642
-msgid "Cooling moves are gradually accelerating towards this speed. "
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:438
+msgid "Sliced Info"
+msgstr "Informations de découpage"
-#: src/libslic3r/PrintConfig.cpp:650
-msgid "Filament load time"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1286
+msgid "Slicing cancelled"
+msgstr "Découpe annulée"
-#: src/libslic3r/PrintConfig.cpp:651
-msgid ""
-"Time for the printer firmware (or the Multi Material Unit 2.0) to load a new "
-"filament during a tool change (when executing the T code). This time is "
-"added to the total print time by the G-code time estimator."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:550
+msgid "Slicing Done!"
+msgstr "Découpe Effectuée !"
-#: src/libslic3r/PrintConfig.cpp:659
-msgid "Ramming parameters"
-msgstr "Paramètres de l'expulsion"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:528
+msgid "Slicing…"
+msgstr "Découpe en cours…"
-#: src/libslic3r/PrintConfig.cpp:660
-msgid ""
-"This string is edited by RammingDialog and contains ramming specific "
-"parameters "
-msgstr ""
-"Cette chaine est éditée par RammingDialog et contient les paramètres "
-"spécifiques d'expulsion "
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1239
+msgid "Slow down if layer print time is below"
+msgstr "Ralentir si le temps d'impression de la couche est inférieur à"
-#: src/libslic3r/PrintConfig.cpp:667
-msgid "Filament unload time"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1250
+msgid "Small perimeters"
+msgstr "Périmètres fins"
-#: src/libslic3r/PrintConfig.cpp:668
-msgid ""
-"Time for the printer firmware (or the Multi Material Unit 2.0) to unload a "
-"filament during a tool change (when executing the T code). This time is "
-"added to the total print time by the G-code time estimator."
-msgstr ""
+#: xs/src/slic3r/GUI/GUI.cpp:417
+msgid "Snapshot name"
+msgstr "Nom du snapshot"
-#: src/libslic3r/PrintConfig.cpp:677
-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 ""
-"Entrez le diamètre de votre filament ici. Une bonne précision est requise, "
-"utilisez un pied à coulisse et calculez la moyenne de plusieurs mesures le "
-"long du filament."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:179
+msgid "solid infill"
+msgstr "remplissage plein"
-#: src/libslic3r/PrintConfig.cpp:685
-msgid "Density"
-msgstr "Densité"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1291
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1301
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:142
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:84
+msgid "Solid infill"
+msgstr "Remplissage plein"
-#: src/libslic3r/PrintConfig.cpp:686
-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 "
-"the length to volume. Better is to calculate the volume directly through "
-"displacement."
-msgstr ""
-"Entrez ici la densité de votre filament. Ceci est uniquement pour des "
-"informations statistiques. Un bon moyen d'obtenir cette valeur est de peser "
-"un morceau de filament d'une longueur connue et de calculer le rapport de sa "
-"longueur par son poids. Le mieux est de calculer le volume directement par "
-"déplacement."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1279
+msgid "Solid infill every"
+msgstr "Remplissage plein toutes les"
-#: src/libslic3r/PrintConfig.cpp:689
-msgid "g/cm³"
-msgstr "g/cm³"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1271
+msgid "Solid infill extruder"
+msgstr "Extrudeur pour le remplissage plein"
-#: src/libslic3r/PrintConfig.cpp:695
-msgid "Filament type"
-msgstr "Type de filament"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1262
+msgid "Solid infill threshold area"
+msgstr "Surface de seuil pour le remplissage plein"
-#: src/libslic3r/PrintConfig.cpp:696
-msgid "The filament material type for use in custom G-codes."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:330
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1314
+msgid "Solid layers"
+msgstr "Couches pleines"
-#: src/libslic3r/PrintConfig.cpp:712
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:470
msgid "Soluble material"
msgstr "Matériau soluble"
-#: src/libslic3r/PrintConfig.cpp:713
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:471
msgid "Soluble material is most likely used for a soluble support."
-msgstr ""
-"Il est probable qu'un matériau soluble soit utilisé pour un support soluble."
-
-#: src/libslic3r/PrintConfig.cpp:719
-msgid ""
-"Enter your filament cost per kg here. This is only for statistical "
-"information."
-msgstr ""
-"Entrez le coût par Kg de votre filament. Ceci est uniquement pour "
-"l'information statistique."
-
-#: src/libslic3r/PrintConfig.cpp:720
-msgid "money/kg"
-msgstr "€/kg"
+msgstr "Il est probable qu'un matériau soluble soit utilisé pour un support soluble."
-#: src/libslic3r/PrintConfig.cpp:729
-msgid "Fill angle"
-msgstr "Angle du remplissage"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:653
+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 output. The \"No extrusion\" flavor prevents Slic3r from exporting any extrusion value at all."
+msgstr "Certaines commandes G/M-code, dont le contrôle de température et autres, ne sont pas universelles. Paramétrez cette option avec le firmware de votre imprimante pour obtenir une sortie compatible. La version \"sans extrusion\" empêche Slic3r d'exporter toute valeur d'extrusion."
-#: src/libslic3r/PrintConfig.cpp:731
-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 ""
-"Angle de base par défaut pour l'orientation du remplissage. Des croisements "
-"seront appliqués à cette valeur. Les ponts seront remplis avec la meilleure "
-"direction que Slic3r peut détecter, ce réglage ne les affecteront donc pas."
-
-#: src/libslic3r/PrintConfig.cpp:744
-msgid "Fill density"
-msgstr "Densité du remplissage"
-
-#: src/libslic3r/PrintConfig.cpp:746
-msgid "Density of internal infill, expressed in the range 0% - 100%."
-msgstr "Densité du remplissage interne, exprimée en pourcentage de 0% à 100%."
-
-#: src/libslic3r/PrintConfig.cpp:782
-msgid "Fill pattern"
-msgstr "Motif de remplissage"
-
-#: src/libslic3r/PrintConfig.cpp:784
-msgid "Fill pattern for general low-density infill."
-msgstr "Motif pour les remplissages de faible densité."
-
-#: src/libslic3r/PrintConfig.cpp:801
-msgid "Grid"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1682
+msgid "Some printers or printer setups may have difficulties printing with a variable layer height. Enabled by default."
+msgstr "Certaines imprimantes ou certains réglages d'imprimante peuvent rencontrer des difficultés pour imprimer avec une hauteur de couche variable. Activé par défaut."
-#: src/libslic3r/PrintConfig.cpp:802
-msgid "Triangles"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:803
-msgid "Stars"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:804
-msgid "Cubic"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:805
-msgid "Line"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:807 src/libslic3r/PrintConfig.cpp:2023
-msgid "Honeycomb"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:808
-msgid "3D Honeycomb"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1490
+msgid "Spacing between interface lines. Set zero to get a solid interface."
+msgstr "Espacement entre les lignes d'interface. Mettez à zéro pour obtenir une interface pleine."
-#: src/libslic3r/PrintConfig.cpp:809
-msgid "Gyroid"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1526
+msgid "Spacing between support material lines."
+msgstr "Espacement entre les lignes des supports."
-#: src/libslic3r/PrintConfig.cpp:816 src/libslic3r/PrintConfig.cpp:826
-#: src/libslic3r/PrintConfig.cpp:835 src/libslic3r/PrintConfig.cpp:871
-msgid "First layer"
-msgstr "Première couche"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:398
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:118
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:278
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:635
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:747
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:979
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1201
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1251
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1302
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1625
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:71
+msgid "Speed"
+msgstr "Vitesse"
-#: src/libslic3r/PrintConfig.cpp:817
-msgid ""
-"This is the acceleration your printer will use for first layer. Set zero to "
-"disable acceleration control for first layer."
-msgstr ""
-"L'accélération que l'imprimante utilisera pour la première couche. Régler "
-"sur zéro afin de désactiver le contrôle de l'accélération pour la première "
-"couche."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1203
+msgid "Speed (baud) of USB/serial port for printer connection."
+msgstr "Vitesse (baud) du port USB/série pour la connexion à l'imprimante."
-#: src/libslic3r/PrintConfig.cpp:827
-msgid ""
-"Heated build plate temperature for the first layer. Set this to zero to "
-"disable bed temperature control commands in the output."
-msgstr ""
-"Température du plateau chauffant pour la première couche. Mettez ceci à zéro "
-"pour désactiver les commandes de contrôle de température du plateau dans la "
-"sortie."
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:336
+msgid "Speed (mm/s)"
+msgstr "Vitesse (mm/s)"
-#: src/libslic3r/PrintConfig.cpp:837
-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 "
-"expressed as percentage (for example 120%) it will be computed over first "
-"layer height. If set to zero, it will use the default extrusion width."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour la première couche. Vous pouvez procéder ainsi pour "
-"obtenir des extrudats plus épais afin d’avoir une meilleure adhérence. Si la "
-"valeur est exprimée en pourcentage (par exemple : 120%), elle sera calculée "
-"par rapport à la hauteur de la première couche. Si elle est réglée sur zéro, "
-"elle utilisera la largeur d’extrusion par défaut."
-
-#: src/libslic3r/PrintConfig.cpp:848
-msgid "First layer height"
-msgstr "Hauteur de la première couche"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:636
+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 "Vitesse pour combler de petits interstices avec de courts mouvements en zigzag. Gardez un réglage relativement lent afin d'éviter les problèmes de vibration et de résonance. Réglez sur zéro pour désactiver le remplissage d'interstices."
-#: src/libslic3r/PrintConfig.cpp:850
-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 "
-"plates. This can be expressed as an absolute value or as a percentage (for "
-"example: 150%) over the default layer height."
-msgstr ""
-"Lors d'une impression avec de très faibles épaisseurs de couche, vous pouvez "
-"choisir d'imprimer une première couche plus épaisse pour améliorer "
-"l'adhérence et la tolérance aux plateaux imparfaits. Ce réglage peut être "
-"exprimé comme une valeur absolue ou un pourcentage (par exemple 150%) par "
-"rapport à l'épaisseur de couche par défaut."
-
-#: src/libslic3r/PrintConfig.cpp:854 src/libslic3r/PrintConfig.cpp:1003
-#: src/libslic3r/PrintConfig.cpp:1884
-msgid "mm or %"
-msgstr "mm ou %"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:411
+msgid "Speed for non-print moves"
+msgstr "Vitesse pour les déplacements sans impression"
-#: src/libslic3r/PrintConfig.cpp:860
-msgid "First layer speed"
-msgstr "Vitesse de la première couche"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:980
+msgid "Speed for perimeters (contours, aka vertical shells). Set to zero for auto."
+msgstr "Vitesse pour les périmètres (contours, parois verticales). Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:861
-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 ""
-"Si exprimée avec une valeur absolue en mm/s, cette vitesse sera appliquée à "
-"tous les déplacements d'impression de la première couche, quel que soit leur "
-"type. Si exprimée comme un pourcentage (par exemple 40%), cela modulera la "
-"vitesse par défaut."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:399
+msgid "Speed for print moves"
+msgstr "Vitesse pour les déplacements d'impression"
-#: src/libslic3r/PrintConfig.cpp:872
-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 ""
-"Température de l’extrudeur pour la première couche. Si vous voulez contrôler "
-"manuellement la température au cours de l’impression, mettez à zéro pour "
-"désactiver les commandes de contrôle de température dans le fichier de "
-"sortie."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:119
+msgid "Speed for printing bridges."
+msgstr "Vitesse d'impression des ponts."
-#: src/libslic3r/PrintConfig.cpp:882
-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 ""
-"Vitesse pour combler de petits interstices avec de courts mouvements en "
-"zigzag. Gardez un réglage relativement lent afin d'éviter les problèmes de "
-"vibration et de résonance. Réglez sur zéro pour désactiver le remplissage "
-"d'interstices."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1303
+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 "Vitesse pour imprimer des zones pleines (supérieures/inférieures/parois horizontales internes). Peut être exprimée en pourcentage (par exemple: 80%) de la vitesse de remplissage par défaut susmentionnée. Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:890
-msgid "Verbose G-code"
-msgstr "G-code commenté"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1499
+msgid "Speed for printing support material interface layers. If expressed as percentage (for example 50%) it will be calculated over support material speed."
+msgstr "Vitesse d'impression des couches d'interface des supports. Si exprimée en pourcentage (par exemple 50%), elle sera calculée à partir de la vitesse d'impression des supports."
-#: src/libslic3r/PrintConfig.cpp:891
-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 ""
-"Activez ceci pour obtenir un fichier G-code commenté, avec chaque ligne "
-"expliquée par un texte descriptif. Si vous imprimez depuis une carte SD, le "
-"poids supplémentaire du fichier pourrait ralentir le firmware de votre "
-"imprimante."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1535
+msgid "Speed for printing support material."
+msgstr "Vitesse d'impression du support."
-#: src/libslic3r/PrintConfig.cpp:899
-msgid "G-code flavor"
-msgstr "Version du G-code"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:748
+msgid "Speed for printing the internal fill. Set to zero for auto."
+msgstr "Vitesse pour imprimer le remplissage interne. Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:900
-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 "
-"output. The \"No extrusion\" flavor prevents Slic3r from exporting any "
-"extrusion value at all."
-msgstr ""
-"Certaines commandes G/M-code, dont le contrôle de température et autres, ne "
-"sont pas universelles. Paramétrez cette option avec le firmware de votre "
-"imprimante pour obtenir une sortie compatible. La version \"sans extrusion\" "
-"empêche Slic3r d'exporter toute valeur d'extrusion."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1626
+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 slow down this to get a nicer surface finish. This can be expressed as a percentage (for example: 80%) over the solid infill speed above. Set to zero for auto."
+msgstr "Vitesse pour imprimer les couches pleines du dessus (ne s'applique qu'aux couches externes les plus hautes et pas aux couches pleines internes). Vous voudrez peut-être abaisser cette vitesse afin d'avoir une finition de surface plus nette. Peut être exprimé en pourcentage (par exemple: 80%) de la vitesse de remplissage pleine susmentionnée. Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:924
-msgid "No extrusion"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1648
+msgid "Speed for travel moves (jumps between distant extrusion points)."
+msgstr "Vitesse pour les déplacements (trajet entre deux points d'extrusion distants)."
-#: src/libslic3r/PrintConfig.cpp:929
-msgid "High extruder current on filament swap"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:460
+msgid "Speed used for loading the filament on the wipe tower. "
+msgstr "Vitesse utilisée pour charger le filament sur la tour de nettoyage. "
-#: src/libslic3r/PrintConfig.cpp:930
-msgid ""
-"It may be beneficial to increase the extruder motor current during the "
-"filament exchange sequence to allow for rapid ramming feed rates and to "
-"overcome resistance when loading a filament with an ugly shaped tip."
-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 "Vitesse utilisée pour décharger le filament sur la tour de nettoyage (n'affecte pas l'étape initiale de déchargement juste après l'expulsion). "
-#: src/libslic3r/PrintConfig.cpp:939
-msgid ""
-"This is the acceleration your printer will use for infill. Set zero to "
-"disable acceleration control for infill."
-msgstr ""
-"Il s'agit de l'accélération que votre imprimante utilisera pour le "
-"remplissage. Régler sur zéro afin de désactiver le contrôle de "
-"l'accélération pour le remplissage."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1322
+msgid "Spiral vase"
+msgstr "Mode vase (spirale)"
-#: src/libslic3r/PrintConfig.cpp:948
-msgid "Combine infill every"
-msgstr "Combiner le remplissage toutes les"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:540
+msgid "Spiral Vase"
+msgstr "Mode vase (spirale)"
-#: src/libslic3r/PrintConfig.cpp:950
-msgid ""
-"This feature allows to combine infill and speed up your print by extruding "
-"thicker infill layers while preserving thin perimeters, thus accuracy."
-msgstr ""
-"Cette fonction permet de combiner le remplissage afin d'accélérer "
-"l'impression en extrudant des couches de remplissage plus épaisses tout en "
-"conservant des périmètres fins, avec plus de précision."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:188
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:204
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2099
+msgid "Split"
+msgstr "Scinder"
-#: src/libslic3r/PrintConfig.cpp:954
-msgid "Combine infill every n layers"
-msgstr "Combiner le remplissage toutes les n couches"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2099
+msgid "Split the selected object into individual parts"
+msgstr "Scinder l'objet sélectionné en pièces individuelles"
-#: src/libslic3r/PrintConfig.cpp:960
-msgid "Infill extruder"
-msgstr "Extrudeur pour le remplissage"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:847
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1120
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1342
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1357
+msgid "Start G-code"
+msgstr "G-code de début"
-#: src/libslic3r/PrintConfig.cpp:962
-msgid "The extruder to use when printing infill."
-msgstr "L'extrudeur à utiliser pour imprimer le remplissage."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:291
+msgid "Start new slicing process"
+msgstr "Démarrer un nouveau processus de découpe"
-#: src/libslic3r/PrintConfig.cpp:971
-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 "
-"nozzle diameter will be used. You may want to use fatter extrudates to speed "
-"up the infill and make your parts stronger. If expressed as percentage (for "
-"example 90%) it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour le remplissage. Si la valeur reste sur zéro, la "
-"largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur "
-"1.125 x diamètre de la buse sera utilisée. Vous voudrez peut-être utiliser "
-"des extrudats plus épais pour accélérer le remplissage et rendre vos pièces "
-"plus solides. Si la valeur est exprimée en pourcentage (par exemple : 90%), "
-"elle sera calculée par rapport à la hauteur de couche."
-
-#: src/libslic3r/PrintConfig.cpp:981
-msgid "Infill before perimeters"
-msgstr "Remplissage avant les périmètres"
+#: xs/src/slic3r/GUI/FirmwareDialog.cpp:296
+msgid "Status:"
+msgstr "État :"
-#: src/libslic3r/PrintConfig.cpp:982
-msgid ""
-"This option will switch the print order of perimeters and infill, making the "
-"latter first."
-msgstr ""
-"Cette option inverse l'ordre d'impression des périmètres et du remplissage, "
-"ce dernier étant alors imprimé en premier."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1539
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1581
+msgid "STL file exported to "
+msgstr "Fichier STL exporté vers "
-#: src/libslic3r/PrintConfig.cpp:988
-msgid "Only infill where needed"
-msgstr "Remplissage seulement où cela est nécessaire"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1017
+msgid "Success!"
+msgstr "Réussi !"
-#: src/libslic3r/PrintConfig.cpp:990
-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 ""
-"Cette option limitera le remplissage aux zones nécessaires pour soutenir les "
-"couches supérieures (cela agira comme un support interne). Si activé, la "
-"génération du G-Code prendra plus de temps à cause des calculs "
-"supplémentaires requis."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:198
+msgid "support"
+msgstr "support"
-#: src/libslic3r/PrintConfig.cpp:998
-msgid "Infill/perimeters overlap"
-msgstr "Chevauchement remplissage/périmètres"
+#: xs/src/slic3r/GUI/GUI.cpp:879
+msgid "Support"
+msgstr "Support"
-#: src/libslic3r/PrintConfig.cpp:1000
-msgid ""
-"This setting applies an additional overlap between infill and perimeters for "
-"better bonding. Theoretically this shouldn't be needed, but backlash might "
-"cause gaps. If expressed as percentage (example: 15%) it is calculated over "
-"perimeter extrusion width."
-msgstr ""
-"Cette option applique un chevauchement supplémentaire entre les périmètres "
-"et le remplissage pour une meilleur fusion. En théorie, cela ne devrait pas "
-"être nécessaire, mais le jeu mécanique peut générer des espacements. Si "
-"exprimé en pourcentage (par exemple 15%), la valeur sera calculée en "
-"fonction de la largeur d'extrusion du périmètre."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:620
+msgid "Support Generator"
+msgstr "Générateur de Support"
-#: src/libslic3r/PrintConfig.cpp:1012
-msgid "Speed for printing the internal fill. Set to zero for auto."
-msgstr ""
-"Vitesse pour imprimer le remplissage interne. Réglez sur zéro pour un "
-"ajustement automatique."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:208
+msgid "support interface"
+msgstr "interface du support"
-#: src/libslic3r/PrintConfig.cpp:1020
-msgid "Inherits profile"
-msgstr "Hérite du profil"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:374
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:375
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:191
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1030
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1380
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1387
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1399
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1409
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1417
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1432
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1453
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1464
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1480
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1489
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1498
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1509
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1525
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1533
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1534
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1543
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1551
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1565
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:147
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:89
+msgid "Support material"
+msgstr "Support"
-#: src/libslic3r/PrintConfig.cpp:1021
-msgid "Name of the profile, from which this profile inherits."
-msgstr "Nom du profil, duquel hérite ce profil."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1497
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:148
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:90
+msgid "Support material interface"
+msgstr "Interface des supports"
-#: src/libslic3r/PrintConfig.cpp:1032
-msgid "Interface shells"
-msgstr "Coques d'interface"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1552
+msgid "Support material will not be generated for overhangs whose slope angle (90° = vertical) is above the given threshold. In other words, this value represent the most horizontal slope (measured from the horizontal plane) that you can print without support material. Set to zero for automatic detection (recommended)."
+msgstr "Le support ne sera pas généré pour les surplombs dont l'inclinaison (90° = vertical) dépasse le seuil défini. Autrement dit, cette valeur représente l'inclinaison horizontale maximum (mesurée à partir du plan horizontal) que vous pouvez imprimer sans support. Réglez sur zéro pour une détection automatique (recommandé)."
-#: src/libslic3r/PrintConfig.cpp:1033
-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 ""
-"Force la génération de coques solides entre des volumes/matériaux adjacents. "
-"Utile pour des impressions multi-extrudeurs avec des matériaux translucides "
-"ou avec un support manuel soluble."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1470
+msgid "Support material/raft interface extruder"
+msgstr "Extrudeur pour l'interface des supports/du radeau"
-#: src/libslic3r/PrintConfig.cpp:1043
-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 "
-"use placeholder variables for all Slic3r settings as well as [layer_num] and "
-"[layer_z]."
-msgstr ""
-"Ce code personnalisé est inséré à chaque changement de couche, juste après "
-"le mouvement Z et avant le déplacement de l'extrudeur au point de départ de "
-"la couche suivante. Notez que vous pouvez utiliser des variables génériques "
-"pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1444
+msgid "Support material/raft/skirt extruder"
+msgstr "Extrudeur pour support/tapis/clôture"
-#: src/libslic3r/PrintConfig.cpp:1054
-msgid "Supports remaining times"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1408
+msgid "Support on build plate only"
+msgstr "Support sur le plateau uniquement"
-#: src/libslic3r/PrintConfig.cpp:1055
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:617
msgid ""
-"Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute "
-"intervals into the G-code to let the firmware show accurate remaining time. "
-"As of now only the Prusa i3 MK3 firmware recognizes M73. Also the i3 MK3 "
-"firmware supports M73 Qxx Sxx for the silent mode."
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1063
-msgid "Supports silent mode"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1064
-msgid "Set silent mode for the G-code flavor"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1087
-msgid "Maximum feedrate %1%"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1089
-msgid "Maximum feedrate of the %1% axis"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1097
-msgid "Maximum acceleration %1%"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1099
-msgid "Maximum acceleration of the %1% axis"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1107
-msgid "Maximum jerk %1%"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1109
-msgid "Maximum jerk of the %1% axis"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1120 src/libslic3r/PrintConfig.cpp:1122
-msgid "Minimum feedrate when extruding"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1131 src/libslic3r/PrintConfig.cpp:1133
-msgid "Minimum travel feedrate"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1142 src/libslic3r/PrintConfig.cpp:1144
-msgid "Maximum acceleration when extruding"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1153 src/libslic3r/PrintConfig.cpp:1155
-msgid "Maximum acceleration when retracting"
+"Supports work better, if the following feature is enabled:\n"
+"- Detect bridging perimeters\n"
+"\n"
+"Shall I adjust those settings for supports?"
msgstr ""
+"Les supports sont plus efficaces, si la fonctionnalité suivante est activée :\n"
+"-Détection des périmètres de pont\n"
+"\n"
+"Voulez-vous que que je modifie les réglages des supports ?"
-#: src/libslic3r/PrintConfig.cpp:1163 src/libslic3r/PrintConfig.cpp:1173
-msgid "Max"
-msgstr "Maximum"
-
-#: src/libslic3r/PrintConfig.cpp:1164
-msgid "This setting represents the maximum speed of your fan."
-msgstr "Cette option représente la vitesse maximum du ventilateur."
-
-#: src/libslic3r/PrintConfig.cpp:1174
-#, 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 "
-"layer height is 75% of the extrusion width to achieve reasonable inter-layer "
-"adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter."
-msgstr ""
-"Ceci est la hauteur de couche imprimable maximum pour cet extrudeur, "
-"utilisée pour plafonner la hauteur de couche variable et la hauteur de "
-"couche des supports. La hauteur de couche maximum recommandée est 75% de la "
-"largeur d'extrusion afin d'obtenir une adhésion inter-couches correcte. Si "
-"réglée sur 0, la hauteur de couche est limitée à 75% du diamètre de la buse."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:59
+msgid "Suppress \" - default - \" presets"
+msgstr "Supprimer les préréglages \" - par défaut - \""
-#: src/libslic3r/PrintConfig.cpp:1185
-msgid "Max print speed"
-msgstr "Vitesse d'impression maximale"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:61
+msgid "Suppress \" - default - \" presets in the Print / Filament / Printer selections once there are any other valid presets available."
+msgstr "Supprimer les préréglages \" - par défaut - \" dans les choix Impression / Filament / Imprimante une fois qu'il y a d'autres préréglages valides disponibles."
-#: src/libslic3r/PrintConfig.cpp:1186
-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 ""
-"Lorsque vous réglez les autres vitesses à 0, Slic3r calculera "
-"automatiquement la vitesse optimale de façon à garder une pression constante "
-"dans l'extrudeur. Cette fonction expérimentale est utilisée pour régler la "
-"plus haute vitesse que vous souhaitez autoriser."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:514
+msgid "SVG"
+msgstr "SVG"
-#: src/libslic3r/PrintConfig.cpp:1197
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:325
msgid ""
-"This experimental setting is used to set the maximum volumetric speed your "
-"extruder supports."
+"Switching to simple settings will discard changes done in the advanced mode!\n"
+"\n"
+"Do you want to proceed?"
msgstr ""
-"Ce réglage expérimental est utilisé pour paramétrer la vitesse volumétrique "
-"maximum tolérée par votre extrudeur."
+"Basculer vers les réglages simples annulera les changements effectués en mode avancé !\n"
+"\n"
+"Voulez-vous continuer ?"
-#: src/libslic3r/PrintConfig.cpp:1206
-msgid "Max volumetric slope positive"
-msgstr "Pente volumétrique positive maximum"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1544
+msgid "Synchronize support layers with the object print layers. This is useful with multi-material printers, where the extruder switch is expensive."
+msgstr "Synchroniser les couches du support avec les couches d'impression de l'objet. Cela est utile pour les imprimantes multi-matériaux, pour lesquelles le changement d'extrudeur est onéreux."
-#: src/libslic3r/PrintConfig.cpp:1207 src/libslic3r/PrintConfig.cpp:1219
-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 "
-"of 1.8 mm³/s (0.45mm extrusion width, 0.2mm extrusion height, feedrate 20 mm/"
-"s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds."
-msgstr ""
-"Ce réglage expérimental sert à limiter la vitesse de changement dans le flux "
-"d'extrusion. Une valeur de 1.8 mm³/s² garantit qu'un changement de flux "
-"d'extrusion de 1.8 mm³/s (largeur d'extrusion 0.45mm, hauteur d'extrusion "
-"0.2mm, alimentation 20 mm/s) à 5.4 mm³/s (alimentation 60 mm/s) prendra au "
-"moins 2 secondes."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1542
+msgid "Synchronize with object layers"
+msgstr "Synchroniser avec les couches de l'objet"
-#: src/libslic3r/PrintConfig.cpp:1211 src/libslic3r/PrintConfig.cpp:1223
-msgid "mm³/s²"
-msgstr "mm³/s²"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:402
+msgid "System Info"
+msgstr "Informations sur le Système"
-#: src/libslic3r/PrintConfig.cpp:1218
-msgid "Max volumetric slope negative"
-msgstr "Pente volumétrique négative maximum"
+#: 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 "Préréglages système"
-#: src/libslic3r/PrintConfig.cpp:1230 src/libslic3r/PrintConfig.cpp:1240
-msgid "Min"
-msgstr "Minimum"
+#: xs/src/slic3r/GUI/GUI.cpp:403
+msgid "Take Configuration Snapshot"
+msgstr "Prendre un snapshot de la configuration"
-#: src/libslic3r/PrintConfig.cpp:1231
-msgid "This setting represents the minimum PWM your fan needs to work."
-msgstr ""
-"Cette option représente le PWM minimum dont votre ventilateur a besoin pour "
-"tourner."
+#: xs/src/slic3r/GUI/GUI.cpp:417
+msgid "Taking configuration snapshot"
+msgstr "Snapshot de la configuration en cours"
-#: src/libslic3r/PrintConfig.cpp:1241
-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 ""
-"Cette valeur est la hauteur de couche imprimable minimum pour cet extrudeur "
-"et elle limite la résolution pour la hauteur de couche variable. Les valeurs "
-"type se situent entre 0.05 mm et 0.1 mm."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1576
+msgid "Temperature"
+msgstr "Température"
-#: src/libslic3r/PrintConfig.cpp:1250
-msgid "Min print speed"
-msgstr "Vitesse d'impression minimale"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:794
+msgid "Temperature "
+msgstr "Température "
-#: src/libslic3r/PrintConfig.cpp:1251
-msgid "Slic3r will not scale speed down below this speed."
-msgstr "Slic3r ne descendra pas en-dessous de cette vitesse."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1333
+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 "Différence de température devant être appliquée quand un extrudeur n'est pas actif. Permet la génération d'une clôture complète \"sacrificielle\" sur lequel les buses sont nettoyées régulièrement."
-#: src/libslic3r/PrintConfig.cpp:1259
-msgid "Minimal filament extrusion length"
-msgstr "Longueur minimale d'extrusion de filament"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1332
+msgid "Temperature variation"
+msgstr "Variation de température"
-#: src/libslic3r/PrintConfig.cpp:1260
-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 ""
-"Nombre minimum de contours à générer afin de consommer la quantité de "
-"filament spécifiée sur la couche inférieure. Pour les machines multi-"
-"extrudeurs, ce minimum s'applique à chaque extrudeur."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:463
+msgid "Temperatures"
+msgstr "Températures"
-#: src/libslic3r/PrintConfig.cpp:1270
-msgid "Configuration notes"
-msgstr "Notes de configuration"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1004
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1072
+msgid "Test"
+msgstr "Test"
-#: src/libslic3r/PrintConfig.cpp:1271
-msgid ""
-"You can put here your personal notes. This text will be added to the G-code "
-"header comments."
+# Used in context: _("The ") + str_fill_pattern + _(" infill pattern is not supposed to work at 100% density.\n")
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:662
+msgid "The "
msgstr ""
-"Vous pouvez inscrire ici vos commentaires personnels. Ce texte sera ajouté "
-"au commentaire en entête du G-Code."
-#: src/libslic3r/PrintConfig.cpp:1281
-msgid "Nozzle diameter"
-msgstr "Diamètre de la buse"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:309
+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 "L'extrudeur à utiliser (à moins que d'autres réglages d'extrudeur plus spécifiques soient spécifiés). Cette valeur se substitue aux extrudeurs de périmètre et de remplissage, mais pas aux extrudeurs de support."
-#: src/libslic3r/PrintConfig.cpp:1282
-msgid ""
-"This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)"
-msgstr ""
-"Il s'agit du diamètre de la buse de votre extrudeur (par exemple: 0.5, 0.35, "
-"etc.)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:703
+msgid "The extruder to use when printing infill."
+msgstr "L'extrudeur à utiliser pour imprimer le remplissage."
-#: src/libslic3r/PrintConfig.cpp:1288
-msgid "Host Type"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:959
+msgid "The extruder to use when printing perimeters and brim. First extruder is 1."
+msgstr "L'extrudeur à utiliser pour imprimer les périmètres et la jupe. Le premier extrudeur a le numéro 1."
-#: src/libslic3r/PrintConfig.cpp:1289
-msgid ""
-"Slic3r can upload G-code files to a printer host. This field must contain "
-"the kind of the host."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1273
+msgid "The extruder to use when printing solid infill."
+msgstr "L'extrudeur à utiliser pour imprimer les remplissages plein."
-#: src/libslic3r/PrintConfig.cpp:1301
-msgid "API Key / Password"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1472
+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 "L'extrudeur à utiliser pour imprimer les intercalaires du support (1+,0 pour utiliser l'extrudeur actuel et limiter les changements d'outil). Cela affecte également le raft."
-#: src/libslic3r/PrintConfig.cpp:1302
-msgid ""
-"Slic3r can upload G-code files to a printer host. This field should contain "
-"the API Key or the password required for authentication."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1446
+msgid "The extruder to use when printing support material, raft and skirt (1+, 0 to use the current extruder to minimize tool changes)."
+msgstr "L'extrudeur à utiliser pour imprimer des supports, du tapis ou des clôtures (1+,0 pour utiliser l'extrudeur actuel et limiter les changements d'outil)."
-#: src/libslic3r/PrintConfig.cpp:1317
-msgid "Hostname, IP or URL"
-msgstr "Nom d'hôte, IP ou URL"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:209
+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 "La première couche sera réduite sur le plan XY selon la valeur configurée afin de compenser l'écrasement de la première couche également connu sous le nom d'effet Pied d'Éléphant."
-#: src/libslic3r/PrintConfig.cpp:1318
-msgid ""
-"Slic3r can upload G-code files to a printer host. This field should contain "
-"the hostname, IP address or URL of the printer host instance."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1734
+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 sizes."
+msgstr "L'objet sera agrandi/réduit sur les plans XY selon la valeur indiquée (négatif = réduit, positif = agrandi). Ce réglage peut être utile pour un réglage fin des tailles de trous."
-#: src/libslic3r/PrintConfig.cpp:1325
-msgid "Only retract when crossing perimeters"
-msgstr "Rétracter uniquement lors du franchissement de périmètres"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1031
+msgid "The object will be raised by this number of layers, and support material will be generated under it."
+msgstr "L'objet sera surélevé de ce nombre de couches, et du support sera généré en dessous."
-#: src/libslic3r/PrintConfig.cpp:1326
-msgid ""
-"Disables retraction when the travel path does not exceed the upper layer's "
-"perimeters (and thus any ooze will be probably invisible)."
-msgstr ""
-"Désactiver la rétraction lorsque le chemin de déplacement ne franchit pas "
-"les périmètres des couches supérieures (et donc les coulures seront "
-"probablement invisibles)."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1374
+msgid "The printer multiplexes filaments into a single hot end."
+msgstr "L'imprimante multiplexe les filaments vers une seule tête d'extrusion."
-#: src/libslic3r/PrintConfig.cpp:1334
-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 ""
-"Cette option abaissera la température des extrudeurs inutilisés pour "
-"prévenir le oozing (suintement). Cela active automatiquement la génération "
-"d'une grande jupe et le déplacement des extrudeurs hors de cette jupe lors "
-"des changements de température."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:324
+msgid "The selected file contains no geometry."
+msgstr "Le fichier sélectionné ne contient aucune géométrie."
-#: src/libslic3r/PrintConfig.cpp:1342
-msgid "Output filename format"
-msgstr "Format du nom de fichier de sortie"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:328
+msgid "The selected file contains several disjoint areas. This is not supported."
+msgstr "Le fichier sélectionné contient plusieurs zones disjointes. Cela n'est pas utilisable."
-#: src/libslic3r/PrintConfig.cpp:1343
-msgid ""
-"You can use all configuration options as variables inside this template. For "
-"example: [layer_height], [fill_density] etc. You can also use [timestamp], "
-"[year], [month], [day], [hour], [minute], [second], [version], "
-"[input_filename], [input_filename_base]."
-msgstr ""
-"Vous pouvez utiliser toutes les options de configuration comme variables "
-"dans ce modèle. Par exemple : [layer_height], [fill_density] etc. Vous "
-"pouvez aussi utiliser [timestamp], [year], [month], [day], [hour], [minute], "
-"[second], [version], [input_filename], [input_filename_base]."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1112
+msgid "The selected object can't be split because it contains more than one volume/material."
+msgstr "L'objet sélectionné ne peut être scindé car il contient plus d'un volume/matériau."
-#: src/libslic3r/PrintConfig.cpp:1353
-msgid "Detect bridging perimeters"
-msgstr "Détecter les périmètres faisant des ponts"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1121
+msgid "The selected object couldn't be split because it contains only one part."
+msgstr "L'objet sélectionné n'a pu être scindé car il ne contient qu'une seule pièce."
-#: src/libslic3r/PrintConfig.cpp:1355
-msgid ""
-"Experimental option to adjust flow for overhangs (bridge flow will be used), "
-"to apply bridge speed to them and enable fan."
-msgstr ""
-"Option expérimentale qui ajuste le flux pour les surplombs (le flux pour les "
-"ponts sera utilisé), leur applique la vitesse pour les ponts et active le "
-"ventilateur."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1144
+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 "La vitesse de chargement d'un filament dans l'extrudeur après une rétractation (ne s'applique qu'au moteur de l'extrudeur). Si cette valeur reste sur zéro, la vitesse de rétraction est utilisée."
-#: src/libslic3r/PrintConfig.cpp:1362
-msgid "Filament parking position"
-msgstr "Position d'attente du filament"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1136
+msgid "The speed for retractions (it only applies to the extruder motor)."
+msgstr "La vitesse des rétractations (ne s'applique qu'au moteur de l'extrudeur)."
-#: src/libslic3r/PrintConfig.cpp:1363
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:533
+#, no-c-format
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 ""
-"Distance entre la pointe de l'extrudeur et la position où le filament est "
-"positionné en attente lorsqu'il est déchargé. Cela doit correspondre à la "
-"valeur dans le firmware de l'imprimante. "
-
-#: src/libslic3r/PrintConfig.cpp:1372
-msgid "Extra loading distance"
+"The Spiral Vase mode requires:\n"
+"- one perimeter\n"
+"- no top solid layers\n"
+"- 0% fill density\n"
+"- no support material\n"
+"- no ensure_vertical_shell_thickness\n"
+"\n"
+"Shall I adjust those settings in order to enable Spiral Vase?"
msgstr ""
+"Le mode Vase requiert :\n"
+"-Un seul périmètre\n"
+"-Pas de couches pleines sur le dessus\n"
+"-Une densité de remplissage de 0%\n"
+"-Pas de supports\n"
+"-'S'assurer de l'épaisseur de la coque verticale' décochée\n"
+"\n"
+"Voulez-vous que je modifie ces réglages afin d'activer le mode Vase?"
-#: src/libslic3r/PrintConfig.cpp:1373
-msgid ""
-"When set to zero, the distance the filament is moved from parking position "
-"during load is exactly the same as it was moved back during unload. When "
-"positive, it is loaded further, if negative, the loading move is shorter "
-"than unloading. "
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1560
+msgid "The supplied name is empty. It can't be saved."
+msgstr "Le nom proposé est vide. Sauvegarde impossible."
-#: src/libslic3r/PrintConfig.cpp:1382 src/libslic3r/PrintConfig.cpp:1402
-#: src/libslic3r/PrintConfig.cpp:1415 src/libslic3r/PrintConfig.cpp:1425
-msgid "Perimeters"
-msgstr "Périmètres"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1788
+msgid "The supplied name is not available."
+msgstr "Le nom proposé n'est pas disponible."
-#: src/libslic3r/PrintConfig.cpp:1383
-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 ""
-"L'accélération que votre imprimante utilisera pour les périmètres. Une "
-"valeur élevée comme 9000 donne généralement de bons résultats si votre "
-"matériel le permet. Régler sur zéro afin de désactiver le contrôle de "
-"l'accélération pour les périmètres."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1785
+msgid "The supplied name is not valid; the following characters are not allowed:"
+msgstr "Le nom proposé n'est pas valide ; les caractères suivants ne sont pas autorisés :"
-#: src/libslic3r/PrintConfig.cpp:1392
-msgid "Perimeter extruder"
-msgstr "Extrudeur pour les périmètres"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1418
+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 "Distance verticale entre l'objet et l'intercalaire du support. Régler cette valeur sur zéro empêchera Slic3r d'utiliser la vitesse et le débit des ponts pour la première couche de l'objet."
-#: src/libslic3r/PrintConfig.cpp:1394
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1312
msgid ""
-"The extruder to use when printing perimeters and brim. First extruder is 1."
+"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 ""
-"L'extrudeur à utiliser pour imprimer les périmètres et la bordure. Le "
-"premier extrudeur a le numéro 1."
+"L'option Nettoyage n'est pas disponible lorsque vous utilisez le mode Rétractation du Firmware.\n"
+"\n"
+"Voulez-vous que je la désactive pour permettre la Rétractation du Firmware ?"
-#: src/libslic3r/PrintConfig.cpp:1404
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:581
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 "
-"left zero, default extrusion width will be used if set, otherwise 1.125 x "
-"nozzle diameter will be used. If expressed as percentage (for example 200%) "
-"it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement une "
-"largeur d’extrusion pour les périmètres. Vous voudrez peut-être utiliser des "
-"extrudats plus fin pour obtenir des surfaces plus nettes. Si la valeur reste "
-"sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon "
-"la valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est "
-"exprimée en pourcentage (par exemple : 200%), elle sera calculée par rapport "
-"à la hauteur de couche."
-
-#: src/libslic3r/PrintConfig.cpp:1417
-msgid ""
-"Speed for perimeters (contours, aka vertical shells). Set to zero for auto."
+"The Wipe Tower currently supports the non-soluble supports only\n"
+"if they are printed with the current extruder without triggering a tool change.\n"
+"(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n"
+"\n"
+"Shall I adjust those settings in order to enable the Wipe Tower?"
msgstr ""
-"Vitesse pour les périmètres (contours, parois verticales). Réglez sur zéro "
-"pour un ajustement automatique."
+"A l'heure actuelle la Tour de Nettoyage ne tolère les supports non-solubles \n"
+"que s'ils sont imprimés avec l'extrudeur en cours d'utilisation sans déclencher un changement d'outil.\n"
+"(support_material_extruder de même que support_material_interface_extruder doivent être réglés sur 0).\n"
+"\n"
+"Voulez-vous que je modifie ces réglages pour activer la Tour de Nettoyage ?"
-#: src/libslic3r/PrintConfig.cpp:1427
-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 "
-"surfaces which benefit from a higher number of perimeters if the Extra "
-"Perimeters option is enabled."
-msgstr ""
-"Cette option définit le nombre de périmètres à générer pour chaque couche. "
-"Notez que Slic3r peut augmenter cette valeur automatiquement si il détecte "
-"une surface inclinée qui nécessite un plus grand nombre de périmètres, si "
-"l'option \"Périmètres supplémentaires\" est sélectionnée."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:60
+msgid "This code is inserted between objects when using sequential printing. By 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."
+msgstr "Ce code est inséré entre des objets lorsque vous utilisez l'impression séquentielle. Par défaut la température de l'extrudeur et du plateau est réinitialisée et utilise la commande sans-attente ; toutefois si des commandes M104, M109, M140 ou M190 sont détectées dans ce code personnalisé, Slic3r n'ajoutera pas de commandes de température. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r, donc vous pouvez entrer une commande \"M109S[first_layer_temperature]\" où vous le souhaitez."
-#: src/libslic3r/PrintConfig.cpp:1431
-msgid "(minimum)"
-msgstr "(minimum)"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:767
+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 use placeholder variables for all Slic3r settings as well as [layer_num] and [layer_z]."
+msgstr "Ce code personnalisé est inséré à chaque changement de couche, juste après le mouvement Z et avant le déplacement de l'extrudeur au point de départ de la couche suivante. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]."
-#: src/libslic3r/PrintConfig.cpp:1439
-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. "
-"Scripts will be passed the absolute path to the G-code file as the first "
-"argument, and they can access the Slic3r config settings by reading "
-"environment variables."
-msgstr ""
-"Si vous voulez traiter le G-code de sortie à l'aide de scripts "
-"personnalisés, listez simplement leurs chemins absolus ici. Séparez les "
-"divers scripts avec un point virgule. Les scripts vont recevoir en premier "
-"argument le chemin absolu du fichier G-code, et ils peuvent accéder aux "
-"réglages de configuration de Slic3r en lisant des variables d'environnement."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:49
+msgid "This custom code is inserted at every layer change, right before the Z move. Note that you can use placeholder variables for all Slic3r settings as well as [layer_num] and [layer_z]."
+msgstr "Ce code personnalisé est inséré à chaque changement de couche, juste avant le mouvement en Z. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]."
-#: src/libslic3r/PrintConfig.cpp:1452
-msgid "Printer type"
-msgstr "Type d'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1603
+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 "Ce code personnalisé est inséré juste avant chaque changement d'extrudeur. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r de même que [previous_extruder] et [next_extruder]."
-#: src/libslic3r/PrintConfig.cpp:1453
-msgid "Type of the printer."
-msgstr "Type d'imprimante."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:228
+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 Slic3r settings. If you have multiple extruders, the gcode is processed in extruder order."
+msgstr "Cette procédure de fin est insérée à la fin du fichier de sortie, avant le gcode de fin de l'imprimante. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r. Si vous avez plusieurs extrudeurs, le gcode sera traité suivant l'ordre des extrudeurs."
-#: src/libslic3r/PrintConfig.cpp:1457
-msgid "Printer notes"
-msgstr "Notes de l'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:218
+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 "Cette procédure de fin est insérée à la fin du fichier de sortie. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r."
-#: src/libslic3r/PrintConfig.cpp:1458
-msgid "You can put your notes regarding the printer here."
-msgstr "Vous pouvez saisir ici vos observations concernant l'imprimante."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:827
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:838
+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 of 1.8 mm³/s (0.45mm extrusion width, 0.2mm extrusion height, feedrate 20 mm/s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds."
+msgstr "Ce réglage expérimental sert à limiter la vitesse de changement dans le flux d'extrusion. Une valeur de 1.8 mm³/s² garantit qu'un changement de flux d'extrusion de 1.8 mm³/s (largeur d'extrusion 0.45mm, hauteur d'extrusion 0.2mm, alimentation 20 mm/s) à 5.4 mm³/s (alimentation 60 mm/s) prendra au moins 2 secondes."
-#: src/libslic3r/PrintConfig.cpp:1467
-msgid "Printer vendor"
-msgstr "Fabriquant de l'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:818
+msgid "This experimental setting is used to set the maximum volumetric speed your extruder supports."
+msgstr "Ce réglage expérimental est utilisé pour paramétrer la vitesse volumétrique maximum tolérée par votre extrudeur."
-#: src/libslic3r/PrintConfig.cpp:1468
-msgid "Name of the printer vendor."
-msgstr "Nom du fabriquant de l'imprimante."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1657
+msgid "This experimental setting uses G10 and G11 commands to have the firmware handle the retraction. This is only supported in recent Marlin."
+msgstr "Ce réglage expérimental utilise les commandes G10 et G11 pour laisser le firmware gérer la rétractation. Utilisable seulement par les versions récentes de Marlin."
-#: src/libslic3r/PrintConfig.cpp:1472
-msgid "Printer variant"
-msgstr "Variante d'imprimante"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1671
+msgid "This experimental setting uses outputs the E values in cubic millimeters instead of linear millimeters. If your firmware doesn't already know filament diameter(s), you can put commands like 'M200 D[filament_diameter_0] T0' in your start G-code in order to turn volumetric mode on and use the filament diameter associated to the filament selected in Slic3r. This is only supported in recent Marlin."
+msgstr "Cette fonction expérimentale génère des valeurs de E en millimètres cubiques au lieu de millimètres linéaires. Si votre firmware ne connait pas déjà le diamètre du filament, vous pouvez saisir une commande comme 'M200 D[filament_diameter_0] T0' dans votre G-Code de début pour activer le mode volumétrique, et utiliser le diamètre de filament associé au filament choisi dans Slic3r. Cette fonction n'est utilisable que dans les versions récentes de Marlin."
-#: src/libslic3r/PrintConfig.cpp:1473
-msgid ""
-"Name of the printer variant. For example, the printer variants may be "
-"differentiated by a nozzle diameter."
-msgstr ""
-"Nom de la variante d'imprimante. Par exemple, la variante d'imprimante peut "
-"être différenciée par un diamètre de buse."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:108
+msgid "This factor affects the amount of plastic for bridging. You can decrease it slightly to pull the extrudates and prevent sagging, although default settings are usually good and you should experiment with cooling (use a fan) before tweaking this."
+msgstr "Ce facteur affecte la quantité de plastique utilisée pour les ponts. Vous pouvez le diminuer légèrement pour éviter l'affaissement. La valeur par défaut est généralement suffisante et vous devriez expérimenter le refroidissement (utiliser un ventilateur) avant de modifier ceci."
-#: src/libslic3r/PrintConfig.cpp:1483
-msgid "Raft layers"
-msgstr "Couches du radeau"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:368
+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. Usual values are between 0.9 and 1.1. If you think you need to change this more, check filament diameter and your firmware E steps."
+msgstr "Ce facteur modifie proportionnellement le flux d'extrusion. Vous pouvez avoir besoin de modifier ceci afin d'obtenir un rendu de surface net et une largeur correcte pour les murs uniques. Les valeurs habituelles vont de 0.9 à 1.1. Si vous pensez devoir changer davantage cette valeur, vérifiez le diamètre de votre filament et les E Steps dans le firmware."
-#: src/libslic3r/PrintConfig.cpp:1485
-msgid ""
-"The object will be raised by this number of layers, and support material "
-"will be generated under it."
-msgstr ""
-"L'objet sera surélevé de ce nombre de couches, et du support sera généré en "
-"dessous."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:98
+msgid "This fan speed is enforced during all bridges and overhangs."
+msgstr "Cette vitesse de ventilateur sera utilisée pour les ponts et les surplombs."
-#: src/libslic3r/PrintConfig.cpp:1494
-msgid "Resolution"
-msgstr "Résolution"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:692
+msgid "This feature allows to combine infill and speed up your print by extruding thicker infill layers while preserving thin perimeters, thus accuracy."
+msgstr "Cette fonction permet de combiner le remplissage afin d'accélérer l'impression en extrudant des couches de remplissage plus épaisses tout en conservant des périmètres fins, avec plus de précision."
-#: src/libslic3r/PrintConfig.cpp:1495
-msgid ""
-"Minimum detail resolution, used to simplify the input file for speeding up "
-"the slicing job and reducing memory usage. High-resolution models often "
-"carry more detail than printers can render. Set to zero to disable any "
-"simplification and use full resolution from input."
-msgstr ""
-"Résolution minimale pour les détails, utilisée pour simplifier le fichier "
-"d'entrée afin d'accélérer le découpage et de réduire l'utilisation de la "
-"mémoire. Les modèles haute-résolution possèdent souvent plus de détails que "
-"ce que les imprimantes peuvent produire. Mettez à zéro pour désactiver toute "
-"simplification et utiliser la résolution complète de l'entrée."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1281
+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 will automatically choose the maximum possible number of layers to combine according to nozzle diameter and layer height."
+msgstr "Cette fonction permet de forcer l'impression d'une couche pleine après le nombre de couches indiqué. Réglez sur zéro pour la désactiver. Vous pouvez indiquer n'importe quelle valeur (par exemple 9999); Slic3r choisira automatiquement le nombre maximum de couches a combiner en fonction du diamètre de la buse et de l'épaisseur des couches."
-#: src/libslic3r/PrintConfig.cpp:1506
-msgid "Minimum travel after retraction"
-msgstr "Trajet minimal après une rétraction"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1323
+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, no infill, no top solid layers and no support material. You can still set any number of bottom solid layers as well as skirt/brim loops. It won't work when printing more than an object."
+msgstr "Afin de rendre invisible les jointures, cette fonction élèvera la tête d'impresion graduellement (en cas d'impression d'un objet à paroi unique). Cette option nécessite de n'avoir qu'un seul périmètre, de ne pas avoir de remplissage, ni de surface pleine supérieure, ni de support. Vous pouvez toujours choisir le nombre de surface pleines inférieures de même que les boucles des jupes et des clôtures. Cela ne fonctionnera pas si vous imprimez plus d'un objet."
-#: src/libslic3r/PrintConfig.cpp:1507
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:663
msgid ""
-"Retraction is not triggered when travel moves are shorter than this length."
+"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 ""
-"La rétraction n'est pas déclenchée lorsque les déplacements sont plus courts "
-"que cette distance."
-
-#: src/libslic3r/PrintConfig.cpp:1514
-msgid "Retract amount before wipe"
-msgstr "Quantité de rétractation avant essuyage"
+"Ce fichier contient plusieurs objets positionnés à différentes hauteurs. Au lieu de les considérer comme des objets distincts, voulez-vous que je considère\n"
+"ce fichier comme un seul objet en plusieurs parties?\n"
-#: src/libslic3r/PrintConfig.cpp:1515
-msgid ""
-"With bowden extruders, it may be wise to do some amount of quick retract "
-"before doing the wipe movement."
-msgstr ""
-"Avec les extrudeurs bowden, il est conseillé d'effectuer une rétractation "
-"rapide avant de réaliser le mouvement de nettoyage."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:164
+msgid "This flag enables the automatic cooling logic that adjusts print speed and fan speed according to layer printing time."
+msgstr "Cette option active la logique de refroidissement automatique, qui ajuste la vitesse d'impression et celle du ventilateur en fonction du temps d'impression de la couche."
-#: src/libslic3r/PrintConfig.cpp:1523
-msgid "Retract on layer change"
-msgstr "Rétracter lors des changements de couche"
+#: 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 "Cette option permet l'impression de la jupe qui entoure chaque objet lors de la première couche."
-#: src/libslic3r/PrintConfig.cpp:1524
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1066
msgid "This flag enforces a retraction whenever a Z move is done."
msgstr "Cette option active la rétractation lors d'un déplacement sur l'axe Z."
-#: src/libslic3r/PrintConfig.cpp:1530 src/libslic3r/PrintConfig.cpp:1539
-msgid "Length"
-msgstr "Longueur"
-
-#: src/libslic3r/PrintConfig.cpp:1531
-msgid "Retraction Length"
-msgstr "Longueur de Rétractation"
-
-#: src/libslic3r/PrintConfig.cpp:1532
-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 ""
-"Lorsque la rétractation est déclenchée, le filament est tiré en arrière de "
-"la longueur indiquée (la longueur est mesurée sur le filament brut, avant "
-"qu'il entre dans l'extrudeur)."
-
-#: src/libslic3r/PrintConfig.cpp:1534 src/libslic3r/PrintConfig.cpp:1544
-msgid "mm (zero to disable)"
-msgstr "mm (zéro pour désactiver)"
-
-#: src/libslic3r/PrintConfig.cpp:1540
-msgid "Retraction Length (Toolchange)"
-msgstr "Longueur de Rétractation (changement d'outil)"
-
-#: src/libslic3r/PrintConfig.cpp:1541
-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 ""
-"Lorsque la rétractation est déclenchée avant un changement d'outil, le "
-"filament est retiré de la longueur indiquée (la longueur est mesurée sur le "
-"filament brut, avant qu'il entre dans l'extrudeur)."
-
-#: src/libslic3r/PrintConfig.cpp:1550
-msgid "Lift Z"
-msgstr "Levage de l'axe Z"
-
-#: src/libslic3r/PrintConfig.cpp:1551
-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 ""
-"Si vous indiquez une valeur positive, l'axe Z est rapidement élevé à chaque "
-"rétraction. Lorsque vous utilisez plusieurs extrudeurs, seul le réglage du "
-"premier extrudeur sera pris en compte."
-
-#: src/libslic3r/PrintConfig.cpp:1559
-msgid "Above Z"
-msgstr "Au-delà de Z"
-
-#: src/libslic3r/PrintConfig.cpp:1560
-msgid "Only lift Z above"
-msgstr "Lever Z seulement au-dessus de"
-
-#: src/libslic3r/PrintConfig.cpp:1561
-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 ""
-"Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché "
-"qu'à partir de la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier "
-"ce réglage pour éviter le levage de l'axe Z sur les premières couches."
-
-#: src/libslic3r/PrintConfig.cpp:1569
-msgid "Below Z"
-msgstr "En-deçà de Z"
-
-#: src/libslic3r/PrintConfig.cpp:1570
-msgid "Only lift Z below"
-msgstr "Lever Z seulement en-dessous de"
-
-#: src/libslic3r/PrintConfig.cpp:1571
-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 ""
-"Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché "
-"que jusqu'à la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier ce "
-"réglage pour limiter le levage de l'axe Z aux premières couches."
-
-#: src/libslic3r/PrintConfig.cpp:1580 src/libslic3r/PrintConfig.cpp:1589
-msgid "Extra length on restart"
-msgstr "Longueur supplémentaire à la reprise"
-
-#: src/libslic3r/PrintConfig.cpp:1581
-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 ""
-"Lorsque la rétractation est compensée après un déplacement, l'extruder "
-"exprimera cette quantité de filament en plus. Ce réglage est rarement "
-"nécessaire."
-
-#: src/libslic3r/PrintConfig.cpp:1590
-msgid ""
-"When the retraction is compensated after changing tool, the extruder will "
-"push this additional amount of filament."
-msgstr ""
-"Lorsque la rétractation est compensée après un changement d'outil, "
-"l'extrudeur exprimera cette quantité de filament en plus."
-
-#: src/libslic3r/PrintConfig.cpp:1598 src/libslic3r/PrintConfig.cpp:1599
-msgid "Retraction Speed"
-msgstr "Vitesse de Rétractation"
-
-#: src/libslic3r/PrintConfig.cpp:1600
-msgid "The speed for retractions (it only applies to the extruder motor)."
-msgstr ""
-"La vitesse des rétractations (ne s'applique qu'au moteur de l'extrudeur)."
-
-#: src/libslic3r/PrintConfig.cpp:1607 src/libslic3r/PrintConfig.cpp:1608
-msgid "Deretraction Speed"
-msgstr "Vitesse de Réinsertion"
-
-#: src/libslic3r/PrintConfig.cpp:1609
-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 ""
-"La vitesse de chargement d'un filament dans l'extrudeur après une "
-"rétractation (ne s'applique qu'au moteur de l'extrudeur). Si cette valeur "
-"reste sur zéro, la vitesse de rétraction est utilisée."
-
-#: src/libslic3r/PrintConfig.cpp:1617
-msgid "Seam position"
-msgstr "Position de la jointure"
-
-#: src/libslic3r/PrintConfig.cpp:1619
-msgid "Position of perimeters starting points."
-msgstr "Position des points de départ des périmètres."
-
-#: src/libslic3r/PrintConfig.cpp:1626
-msgid "Random"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1627
-msgid "Nearest"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1628
-msgid "Aligned"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1629
-msgid "Rear"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:1636
-msgid "Direction"
-msgstr "Direction"
-
-#: src/libslic3r/PrintConfig.cpp:1638
-msgid "Preferred direction of the seam"
-msgstr "Direction préférée de la jointure"
-
-#: src/libslic3r/PrintConfig.cpp:1639
-msgid "Seam preferred direction"
-msgstr "Direction préférée de la jointure"
-
-#: src/libslic3r/PrintConfig.cpp:1647
-msgid "Jitter"
-msgstr "Gigue"
-
-#: src/libslic3r/PrintConfig.cpp:1649
-msgid "Seam preferred direction jitter"
-msgstr "Gigue de la direction préférée de la jointure"
-
-#: src/libslic3r/PrintConfig.cpp:1650
-msgid "Preferred direction of the seam - jitter"
-msgstr "Direction préférée de la jointure - gigue"
-
-#: src/libslic3r/PrintConfig.cpp:1661
-msgid "USB/serial port for printer connection."
-msgstr "Port USB/Série pour la connexion de l'imprimante."
-
-#: src/libslic3r/PrintConfig.cpp:1669
-msgid "Serial port speed"
-msgstr "Vitesse du port série"
-
-#: src/libslic3r/PrintConfig.cpp:1670
-msgid "Speed (baud) of USB/serial port for printer connection."
-msgstr "Vitesse (baud) du port USB/série pour la connexion à l'imprimante."
-
-#: src/libslic3r/PrintConfig.cpp:1679
-msgid "Distance from object"
-msgstr "Distance de l'objet"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1689
+msgid "This flag will move the nozzle while retracting to minimize the possible blob on leaky extruders."
+msgstr "Cette option déplace la buse lors des rétractations, limitant ainsi l'apparition d'amas sur les extrudeurs ayant tendance à couler."
-#: src/libslic3r/PrintConfig.cpp:1680
-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 ""
-"Distance entre le ou les objet(s) et la jupe. Mettez zéro pour attacher la "
-"jupe a(ux) objet(s) et obtenir une bordure pour une meilleure adhésion."
-
-#: src/libslic3r/PrintConfig.cpp:1688
-msgid "Skirt height"
-msgstr "Hauteur de la jupe"
-
-#: src/libslic3r/PrintConfig.cpp:1689
-msgid ""
-"Height of skirt expressed in layers. Set this to a tall value to use skirt "
-"as a shield against drafts."
-msgstr ""
-"Hauteur de la jupe exprimée en couches. Mettez une valeur élevée pour "
-"utiliser la jupe comme un bouclier contre les flux d'airs."
-
-#: src/libslic3r/PrintConfig.cpp:1697
-msgid "Loops (minimum)"
-msgstr "Boucles (minimum)"
-
-#: src/libslic3r/PrintConfig.cpp:1698
-msgid "Skirt Loops"
-msgstr "Boucles de la Jupe"
-
-#: src/libslic3r/PrintConfig.cpp:1699
-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 ""
-"Nombre de boucles pour la jupe. Si la Longueur Minimale d'Extrusion est "
-"paramétrée, le nombre de boucles minimal sera plus grand que celui configuré "
-"ici. Mettez à zéro pour désactiver complètement la jupe."
-
-#: src/libslic3r/PrintConfig.cpp:1708
-msgid "Slow down if layer print time is below"
-msgstr "Ralentir si le temps d'impression de la couche est inférieur à"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:343
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:406
+msgid "This is only used in the Slic3r interface as a visual help."
+msgstr "Ceci est uniquement utilisé dans l'interface de Slic3r comme indication visuelle."
-#: src/libslic3r/PrintConfig.cpp:1709
-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 ""
-"Si le temps d'impression estimé de la couche est inférieur à ce nombre de "
-"secondes, la vitesse des déplacements d'impression sera réduite afin "
-"d'atteindre cette valeur."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:171
+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 "Accélération à laquelle votre imprimante sera réinitialisée suite à une modification de l'accélération des fonctions spécifiques (périmètre/remplissage). Régler sur zéro pour ne pas réinitialiser l'accélération."
-#: src/libslic3r/PrintConfig.cpp:1720
-msgid "Small perimeters"
-msgstr "Périmètres courts"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:78
+msgid "This is the acceleration your printer will use for bridges. Set zero to disable acceleration control for bridges."
+msgstr "L'accélération qui sera utilisée par votre imprimante pour les ponts. Régler sur zéro pour désactiver l'accélération pour les ponts."
-#: src/libslic3r/PrintConfig.cpp:1722
-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 ""
-"Ce réglage distinct affectera la vitesse des périmètre ayant un rayon <= "
-"6.5mm (les trous habituellement). Si cette valeur est exprimée en "
-"pourcentage (par exemple: 80%) elle sera calculée d'après le réglage de la "
-"vitesse de périmètre susmentionnée. Réglez sur zéro pour un ajustement "
-"automatique."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:574
+msgid "This is the acceleration your printer will use for first layer. Set zero to disable acceleration control for first layer."
+msgstr "L'accélération que l'imprimante utilisera pour la première couche. Régler sur zéro afin de désactiver le contrôle de l'accélération pour la première couche."
-#: src/libslic3r/PrintConfig.cpp:1732
-msgid "Solid infill threshold area"
-msgstr "Surface de seuil pour le remplissage solide"
-
-#: src/libslic3r/PrintConfig.cpp:1734
-msgid ""
-"Force solid infill for regions having a smaller area than the specified "
-"threshold."
-msgstr ""
-"Forcer un remplissage solide pour les zones ayant une surface plus petite "
-"que la valeur indiquée."
-
-#: src/libslic3r/PrintConfig.cpp:1735
-msgid "mm²"
-msgstr "mm²"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:682
+msgid "This is the acceleration your printer will use for infill. Set zero to disable acceleration control for infill."
+msgstr "Il s'agit de l'accélération que votre imprimante utilisera pour le remplissage. Régler sur zéro afin de désactiver le contrôle de l'accélération pour le remplissage."
-#: src/libslic3r/PrintConfig.cpp:1742
-msgid "Solid infill extruder"
-msgstr "Extrudeur pour le remplissage solide"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:949
+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 "L'accélération que votre imprimante utilisera pour les périmètres. Une valeur élevée comme 9000 donne généralement de bons résultats si votre matériel le permet. Régler sur zéro afin de désactiver le contrôle de l'accélération pour les périmètres."
-#: src/libslic3r/PrintConfig.cpp:1744
-msgid "The extruder to use when printing solid infill."
-msgstr "L'extrudeur à utiliser pour imprimer les remplissages solides."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:895
+msgid "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)"
+msgstr "Il s'agit du diamètre de la buse de votre extrudeur (par exemple: 0.5, 0.35, etc.)"
-#: src/libslic3r/PrintConfig.cpp:1751
-msgid "Solid infill every"
-msgstr "Remplissage solide toutes les"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:797
+#, 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 layer height is 75% of the extrusion width to achieve reasonable inter-layer adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter."
+msgstr "Ceci est la hauteur de couche imprimable maximum pour cet extrudeur, utilisée pour plafonner la hauteur de couche variable et la hauteur de couche des supports. La hauteur de couche maximum recommandée est 75% de la largeur d'extrusion afin d'obtenir une adhésion inter-couches correcte. Si réglée sur 0, la hauteur de couche est limitée à 75% du diamètre de la buse."
-#: src/libslic3r/PrintConfig.cpp:1753
-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 "
-"will automatically choose the maximum possible number of layers to combine "
-"according to nozzle diameter and layer height."
-msgstr ""
-"Cette fonction permet de forcer l'impression d'une couche solide après le "
-"nombre de couches indiqué. Réglez sur zéro pour la désactiver. Vous pouvez "
-"indiquer n'importe quelle valeur (par exemple 9999); Slic3r choisira "
-"automatiquement le nombre maximum de couches a combiner en fonction du "
-"diamètre de la buse et de l'épaisseur des couches."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:858
+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 "Cette valeur est la hauteur de couche imprimable minimum pour cet extrudeur et elle limite la résolution pour la hauteur de couche variable. Les valeurs type se situent entre 0.05 mm et 0.1 mm."
-#: src/libslic3r/PrintConfig.cpp:1766
-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, "
-"otherwise 1.125 x nozzle diameter will be used. If expressed as percentage "
-"(for example 90%) it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour le remplissage ou les surfaces solides. Si la "
-"valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si "
-"définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Si la "
-"valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée "
-"par rapport à la hauteur de couche."
-
-#: src/libslic3r/PrintConfig.cpp:1777
-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 ""
-"Vitesse pour imprimer des zones solides (supérieures/inférieures/parois "
-"horizontales internes). Peut être exprimée en pourcentage (par exemple: 80%) "
-"de la vitesse de remplissage par défaut susmentionnée. Réglez sur zéro pour "
-"un ajustement automatique."
+#: 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 "Cette matrice décrit les volumes (en millimètres cube) nécessaires pour purger le nouveau filament dans la tour de nettoyage pour une paire d'outils donnée. "
-#: src/libslic3r/PrintConfig.cpp:1789
-msgid "Number of solid layers to generate on top and bottom surfaces."
-msgstr ""
-"Nombre de couches solides à générer sur les surfaces supérieures et "
-"inférieures."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:990
+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 surfaces which benefit from a higher number of perimeters if the Extra Perimeters option is enabled."
+msgstr "Cette option définit le nombre de périmètres à générer pour chaque couche. Notez que Slic3r peut augmenter cette valeur automatiquement si il détecte une surface inclinée qui nécessite un plus grand nombre de périmètres, si l'option \"Périmètres supplémentaires\" est sélectionnée."
-#: src/libslic3r/PrintConfig.cpp:1796
-msgid "Spiral vase"
-msgstr "Vase spiral"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:923
+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 "Cette option abaissera la température des extrudeurs inutilisés pour prévenir le oozing (suintement). Cela active automatiquement la génération d'une grande clôture et le déplacement des extrudeurs hors de cette clôture lors des changements de température."
-#: src/libslic3r/PrintConfig.cpp:1797
-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, "
-"no infill, no top solid layers and no support material. You can still set "
-"any number of bottom solid layers as well as skirt/brim loops. It won't work "
-"when printing more than an object."
-msgstr ""
-"Cette fonction élèvera le Z graduellement en cas d'impression d'un objet à "
-"paroi unique, afin de rendre invisibles les jointures. Cette option "
-"nécessite de n'avoir qu'un seul périmètre, de ne pas avoir de remplissage, "
-"ni de surface solide supérieure, ni de support. Vous pouvez toujours choisir "
-"le nombre de surface solides inférieures de même que les boucles des jupes "
-"et des bordures. Cela ne fonctionnera pas si vous imprimez plus d'un objet."
-
-#: src/libslic3r/PrintConfig.cpp:1806
-msgid "Temperature variation"
-msgstr "Variation de température"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:728
+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 "Cette option limitera le remplissage aux zones nécessaires pour soutenir les couches supérieures (cela agira comme un support interne). Si activé, la génération du G-Code prendra plus de temps à cause des calculs supplémentaires requis."
-#: src/libslic3r/PrintConfig.cpp:1807
-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 ""
-"Différence de température devant être appliquée quand un extrudeur n'est pas "
-"actif. Permet la génération d'un contour complet \"sacrificiel\" sur lequel "
-"les buses sont nettoyées régulièrement."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:721
+msgid "This option will switch the print order of perimeters and infill, making the latter first."
+msgstr "Cette option inverse l'ordre d'impression des périmètres et du remplissage, ce dernier étant alors imprimé en premier."
-#: src/libslic3r/PrintConfig.cpp:1818
-msgid ""
-"This start procedure is inserted at the beginning, after bed has reached the "
-"target temperature and extruder just started heating, and before extruder "
-"has finished heating. If Slic3r detects M104 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."
-msgstr ""
-"Cette procédure de démarrage est insérée au début, après que le plateau a "
-"atteint la température ciblée et lorsque l'extrudeur vient juste de "
-"commencer à chauffer, et avant que l'extrudeur ait terminé de chauffer. Si "
-"Slic3r détecte des commandes M104 ou M190 dans vos codes personnalisés, ces "
-"commandes ne seront pas ajoutées automatiquement ainsi vous serez libre de "
-"personnaliser l'ordre des commandes de chauffe et autres actions "
-"personnalisées. Notez que vous pouvez utiliser des variables génériques pour "
-"tous les réglages de Slic3r, donc vous pouvez mettre une commande "
-"\"M109S[first_layer_temperature]\" où vous le souhaitez."
-
-#: src/libslic3r/PrintConfig.cpp:1834
-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 "
-"extruders, the gcode is processed in extruder order."
-msgstr ""
-"Cette procédure de démarrage est insérée au début, après un gcode de "
-"démarrage de l'imprimante. Elle est utilisée pour remplacer les réglages "
-"pour un filament spécifique. Si Slic3r détecte des commandes M104, M109, "
-"M140 ou M190 dans vos codes personnalisés ces commandes ne seront pas "
-"ajoutées automatiquement, de cette manière vous pouvez personnaliser la "
-"procédure de chauffe et autres actions. Notez que vous pouvez utiliser des "
-"variables génériques pour tous les réglages de Slic3r, donc vous pouvez "
-"saisir une commande \"M109 S[first_layer_temperature]\" où vous voulez. Si "
-"vous avez plusieurs extrudeurs, le G-Code sera exécuté dans l'ordre des "
-"extrudeurs."
-
-#: src/libslic3r/PrintConfig.cpp:1850
-msgid "Single Extruder Multi Material"
-msgstr "Extrudeur Unique Multi-Matériaux"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:279
+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 "Ce réglage distinct affectera la vitesse des périmètres extérieurs (ceux qui sont visibles). Si cette valeur est exprimée en pourcentage (par exemple: 80%) elle sera calculée d'après le réglage de la vitesse de périmètre susmentionnée. Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:1851
-msgid "The printer multiplexes filaments into a single hot end."
-msgstr "L'imprimante multiplexe les filaments vers une seule tête d'extrusion."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1252
+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 "Ce réglage distinct affectera la vitesse des périmètre ayant un rayon <= 6.5mm (les trous habituellement). Si cette valeur est exprimée en pourcentage (par exemple: 80%) elle sera calculée d'après le réglage de la vitesse de périmètre susmentionnée. Réglez sur zéro pour un ajustement automatique."
-#: src/libslic3r/PrintConfig.cpp:1857
-msgid "Prime all printing extruders"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:737
+msgid "This setting applies an additional overlap between infill and perimeters for better bonding. Theoretically this shouldn't be needed, but backlash might cause gaps. If expressed as percentage (example: 15%) it is calculated over perimeter extrusion width."
+msgstr "Cette option applique un chevauchement supplémentaire entre les périmètres et le remplissage pour une meilleur fusion. En théorie, cela ne devrait pas être nécessaire, mais le jeu mécanique peut générer des espacements. Si exprimé en pourcentage (par exemple 15%), la valeur sera calculée en fonction de la largeur d'extrusion du périmètre."
-#: src/libslic3r/PrintConfig.cpp:1858
-msgid ""
-"If enabled, all printing extruders will be primed at the front edge of the "
-"print bed at the start of the print."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:779
+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 "Cette option contrôle l'épaisseur (et donc le nombre total) des couches. Des couches plus fines donneront une meilleure précision mais l'impression sera plus longue."
-#: src/libslic3r/PrintConfig.cpp:1864
-msgid "Generate support material"
-msgstr "Générer des supports"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:788
+msgid "This setting represents the maximum speed of your fan."
+msgstr "Cette option représente la vitesse maximum du ventilateur."
-#: src/libslic3r/PrintConfig.cpp:1866
-msgid "Enable support material generation."
-msgstr "Activer la génération des supports."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:849
+msgid "This setting represents the minimum PWM your fan needs to work."
+msgstr "Cette option représente le PWM minimum dont votre ventilateur a besoin pour tourner."
-#: src/libslic3r/PrintConfig.cpp:1871
-msgid "Auto generated supports"
-msgstr ""
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:120
+#, c-format
+msgid "This Slic3r PE version: %s"
+msgstr "Version de ce Slic3r PE : %s"
-#: src/libslic3r/PrintConfig.cpp:1873
-msgid ""
-"If checked, supports will be generated automatically based on the overhang "
-"threshold value. If unchecked, supports will be generated inside the "
-"\"Support Enforcer\" volumes only."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1358
+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 extruders, the gcode is processed in extruder order."
+msgstr "Cette procédure de démarrage est insérée au début, après un gcode de démarrage de l'imprimante. Elle est utilisée pour remplacer les réglages pour un filament spécifique. Si Slic3r détecte des commandes M104, M109, M140 ou M190 dans vos codes personnalisés ces commandes ne seront pas ajoutées automatiquement, de cette manière vous pouvez personnaliser la procédure de chauffe et autres actions. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r, donc vous pouvez saisir une commande \"M109 S[first_layer_temperature]\" où vous voulez. Si vous avez plusieurs extrudeurs, le G-Code sera exécuté dans l'ordre des extrudeurs."
-#: src/libslic3r/PrintConfig.cpp:1880
-msgid "XY separation between an object and its support"
-msgstr "Séparation XY entre un objet et son support"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1343
+msgid "This start procedure is inserted at the beginning, after bed has reached the target temperature and extruder just started heating, and before extruder has finished heating. If Slic3r detects M104 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."
+msgstr "Cette procédure de démarrage est insérée au début, après que le plateau a atteint la température ciblée et lorsque l'extrudeur vient juste de commencer à chauffer, et avant que l'extrudeur ait terminé de chauffer. Si Slic3r détecte des commandes M104 ou M190 dans vos codes personnalisés, ces commandes ne seront pas ajoutées automatiquement ainsi vous serez libre de personnaliser l'ordre des commandes de chauffe et autres actions personnalisées. Notez que vous pouvez utiliser des variables génériques pour tous les réglages de Slic3r, donc vous pouvez mettre une commande \"M109S[first_layer_temperature]\" où vous le souhaitez."
-#: src/libslic3r/PrintConfig.cpp:1882
-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 ""
-"Séparation XY entre un objet et son support. Si la valeur est exprimée en "
-"pourcentage (par exemple 50%), elle sera calculée à partir de la largeur du "
-"périmètre extérieur."
+#: xs/src/libslic3r/PrintConfig.cpp:487
+msgid "This string is edited by RammingDialog and contains ramming specific parameters "
+msgstr "Cette chaine est éditée par RammingDialog et contient les paramètres spécifiques d'expulsion "
-#: src/libslic3r/PrintConfig.cpp:1893
-msgid "Pattern angle"
-msgstr "Angle du motif"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1743
+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 example, if your endstop zero actually leaves the nozzle 0.3mm far from the print bed, set this to -0.3 (or fix your endstop)."
+msgstr "Cette valeur sera ajoutée (ou soustraite) de toutes les coordonnées Z dans le G-Code de sortie. Elle est utilisée pour compenser une mauvaise position de fin de course Z: par exemple si votre fin de course place votre buse à 0.3mm au dessus du plateau, réglez cette valeur sur -0.3 (ou corrigez votre fin de course)."
-#: src/libslic3r/PrintConfig.cpp:1895
-msgid ""
-"Use this setting to rotate the support material pattern on the horizontal "
-"plane."
-msgstr ""
-"Utiliser ce réglage pour orienter le motif du support sur le plan horizontal."
+#: 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 "Ce vecteur enregistre les volumes requis pour changer l'outil utilisé pour la tour de nettoyage. Ces valeurs sont utilisées pour simplifier la création des volumes de purge complets ci-dessous. "
-#: src/libslic3r/PrintConfig.cpp:1906
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:111
msgid ""
-"Only create support if it lies on a build plate. Don't create support on a "
-"print."
+"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 ""
-"Créer uniquement des supports reposant sur le plateau. Ne pas créer pas de "
-"supports sur une impression."
-
-#: src/libslic3r/PrintConfig.cpp:1913
-msgid "Contact Z distance"
-msgstr "Distance de contact Z"
+"Cette version de Slic3r PE n'est pas compatible avec les ensembles de configuration actuellement installés.\n"
+"Cela survient probablement du fait d'avoir lancé une ancienne version de Slic3r PE après en avoir utilisé une nouvelle.\n"
+"\n"
+"Vous pouvez soit quitter Slic3r et essayer à nouveau avec une version plus récente, ou vous pouvez relancer la configuration initiale. Procéder ainsi permettra de créer une sauvegarde de la configuration existante avant d'installer les fichiers compatibles avec ce Slic3r.\n"
-#: src/libslic3r/PrintConfig.cpp:1915
-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 ""
-"Distance verticale entre l'objet et l'intercalaire du support. Régler cette "
-"valeur sur zéro empêchera Slic3r d'utiliser la vitesse et le débit des ponts "
-"pour la première couche de l'objet."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1590
+msgid "Threads"
+msgstr "Threads"
-#: src/libslic3r/PrintConfig.cpp:1923
-msgid "soluble"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1591
+msgid "Threads are used to parallelize long-running tasks. Optimal threads number is slightly above the number of available cores/processors."
+msgstr "Les threads sont utilisés pour paralléliser les calculs longs. Le nombre optimal de threads est légèrement supérieur au nombre de coeurs/processeurs disponibles."
-#: src/libslic3r/PrintConfig.cpp:1924
-msgid "detachable"
-msgstr ""
+#: xs/src/slic3r/GUI/RammingChart.cpp:81
+msgid "Time"
+msgstr "Durée"
-#: src/libslic3r/PrintConfig.cpp:1929
-msgid "Enforce support for the first"
-msgstr "Renforcer le support sur le(s) première(s)"
+#: 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 "Temps d'attente nécessaire après que le filament ait été déchargé. Peut aider à obtenir des changements d'outils fiables avec des matériaux flexible qui ont besoin de plus de temps pour revenir à leurs dimensions originales. "
-#: src/libslic3r/PrintConfig.cpp:1931
-msgid ""
-"Generate support material for the specified number of layers counting from "
-"bottom, regardless of whether normal support material is enabled or not and "
-"regardless of any angle threshold. This is useful for getting more adhesion "
-"of objects having a very thin or poor footprint on the build plate."
-msgstr ""
-"Générer des supports pour le nombre de couches spécifié à partir du bas, que "
-"les supports normaux soient activés ou non et sans tenir compte de seuils "
-"d'inclinaison. Ceci est utile pour obtenir une meilleure adhésion pour des "
-"objets ayant une surface de contact très fine ou limitée sur le plateau."
+#: xs/src/slic3r/GUI/Tab.cpp:750
+msgid "To do that please specify a new name for the preset."
+msgstr "Pour faire cela veuillez spécifier un nouveau nom pour le préréglage."
-#: src/libslic3r/PrintConfig.cpp:1937
-msgid "Enforce support for the first n layers"
-msgstr "Renforcer le support pour les n premières couches"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:34
+msgid "To download, follow the link below."
+msgstr "Pour télécharger, suivez le lien ci-dessous."
-#: src/libslic3r/PrintConfig.cpp:1943
-msgid "Support material/raft/skirt extruder"
-msgstr "Extrudeur pour support/raft/jupe"
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:338
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:72
+msgid "Tool"
+msgstr "Outil"
-#: src/libslic3r/PrintConfig.cpp:1945
-msgid ""
-"The extruder to use when printing support material, raft and skirt (1+, 0 to "
-"use the current extruder to minimize tool changes)."
-msgstr ""
-"L'extrudeur à utiliser pour imprimer des supports, du raft ou des contours "
-"(1+,0 pour utiliser l'extrudeur actuel et limiter les changements d'outil)."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:238
+msgid "Tool #"
+msgstr "Outil #"
-#: src/libslic3r/PrintConfig.cpp:1955
-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, "
-"otherwise nozzle diameter will be used. If expressed as percentage (for "
-"example 90%) it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour les supports. Si la valeur reste sur zéro, la "
-"largeur d’extrusion par défaut sera utilisée si définie, sinon le diamètre "
-"de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par "
-"exemple : 90%), elle sera calculée par rapport à la hauteur de couche."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1144
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1602
+msgid "Tool change G-code"
+msgstr "G-code de changement d'outil"
-#: src/libslic3r/PrintConfig.cpp:1964
-msgid "Interface loops"
-msgstr "Boucles d'interface"
+#: xs/src/slic3r/GUI/Tab.cpp:1315
+msgid "Toolchange parameters with single extruder MM printers"
+msgstr "Paramètres de changement d'outil pour les imprimantes multi-matériaux mono-extrudeur"
-#: src/libslic3r/PrintConfig.cpp:1966
-msgid ""
-"Cover the top contact layer of the supports with loops. Disabled by default."
-msgstr ""
-"Recouvrir la couche de contact supérieure des supports avec des boucles. "
-"Désactivé par défaut."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1638
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:369
+msgid "Top"
+msgstr "Haut"
-#: src/libslic3r/PrintConfig.cpp:1972
-msgid "Support material/raft interface extruder"
-msgstr "Extrudeur pour l'interface des supports/du radeau"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:187
+msgid "top solid infill"
+msgstr "remplissage plein du dessus"
-#: src/libslic3r/PrintConfig.cpp:1974
-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 ""
-"L'extrudeur à utiliser pour imprimer les intercalaires du support (1+,0 pour "
-"utiliser l'extrudeur actuel et limiter les changements d'outil). Cela "
-"affecte également le raft."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1613
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1624
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:143
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:85
+msgid "Top solid infill"
+msgstr "Remplissage plein du dessus"
-#: src/libslic3r/PrintConfig.cpp:1982
-msgid "Interface layers"
-msgstr "Couches d'interface"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1642
+msgid "Top solid layers"
+msgstr "Couches pleines du dessus"
-#: src/libslic3r/PrintConfig.cpp:1984
-msgid ""
-"Number of interface layers to insert between the object(s) and support "
-"material."
-msgstr ""
-"Nombre de couches d'interface à insérer entre le(s) objet(s) et les supports."
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:369
+msgid "Top View"
+msgstr "Vue du Dessus"
-#: src/libslic3r/PrintConfig.cpp:1992
-msgid "Interface pattern spacing"
-msgstr "Espacement du motif d'interface"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:246
+msgid "Top/bottom fill pattern"
+msgstr "Motif de remplissage dessus/dessous"
-#: src/libslic3r/PrintConfig.cpp:1994
-msgid "Spacing between interface lines. Set zero to get a solid interface."
-msgstr ""
-"Espacement entre les lignes d'interface. Mettez à zéro pour obtenir une "
-"interface solide."
+#: 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 "Le volume de purge total est calculé en additionnant les deux valeurs ci-dessous, en fonction des outils qui sont chargés/déchargés."
-#: src/libslic3r/PrintConfig.cpp:2004
-msgid ""
-"Speed for printing support material interface layers. If expressed as "
-"percentage (for example 50%) it will be calculated over support material "
-"speed."
-msgstr ""
-"Vitesse d'impression des couches d'interface des supports. Si exprimée en "
-"pourcentage (par exemple 50%), elle sera calculée à partir de la vitesse "
-"d'impression des supports."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:84
+msgid "Total rammed volume"
+msgstr "Volume total expulsé"
-#: src/libslic3r/PrintConfig.cpp:2013
-msgid "Pattern"
-msgstr "Motif"
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:82
+msgid "Total ramming time"
+msgstr "Durée totale de l'expulsion"
-#: src/libslic3r/PrintConfig.cpp:2015
-msgid "Pattern used to generate support material."
-msgstr "Motif utilisé pour générer les supports."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1647
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:95
+msgid "Travel"
+msgstr "Déplacement"
-#: src/libslic3r/PrintConfig.cpp:2022
-msgid "Rectilinear grid"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:1107
+msgid "Type of the printer."
+msgstr "Type d'imprimante."
-#: src/libslic3r/PrintConfig.cpp:2028
-msgid "Pattern spacing"
-msgstr "Espacement du motif"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2070
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2086
+msgid "Uniformly…"
+msgstr "Uniformément…"
-#: src/libslic3r/PrintConfig.cpp:2030
-msgid "Spacing between support material lines."
-msgstr "Espacement entre les lignes des supports."
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:24
+msgid "Unknown"
+msgstr "Inconnu"
-#: src/libslic3r/PrintConfig.cpp:2040
-msgid "Speed for printing support material."
-msgstr "Vitesse d'impression du support."
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:232
+msgid "unloaded"
+msgstr "déchargé"
-#: src/libslic3r/PrintConfig.cpp:2047
-msgid "Synchronize with object layers"
-msgstr "Synchroniser avec les couches de l'objet"
+#: xs/src/libslic3r/PrintConfig.cpp:467
+msgid "Unloading speed"
+msgstr "Vitesse de déchargement"
-#: src/libslic3r/PrintConfig.cpp:2049
+#: xs/src/slic3r/GUI/Tab.cpp:2483
msgid ""
-"Synchronize support layers with the object print layers. This is useful with "
-"multi-material printers, where the extruder switch is expensive."
+"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 ""
-"Synchroniser les couches du support avec les couches d'impression de "
-"l'objet. Cela est utile pour les imprimantes multi-matériaux, pour "
-"lesquelles le changement d'extrudeur est onéreux."
+"L'icône CADENAS OUVERT indique que certains paramètres ont été modifiés et ne sont pas égaux aux valeurs par défaut pour le groupe d'options actuel.\n"
+"Cliquez pour régler tous les paramètres pour le groupe d'options actuel sur les valeurs par défaut."
-#: src/libslic3r/PrintConfig.cpp:2056
-msgid "Overhang threshold"
-msgstr "Seuil de surplomb"
-
-#: src/libslic3r/PrintConfig.cpp:2058
+#: xs/src/slic3r/GUI/Tab.cpp:2498
msgid ""
-"Support material will not be generated for overhangs whose slope angle (90° "
-"= vertical) is above the given threshold. In other words, this value "
-"represent the most horizontal slope (measured from the horizontal plane) "
-"that you can print without support material. Set to zero for automatic "
-"detection (recommended)."
+"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 ""
-"Le support ne sera pas généré pour les surplombs dont l'inclinaison (90° = "
-"vertical) dépasse le seuil défini. Autrement dit, cette valeur représente "
-"l'inclinaison horizontale maximum (mesurée à partir du plan horizontal) que "
-"vous pouvez imprimer sans support. Réglez sur zéro pour une détection "
-"automatique (recommandé)."
+"L'icône CADENAS OUVERT indique que la valeur a été changée et n'est pas égale à la valeur par défaut.\n"
+"Cliquez pour régler la valeur actuelle sur la valeur par défaut."
-#: src/libslic3r/PrintConfig.cpp:2071
-msgid "With sheath around the support"
-msgstr "Avec une enveloppe autour du support"
-
-#: src/libslic3r/PrintConfig.cpp:2073
+#: xs/src/slic3r/GUI/Tab.cpp:2445
msgid ""
-"Add a sheath (a single perimeter line) around the base support. This makes "
-"the support more reliable, but also more difficult to remove."
+"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 ""
-"Ajouter une enveloppe (une ligne unique de périmètre) autour de la base du "
-"support. Ceci rend le support plus fiable, mais aussi plus difficile à "
-"retirer."
+"CADENAS OUVERT;indique que certains paramètres ont été modifiés et ne sont pas égaux aux valeurs par défaut pour le groupe d'options actuel.\n"
+"Cliquez sur l'icône CADENAS OUVERT pour régler tous les paramètres pour le groupe d'options actuel sur les valeurs par défaut."
-#: src/libslic3r/PrintConfig.cpp:2081
-msgid ""
-"Extruder temperature for layers after the first one. Set this to zero to "
-"disable temperature control commands in the output."
-msgstr ""
-"Température de l'extrudeur pour les couches après la première. Mettez zéro "
-"pour désactiver les commandes de contrôle de la température dans le fichier "
-"de sortie."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:97
+msgid "Unretractions"
+msgstr "Dérétractation"
-#: src/libslic3r/PrintConfig.cpp:2084
-msgid "Temperature"
-msgstr "Température"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1492
+msgid "Unsaved Changes"
+msgstr "Changements Non Sauvegardés"
-#: src/libslic3r/PrintConfig.cpp:2090
-msgid "Detect thin walls"
-msgstr "Détecter les parois fines"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:750
+msgid "Unsaved Presets"
+msgstr "Préréglages Non Sauvegardés"
-#: src/libslic3r/PrintConfig.cpp:2092
-msgid ""
-"Detect single-width walls (parts where two extrusions don't fit and we need "
-"to collapse them into a single trace)."
-msgstr ""
-"Détecter les parois de largeur unique (où deux extrusions côte à côte ne "
-"rentrent pas et doivent êtres fusionnées en un seul trait)."
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:27
+msgid "Update available"
+msgstr "Mise à jour disponible"
-#: src/libslic3r/PrintConfig.cpp:2099
-msgid "Threads"
-msgstr "Threads"
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:279 xs/src/slic3r/GUI/Preferences.cpp:67
+msgid "Update built-in Presets automatically"
+msgstr "Mettre à jour automatiquement les Préréglages intégrés"
-#: src/libslic3r/PrintConfig.cpp:2100
-msgid ""
-"Threads are used to parallelize long-running tasks. Optimal threads number "
-"is slightly above the number of available cores/processors."
-msgstr ""
-"Les threads sont utilisés pour paralléliser les calculs longs. Le nombre "
-"optimal de threads est légèrement supérieur au nombre de coeurs/processeurs "
-"disponibles."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:264
+msgid "Updates"
+msgstr "Mises à jour"
-#: src/libslic3r/PrintConfig.cpp:2112
-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 ""
-"Ce code personnalisé est inséré juste avant chaque changement d'extrudeur. "
-"Notez que vous pouvez utiliser des variables génériques pour tous les "
-"réglages de Slic3r de même que [previous_extruder] et [next_extruder]."
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:283
+msgid "Updates are never applied without user's consent and never overwrite user's customized settings."
+msgstr "Les mises à jour ne sont jamais appliquées sans l'accord de l'utilisateur et n'annulent jamais les réglages personnalisés de l'utilisateur."
-#: src/libslic3r/PrintConfig.cpp:2125
-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 "
-"regions and get a smoother finish. If left zero, default extrusion width "
-"will be used if set, otherwise nozzle diameter will be used. If expressed as "
-"percentage (for example 90%) it will be computed over layer height."
-msgstr ""
-"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la "
-"largeur d’extrusion pour le remplissage ou les surfaces supérieures. Vous "
-"voudrez peut-être utiliser des extrudats plus fins pour remplir les zones "
-"les plus étroites et obtenir des finitions plus lisses. Si la valeur reste "
-"sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon "
-"le diamètre de la buse sera utilisé. Si la valeur est exprimée en "
-"pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur "
-"de couche."
-
-#: src/libslic3r/PrintConfig.cpp:2137
-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 "
-"slow down this to get a nicer surface finish. This can be expressed as a "
-"percentage (for example: 80%) over the solid infill speed above. Set to zero "
-"for auto."
-msgstr ""
-"Vitesse pour imprimer les couches solides supérieures (ne s'applique qu'aux "
-"couches externes les plus hautes et pas aux couches internes solides). Vous "
-"voudrez peut-être abaisser cette vitesse afin d'avoir une finition de "
-"surface plus nette. Peut être exprimé en pourcentage (par exemple: 80%) de "
-"la vitesse de remplissage solide susmentionnée. Réglez sur zéro pour un "
-"ajustement automatique."
-
-#: src/libslic3r/PrintConfig.cpp:2149
-msgctxt "Layers"
-msgid "Top"
-msgstr "Haut"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:15
+msgid "Upgrade"
+msgstr "Mise à jour"
-#: src/libslic3r/PrintConfig.cpp:2151
-msgid "Number of solid layers to generate on top surfaces."
-msgstr "Nombre de couches solides à générer sur les surfaces supérieures."
+#: xs/src/slic3r/GUI/GUI.cpp:326
+msgid "Upload a firmware image into an Arduino based printer"
+msgstr "Charger un firmware dans une imprimante basée sur un Arduino"
-#: src/libslic3r/PrintConfig.cpp:2153
-msgid "Top solid layers"
-msgstr "Couches supérieures solides"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:989
+msgid "USB/Serial connection"
+msgstr "Port USB/Série"
-#: src/libslic3r/PrintConfig.cpp:2159
-msgid "Speed for travel moves (jumps between distant extrusion points)."
-msgstr ""
-"Vitesse pour les déplacements (trajet entre deux points d'extrusion "
-"distants)."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1194
+msgid "USB/serial port for printer connection."
+msgstr "Port USB/Série pour la connexion de l'imprimante."
-#: src/libslic3r/PrintConfig.cpp:2168
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1656
msgid "Use firmware retraction"
msgstr "Utiliser la rétractation du firmware"
-#: src/libslic3r/PrintConfig.cpp:2169
-msgid ""
-"This experimental setting uses G10 and G11 commands to have the firmware "
-"handle the retraction. This is only supported in recent Marlin."
-msgstr ""
-"Ce réglage expérimental utilise les commandes G10 et G11 pour laisser le "
-"firmware gérer la rétractation. Utilisable seulement par les versions "
-"récentes de Marlin."
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:75
+msgid "Use legacy OpenGL 1.1 rendering"
+msgstr "Utiliser le rendu de legacy OpenGL 1.1"
-#: src/libslic3r/PrintConfig.cpp:2176
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1663
msgid "Use relative E distances"
msgstr "Utiliser des valeurs E relatives"
-#: src/libslic3r/PrintConfig.cpp:2177
-msgid ""
-"If your firmware requires relative E values, check this, otherwise leave it "
-"unchecked. Most firmwares use absolute values."
-msgstr ""
-"Si votre firmware requiert des valeurs relatives pour E, cochez cette case, "
-"sinon laissez-la décochée. La plupart des firmwares utilisent des valeurs "
-"absolues."
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:361
+msgid "Use this option to set the axis letter associated to your printer's extruder (usually E but some printers use A)."
+msgstr "Utiliser cette option pour indiquer la lettre utilisée par l'extrudeur de votre imprimante (habituellement E, mais certaines imprimantes utilisent A)."
+
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1400
+msgid "Use this setting to rotate the support material pattern on the horizontal plane."
+msgstr "Utiliser ce réglage pour orienter le motif du support sur le plan horizontal."
-#: src/libslic3r/PrintConfig.cpp:2184
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1670
msgid "Use volumetric E"
msgstr "E Volumétrique"
-#: src/libslic3r/PrintConfig.cpp:2185
-msgid ""
-"This experimental setting uses outputs the E values in cubic millimeters "
-"instead of linear millimeters. If your firmware doesn't already know "
-"filament diameter(s), you can put commands like 'M200 D[filament_diameter_0] "
-"T0' in your start G-code in order to turn volumetric mode on and use the "
-"filament diameter associated to the filament selected in Slic3r. This is "
-"only supported in recent Marlin."
-msgstr ""
-"Cette fonction expérimentale génère des valeurs de E en millimètres cubiques "
-"au lieu de millimètres linéaires. Si votre firmware ne connait pas déjà le "
-"diamètre du filament, vous pouvez saisir une commande comme 'M200 "
-"D[filament_diameter_0] T0' dans votre G-Code de début pour activer le mode "
-"volumétrique, et utiliser le diamètre de filament associé au filament choisi "
-"dans Slic3r. Cette fonction n'est utilisable que dans les versions récentes "
-"de Marlin."
-
-#: src/libslic3r/PrintConfig.cpp:2196
-msgid "Enable variable layer height feature"
-msgstr "Activer la fonction de hauteur de couche variable"
-
-#: src/libslic3r/PrintConfig.cpp:2197
-msgid ""
-"Some printers or printer setups may have difficulties printing with a "
-"variable layer height. Enabled by default."
-msgstr ""
-"Certaines imprimantes ou certains réglages d'imprimante peuvent rencontrer "
-"des difficultés pour imprimer avec une hauteur de couche variable. Activé "
-"par défaut."
-
-#: src/libslic3r/PrintConfig.cpp:2204
-msgid "Wipe while retracting"
-msgstr "Nettoyer lors des rétractations"
-
-#: src/libslic3r/PrintConfig.cpp:2205
-msgid ""
-"This flag will move the nozzle while retracting to minimize the possible "
-"blob on leaky extruders."
-msgstr ""
-"Cette option déplace la buse lors des rétractations, limitant ainsi "
-"l'apparition d'amas sur les extrudeurs ayant tendance à couler."
-
-#: src/libslic3r/PrintConfig.cpp:2213
-msgid ""
-"Multi material printers may need to prime or purge extruders on tool "
-"changes. Extrude the excess material into the wipe tower."
-msgstr ""
-"Les imprimantes multi-matériaux peuvent avoir besoin de préparer ou de "
-"purger leurs extrudeurs lors d'un changement d'outil. Extruder le matériau "
-"en excès dans la tour de nettoyage."
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:449
+msgid "Used Filament (g)"
+msgstr "Filament Utilisé (g)"
-#: src/libslic3r/PrintConfig.cpp:2220
-msgid "Purging volumes - load/unload volumes"
-msgstr "Volumes de purge - volumes de chargement/déchargement"
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:447
+msgid "Used Filament (m)"
+msgstr "Filament Utilisé (m)"
-#: src/libslic3r/PrintConfig.cpp:2221
-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 ""
-"Ce vecteur enregistre les volumes requis pour changer l'outil utilisé pour "
-"la tour de nettoyage. Ces valeurs sont utilisées pour simplifier la création "
-"des volumes de purge complets ci-dessous. "
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:448
+msgid "Used Filament (mm³)"
+msgstr "Filament Utilisé (mm³)"
-#: src/libslic3r/PrintConfig.cpp:2228
-msgid "Purging volumes - matrix"
-msgstr "Volumes de purge - matrice"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:21
+msgid "User"
+msgstr "Utilisateur"
-#: src/libslic3r/PrintConfig.cpp:2229
-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 ""
-"Cette matrice décrit les volumes (en millimètres cube) nécessaires pour "
-"purger le nouveau filament dans la tour de nettoyage pour une paire d'outils "
-"donnée. "
+#: 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 "Préréglages utilisateur"
-#: src/libslic3r/PrintConfig.cpp:2239
-msgid "Position X"
-msgstr "Position X"
+#: xs/src/slic3r/GUI/ButtonsDescription.cpp:38
+msgid "Value is the same as the system value"
+msgstr "La valeur est identique à la valeur du système"
-#: src/libslic3r/PrintConfig.cpp:2240
-msgid "X coordinate of the left front corner of a wipe tower"
-msgstr "Coordonnée X du coin avant gauche d'une tour de nettoyage"
+#: 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 "La valeur a été changée et n'est pas égale à la valeur du système ou au dernier préréglage sauvegardé"
-#: src/libslic3r/PrintConfig.cpp:2247
-msgid "Position Y"
-msgstr "Position Y"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:55
+msgid "variants"
+msgstr "variantes"
-#: src/libslic3r/PrintConfig.cpp:2248
-msgid "Y coordinate of the left front corner of a wipe tower"
-msgstr "Coordonnée Y du coin avant gauche d'une tour de nettoyage"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:49 xs/src/slic3r/GUI/Tab.cpp:755
+msgid "vendor"
+msgstr "fabriquant"
-#: src/libslic3r/PrintConfig.cpp:2256
-msgid "Width of a wipe tower"
-msgstr "Largeur d'une tour de nettoyage"
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:644
+msgid "Verbose G-code"
+msgstr "G-code commenté"
-#: src/libslic3r/PrintConfig.cpp:2263
-msgid "Wipe tower rotation angle"
-msgstr "Angle de rotation de la tour de nettoyage"
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:66
+msgid "Version "
+msgstr "Version "
-#: src/libslic3r/PrintConfig.cpp:2264
-msgid "Wipe tower rotation angle with respect to x-axis "
-msgstr "Angle de rotation de la tour de nettoyage par rapport à l'axe X "
+#: xs/src/slic3r/GUI/AboutDialog.cpp:60
+msgid "Version"
+msgstr "Version"
-#: src/libslic3r/PrintConfig.cpp:2265
-msgid "degrees"
-msgstr "degrés"
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:49
+msgid "version"
+msgstr "version"
-#: src/libslic3r/PrintConfig.cpp:2272
-msgid "Wipe into this object's infill"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:318
+msgid "Vertical shells"
+msgstr "Parois verticales"
-#: src/libslic3r/PrintConfig.cpp:2273
-msgid ""
-"Purging after toolchange will done inside this object's infills. This lowers "
-"the amount of waste but may result in longer print time due to additional "
-"travel moves."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:65
+msgid "View"
+msgstr "Vue"
-#: src/libslic3r/PrintConfig.cpp:2281
-msgid "Wipe into this object"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:409
+msgid "Volume"
+msgstr "Volume"
-#: src/libslic3r/PrintConfig.cpp:2282
-msgid ""
-"Object will be used to purge the nozzle after a toolchange to save material "
-"that would otherwise end up in the wipe tower and decrease print time. "
-"Colours of the objects will be mixed as a result."
-msgstr ""
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:241
+msgid "Volume to purge (mm³) when the filament is being"
+msgstr "Volume à purger (mm³) lorsque le filament est"
-#: src/libslic3r/PrintConfig.cpp:2289
-msgid "Maximal bridging distance"
-msgstr "Distance maximale de pont"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214
+msgid "Volumetric"
+msgstr "Volumétrique"
-#: src/libslic3r/PrintConfig.cpp:2290
-msgid "Maximal distance between supports on sparse infill sections. "
-msgstr ""
-"Distance maximale entre les supports sur les sections de remplissage épars. "
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:71
+msgid "Volumetric flow rate"
+msgstr "Débit volumétrique"
-#: src/libslic3r/PrintConfig.cpp:2297
-msgid "XY Size Compensation"
-msgstr "Compensation de Taille XY"
+#: xs/src/libslic3r/GCode/PreviewData.cpp:370
+msgid "Volumetric flow rate (mm3/s)"
+msgstr "Débit volumétrique (mm3/s)"
-#: src/libslic3r/PrintConfig.cpp:2299
-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 ""
-"L'objet sera agrandi/réduit sur les plans XY selon la valeur indiquée "
-"(négatif = réduit, positif = agrandi). Ce réglage peut être utile pour un "
-"réglage fin des tailles de trous."
+#: xs/src/slic3r/GUI/RammingChart.cpp:86
+msgid "Volumetric speed"
+msgstr "Vitesse volumétrique"
-#: src/libslic3r/PrintConfig.cpp:2308
-msgid "Z offset"
-msgstr "Décalage Z"
+#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:500
+msgid "Warning"
+msgstr "Alerte"
-#: src/libslic3r/PrintConfig.cpp:2309
-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 "
-"example, if your endstop zero actually leaves the nozzle 0.3mm far from the "
-"print bed, set this to -0.3 (or fix your endstop)."
-msgstr ""
-"Cette valeur sera ajoutée (ou soustraite) de toutes les coordonnées Z dans "
-"le G-Code de sortie. Elle est utilisée pour compenser une mauvaise position "
-"de fin de course Z: par exemple si votre fin de course place votre buse à "
-"0.3mm au dessus du plateau, réglez cette valeur sur -0.3 (ou corrigez votre "
-"fin de course)."
-
-#: src/libslic3r/PrintConfig.cpp:2319
-msgid "Bed size X"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:205
+msgid "Welcome"
+msgstr "Bienvenue"
-#: src/libslic3r/PrintConfig.cpp:2320 src/libslic3r/PrintConfig.cpp:2327
-#: src/libslic3r/PrintConfig.cpp:2334 src/libslic3r/PrintConfig.cpp:2343
-#: src/libslic3r/PrintConfig.cpp:2351 src/libslic3r/PrintConfig.cpp:2359
-msgid "Dwarf"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:205
+#, c-format
+msgid "Welcome to the Slic3r %s"
+msgstr "Bienvenue sur Slic3r %s"
-#: src/libslic3r/PrintConfig.cpp:2326
-msgid "Bed size Y"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\2D.pm:131
+msgid "What do you want to print today? â„¢"
+msgstr "Que voulez-vous imprimer aujourd'hui? â„¢"
-#: src/libslic3r/PrintConfig.cpp:2333
-msgid "Picture resolution X"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:69
+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 "Lorsqu'ils sont sélectionnés, les préréglages de l'imprimante et du filament sont visibles dans l'éditeur de préréglage même s'ils sont désignés comme incompatibles avec l'imprimante en cours d'utilisation"
-#: src/libslic3r/PrintConfig.cpp:2335 src/libslic3r/PrintConfig.cpp:2344
-msgid "px"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:219
+msgid "when printing "
+msgstr "pendant l'impression des "
-#: src/libslic3r/PrintConfig.cpp:2342
-msgid "Picture resolution Y"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:136
+msgid "When printing multi-material objects, this settings will make slic3r to clip the overlapping object parts one by the other (2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc)."
+msgstr "Lorsque vous imprimez des objets multi-matériaux, ce réglage fera en sorte que Slic3r rattache ensemble les parties de l'objet qui se superposent (la 2e partie sera rattachée à la 1ere, la 3e partie sera rattachée à la 1ere et la 2e, etc...)."
-#: src/libslic3r/PrintConfig.cpp:2350 src/libslic3r/PrintConfig.cpp:2430
-#: src/libslic3r/PrintConfig.cpp:2431
-msgid "Exposure time"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:155
+msgid "When printing multiple objects or copies, this feature will complete each object before moving onto next one (and starting it from its bottom layer). This feature is useful to avoid the risk of ruined prints. Slic3r should warn and prevent you from extruder collisions, but beware."
+msgstr "Lorsque vous imprimez plusieurs objets ou copies, ce réglage permet de terminer un objet avant de passer au suivant (en repartant de sa première couche). Cette fonction est utile pour éviter les risques d'impressions gâchées. Slic3r doit vous avertir et éviter les collisions entre les objets et l'extrudeur, mais soyez vigilant."
-#: src/libslic3r/PrintConfig.cpp:2358
-msgid "Exposure time first layers"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:605
+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 plates. This can be expressed as an absolute value or as a percentage (for example: 150%) over the default layer height."
+msgstr "Lors d'une impression avec de très faibles épaisseurs de couche, vous pouvez choisir d'imprimer une première couche plus épaisse pour améliorer l'adhérence et la tolérance aux plateaux imparfaits. Ce réglage peut être exprimé comme une valeur absolue ou un pourcentage (par exemple 150%) par rapport à l'épaisseur de couche par défaut."
-#: src/libslic3r/PrintConfig.cpp:2373
-msgid "Display width"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1082
+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 "Lorsque la rétractation est déclenchée avant un changement d'outil, le filament est retiré de la longueur indiquée (la longueur est mesurée sur le filament brut, avant qu'il entre dans l'extrudeur)."
-#: src/libslic3r/PrintConfig.cpp:2374
-msgid "Width of the display"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1073
+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 "Lorsque la rétractation est déclenchée, le filament est tiré en arrière de la longueur indiquée (la longueur est mesurée sur le filament brut, avant qu'il entre dans l'extrudeur)."
-#: src/libslic3r/PrintConfig.cpp:2380
-msgid "Display height"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:808
+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 "Lorsque vous réglez les autres vitesses à 0, Slic3r calculera automatiquement la vitesse optimale de façon à garder une pression constante dans l'extrudeur. Cette fonction expérimentale est utilisée pour régler la plus haute vitesse que vous souhaitez autoriser."
-#: src/libslic3r/PrintConfig.cpp:2381
-msgid "Height of the display"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1127
+msgid "When the retraction is compensated after changing tool, the extruder will push this additional amount of filament."
+msgstr "Lorsque la rétractation est compensée après un changement d'outil, l'extrudeur exprimera cette quantité de filament en plus."
-#: src/libslic3r/PrintConfig.cpp:2387
-msgid "Number of pixels in"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1119
+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 "Lorsque la rétractation est compensée après un déplacement, l'extruder exprimera cette quantité de filament en plus. Ce réglage est rarement nécessaire."
-#: src/libslic3r/PrintConfig.cpp:2389
-msgid "Number of pixels in X"
-msgstr ""
+#: xs/src/slic3r/GUI/Tab.cpp:2486
+msgid "WHITE BULLET icon indicates a non system preset."
+msgstr "L'icône en forme de PUCE BLANCHE indique un préréglage non-système."
-#: src/libslic3r/PrintConfig.cpp:2396
-msgid "Number of pixels in Y"
-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 "L'icône en forme de PUCE BLANCHE indique que les réglages sont identiques au dernier préréglage sauvegardé pour le groupe d'options actuel."
-#: src/libslic3r/PrintConfig.cpp:2402
-msgid "Display orientation"
-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 "L'icône PUCE BLANCHE indique que la valeur est la même que pour le dernier préréglage sauvegardé."
-#: src/libslic3r/PrintConfig.cpp:2403
+#: xs/src/slic3r/GUI/Tab.cpp:2451
msgid ""
-"Set the actual LCD display orientation inside the SLA printer. Portrait mode "
-"will flip the meaning of display width and height parameters and the output "
-"images will be rotated by 90 degrees."
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2410
-msgid "Landscape"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2411
-msgid "Portrait"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2415 src/libslic3r/PrintConfig.cpp:2416
-msgid "Printer scaling correction"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2422 src/libslic3r/PrintConfig.cpp:2423
-msgid "Initial layer height"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2438 src/libslic3r/PrintConfig.cpp:2439
-msgid "Initial exposure time"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2446 src/libslic3r/PrintConfig.cpp:2447
-msgid "Correction for expansion when printing"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2452 src/libslic3r/PrintConfig.cpp:2453
-msgid "Correction for expansion after curing"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2458
-msgid "SLA print material notes"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2459
-msgid "You can put your notes regarding the SLA print material here."
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2468 src/libslic3r/PrintConfig.cpp:2478
-msgid "Default SLA material profile"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2487
-msgid "Generate supports"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2489
-msgid "Generate supports for the models"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2494
-msgid "Support head front diameter"
-msgstr ""
+"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 "PUCE BLANCHE;pour le bouton gauche : indique un préréglage non-système, pour le bouton droit : indique que le réglage n'a pas été modifié."
-#: src/libslic3r/PrintConfig.cpp:2496
-msgid "Diameter of the pointing side of the head"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1716
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:70
+msgid "Width"
+msgstr "Largeur"
-#: src/libslic3r/PrintConfig.cpp:2503
-msgid "Support head penetration"
-msgstr ""
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:334
+msgid "Width (mm)"
+msgstr "Largeur (mm)"
-#: src/libslic3r/PrintConfig.cpp:2505
-msgid "How much the pinhead has to penetrate the model surface"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1717
+msgid "Width of a wipe tower"
+msgstr "Largeur d'une tour de nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2512
-msgid "Support head width"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:41
+#, c-format
+msgid "will always run at %d%% "
+msgstr "fonctionnera toujours à %d%% "
-#: src/libslic3r/PrintConfig.cpp:2514
-msgid "Width from the back sphere center to the front sphere center"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:50
+msgid "will be turned off."
+msgstr "sera désactivé."
-#: src/libslic3r/PrintConfig.cpp:2521
-msgid "Support pillar diameter"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:442
+#: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:149
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:91
+msgid "Wipe tower"
+msgstr "Tour de nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2523
-msgid "Diameter in mm of the support pillars"
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:564
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:585
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:602
+msgid "Wipe Tower"
+msgstr "Tour de Nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2530
-msgid "Support pillar connection mode"
-msgstr ""
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:142
+msgid "Wipe tower - Purging volume adjustment"
+msgstr "Tour de nettoyage - Ajustement du volume de purge"
-#: src/libslic3r/PrintConfig.cpp:2531
-msgid ""
-"Controls the bridge type between two neigboring pillars. Can be zig-zag, "
-"cross (double zig-zag) or dynamic which will automatically switch between "
-"the first two depending on the distance of the two pillars."
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:1847
+msgid "Wipe tower rotation angle"
+msgstr "Angle de rotation de la tour de nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2540
-msgid "Zig-Zag"
-msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:1848
+msgid "Wipe tower rotation angle with respect to x-axis "
+msgstr "Angle de rotation de la tour de nettoyage par rapport à l'axe X "
-#: src/libslic3r/PrintConfig.cpp:2541
-msgid "Cross"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1688
+msgid "Wipe while retracting"
+msgstr "Nettoyer lors des rétractations"
-#: src/libslic3r/PrintConfig.cpp:2542
-msgid "Dynamic"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1058
+msgid "With bowden extruders, it may be wise to do some amount of quick retract before doing the wipe movement."
+msgstr "Avec les extrudeurs bowden, il est conseillé d'effectuer une rétractation rapide avant de réaliser le mouvement de nettoyage."
-#: src/libslic3r/PrintConfig.cpp:2546
-msgid "Pillar widening factor"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1564
+msgid "With sheath around the support"
+msgstr "Avec une enveloppe autour du support"
-#: src/libslic3r/PrintConfig.cpp:2548
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:72
msgid ""
-"Merging bridges or pillars into another pillars can increase the radius. "
-"Zero means no increase, one means full increase."
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2557
-msgid "Support base diameter"
-msgstr ""
-
-#: src/libslic3r/PrintConfig.cpp:2559
-msgid "Diameter in mm of the pillar base"
+"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 ""
+"Voulez-vous l'installer ?\n"
+"\n"
+"Notez qu'un snapshot complet de la configuration sera sauvegardé d'abord. Elle peut être restaurée à tout moment si vous rencontrez un problème avec la nouvelle version.\n"
+"\n"
+"Ensembles de configuration mis à jour :"
-#: src/libslic3r/PrintConfig.cpp:2566
-msgid "Support base height"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1703
+msgid "X coordinate of the left front corner of a wipe tower"
+msgstr "Coordonnée X du coin avant gauche d'une tour de nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2568
-msgid "The height of the pillar base cone"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1386
+msgid "XY separation between an object and its support"
+msgstr "Séparation XY entre un objet et son support"
-#: src/libslic3r/PrintConfig.cpp:2575
-msgid "Critical angle"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1388
+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 "Séparation XY entre un objet et son support. Si la valeur est exprimée en pourcentage (par exemple 50%), elle sera calculée à partir de la largeur du périmètre extérieur."
-#: src/libslic3r/PrintConfig.cpp:2577
-msgid "The default angle for connecting support sticks and junctions."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1732
+msgid "XY Size Compensation"
+msgstr "Compensation de Taille XY"
-#: src/libslic3r/PrintConfig.cpp:2584
-msgid "Max bridge length"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1710
+msgid "Y coordinate of the left front corner of a wipe tower"
+msgstr "Coordonnée Y du coin avant gauche d'une tour de nettoyage"
-#: src/libslic3r/PrintConfig.cpp:2586
-msgid "The max length of a bridge"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1970
+msgid "Yes"
+msgstr "Oui"
-#: src/libslic3r/PrintConfig.cpp:2593
-msgid "Object elevation"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:885
+msgid "You can put here your personal notes. This text will be added to the G-code header comments."
+msgstr "Vous pouvez inscrire ici vos commentaires personnels. Ce texte sera ajouté au commentaire en entête du G-Code."
-#: src/libslic3r/PrintConfig.cpp:2595
-msgid "How much the supports should lift up the supported object."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:413
+msgid "You can put your notes regarding the filament here."
+msgstr "Vous pouvez saisir vos remarques concernant le filament ici."
-#: src/libslic3r/PrintConfig.cpp:2602
-msgid "Density on horizontal surfaces"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1015
+msgid "You can put your notes regarding the printer here."
+msgstr "Vous pouvez saisir ici vos observations concernant l'imprimante."
-#: src/libslic3r/PrintConfig.cpp:2604
-msgid ""
-"How many support points (approximately) should be placed on horizontal "
-"surface."
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:181
+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 "Vous pouvez régler ce paramètre sur une valeur positive pour désactiver complètement le ventilateur pendant les premières couches, afin de ne pas rendre l'adhérence plus difficile."
-#: src/libslic3r/PrintConfig.cpp:2605 src/libslic3r/PrintConfig.cpp:2614
-msgid "points per square dm"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:931
+msgid "You can use all configuration options as variables inside this template. For example: [layer_height], [fill_density] etc. You can also use [timestamp], [year], [month], [day], [hour], [minute], [second], [version], [input_filename], [input_filename_base]."
+msgstr "Vous pouvez utiliser toutes les options de configuration comme variables dans ce modèle. Par exemple : [layer_height], [fill_density] etc. Vous pouvez aussi utiliser [timestamp], [year], [month], [day], [hour], [minute], [second], [version], [input_filename], [input_filename_base]."
-#: src/libslic3r/PrintConfig.cpp:2611
-msgid "Density on surfaces at 45 degrees"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:749
+msgid "You have unsaved changes "
+msgstr "Les modifications n'ont pas été sauvegardées "
-#: src/libslic3r/PrintConfig.cpp:2613
-msgid ""
-"How many support points (approximately) should be placed on surface sloping "
-"at 45 degrees."
-msgstr ""
+#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:101
+msgid "You need to restart Slic3r to make the changes effective."
+msgstr "Vous devez redémarrer Slic3r afin que les modifications soient appliquées."
-#: src/libslic3r/PrintConfig.cpp:2620
-msgid "Minimal support point height"
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:594
+msgid "Your file was repaired."
+msgstr "Votre fichier a été réparé."
-#: src/libslic3r/PrintConfig.cpp:2622
-msgid "No support points will be placed lower than this value from the bottom."
-msgstr ""
+#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:744
+msgid "Your object appears to be too large, so it was automatically scaled down to fit your print bed."
+msgstr "Votre objet semble être trop grand, il a donc été automatiquement réduit afin de l'adapter à votre plateau d'impression."
-#: src/libslic3r/PrintConfig.cpp:2629
-msgid "Use pad"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1742
+msgid "Z offset"
+msgstr "Décalage Z"
-#: src/libslic3r/PrintConfig.cpp:2631
-msgid "Add a pad underneath the supported model"
-msgstr ""
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:91
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:492
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1170
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1181
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1401
+#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1557
+msgid "°"
+msgstr "°"
-#: src/libslic3r/PrintConfig.cpp:2636
-msgid "Pad wall thickness"
-msgstr ""
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:484
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:498
+msgid "°C"
+msgstr "°C"
-#: src/libslic3r/PrintConfig.cpp:2645
-msgid "Pad wall height"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Avoid unsupported perimeters"
+msgstr "Eviter les périmètres sans support"
-#: src/libslic3r/PrintConfig.cpp:2654
-msgid "Max merge distance"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Seam"
+msgstr "Jointures"
-#: src/libslic3r/PrintConfig.cpp:2663
-msgid "Pad edge radius"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Looping perimeter"
+msgstr "Périmètres en boucle"
-#: src/libslic3r/PrintConfig.cpp:3017
-msgid "Cut model at the given Z."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Fill internal"
+msgstr "Remplissage interne"
-#: src/libslic3r/PrintConfig.cpp:3022
-msgid "Dont arrange"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Fill external"
+msgstr "Remplissage plein externe"
-#: src/libslic3r/PrintConfig.cpp:3023
-msgid ""
-"Don't arrange the objects on the build plate. The model coordinates define "
-"the absolute positions on the build plate. The option --center will be "
-"ignored."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Supporting dense layer"
+msgstr "Couche de support pour remplissage plein"
-#: src/libslic3r/PrintConfig.cpp:3030
-msgid "User data directory"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Anchor solid infill by X mm"
+msgstr "Ancrage des remplissages plein de X mm "
-#: src/libslic3r/PrintConfig.cpp:3031
-msgid ""
-"Load and store settings at the given directory. This is useful for "
-"maintaining different profiles or including configurations from a network "
-"storage."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Perimeter speed"
+msgstr "Vitesses pour les périmètres"
-#: src/libslic3r/PrintConfig.cpp:3038
-msgid "Export 3MF"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Infill speed"
+msgstr "Vitesses pour les remplissages"
-#: src/libslic3r/PrintConfig.cpp:3039
-msgid "Slice the model and export slices as 3MF."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Support speed"
+msgstr "Vitesses pour les supports"
-#: src/libslic3r/PrintConfig.cpp:3044
-msgid "Slice"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "First layer speed"
+msgstr "Vitesses pour la première couche"
-#: src/libslic3r/PrintConfig.cpp:3045
-msgid "Slice the model and export gcode."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Wipe tower position"
+msgstr "Position de la tour de vidage"
-#: src/libslic3r/PrintConfig.cpp:3050
-msgid "Help"
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "Bridge flow ratio"
+msgstr "Débit lors de ponts"
-#: src/libslic3r/PrintConfig.cpp:3051
-msgid "Show this help."
-msgstr ""
+#: supermerill's add: tab.cpp
+msgid "XY compensation"
+msgstr "Compensation en XY"
-#: src/libslic3r/PrintConfig.cpp:3056
-msgid "Use GUI"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "remove_small_gaps"
+msgstr "Retirer les petites imperfections"
-#: src/libslic3r/PrintConfig.cpp:3057
-msgid ""
-"Forces the GUI launch instead of command line slicing (if you supply a model "
-"file, it will be loaded into the plater)"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Top fan speed"
+msgstr "Vitesse du ventilateur pour le dessus"
-#: src/libslic3r/PrintConfig.cpp:3063
-msgid "Output Model Info"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Above the bridges"
+msgstr "Au-dessus des ponts"
-#: src/libslic3r/PrintConfig.cpp:3064
-msgid "Write information about the model to the console."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "First layer"
+msgstr "Première couche"
-#: src/libslic3r/PrintConfig.cpp:3069
-msgid "Load config file"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Top Pattern"
+msgstr "Motif du dessus"
-#: src/libslic3r/PrintConfig.cpp:3070
-msgid ""
-"Load configuration from the specified file. It can be used more than once to "
-"load options from multiple files."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Bottom Pattern"
+msgstr "Motif du dessous"
-#: src/libslic3r/PrintConfig.cpp:3075
-msgid "Do not use GUI"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Enforce 100% fill volume"
+msgstr "S'assurer que les remplissages sont exacts en volume"
-#: src/libslic3r/PrintConfig.cpp:3076
-msgid ""
-"Forces the command line slicing instead of gui. This takes precedence over --"
-"gui if both are present."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Bridged"
+msgstr "Ponts"
-#: src/libslic3r/PrintConfig.cpp:3081
-msgid "Output File"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "External"
+msgstr "Externe"
-#: src/libslic3r/PrintConfig.cpp:3082
-msgid ""
-"The file where the output will be written (if not specified, it will be "
-"based on the input file)."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Seam position"
+msgstr "Position des jointures"
-#: src/libslic3r/PrintConfig.cpp:3088
-msgid "Rotation angle around the Z axis in degrees (0-360, default: 0)."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Only one perimeter on Top surfaces"
+msgstr "Seulement un périmètre autoir des surfaces du dessus"
-#: src/libslic3r/PrintConfig.cpp:3093
-msgid "Rotate around X"
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Fill"
+msgstr "Remplissage"
-#: src/libslic3r/PrintConfig.cpp:3094
-msgid "Rotation angle around the X axis in degrees (0-360, default: 0)."
-msgstr ""
+#: supermerill's add: PrintConfig.cpp
+msgid "Do not connect infill lines to each other"
+msgstr "Ne pas connecter les lignes de remplissage entre elles"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Algorithm"
+msgstr "Algorithme"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Sparse"
+msgstr "Epars"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Exact last layer height"
+msgstr "Mettre la dernière tranche à la heuteur exacte"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Minimum perimeters"
+msgstr "Nombre min de périmètres"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Only on bridged areas"
+msgstr "Seulement sur ponts"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Solid first layer"
+msgstr "Première couche pleine"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Travel move reduced"
+msgstr "Moins de déplacements"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Hidden"
+msgstr "Cachée"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Small"
+msgstr "Fins"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Solid"
+msgstr "Plein"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Interface"
+msgstr "Interface"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Top solid"
+msgstr "Plein du dessus"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "All layers"
+msgstr "Toutes les couches"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Holes"
+msgstr "Trous"
+
+#: tooltips
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Remove small gaps"
+msgstr "Retire les mini-espaces/imperfections"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Remove the small gaps in the 3D model when slicing. Disable it if you "
+ "are very confident on your model, or you want to print an item with a geometry "
+ "designed for vase mode."
+msgstr "Retire touts les petits trous et espaces (imperfections) qui peuvent être présent sur le modèle. A ne décocher que si le modèle 3D à été crée exprès, pour le mode vase."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "This fan speed is enforced during all top fills."
+msgstr "Cette vitesse de ventilation est utilisé pour toutes les surface du dessus."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "This factor affects the amount of plastic to overextrude "
+ "when we are filling on top of a bridge surface."
+ "With a number >1, we can retrieve a correct z-height "
+ "even if the bridged layer has fallen a bit. "
+ "It's useful if you want to have a nice flat top layer."
+msgstr "Ce paramètre affecxte la quantité de matière déposée au-dessus des ponts. Sachant que les ponts s'affaissent un peu, avec un paramètre légèrement supérieur à 1, on peut revenir à la bonne hauteur. C'est surtotu utile si on veut obtenir des surfaces supérieure bien plate et jolie."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "The first layer will be grown / shrunk in the XY plane by the configured value "
+ "to compensate for the 1st layer squish aka an Elephant Foot effect. (should be negative = inwards)"
+msgstr "La première couche est agrandie / rétrécie en XY par cette valeur pour compenser la déformation de la première couche. (negatif = vers l'intérieur de la pièce, positif = vers l'extérieur) !!! Devrait être négative (<0) afin de rétrécir la pièce !!!"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Fill pattern for top infill. This only affects the top external visible layer, and not its adjacent solid shells."
+msgstr "Motif pour les surfaces du dessus. Ceci affecte seulement la couche externe visible, et non les coques pleines adjacentes."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells."
+msgstr "Motif pour les surfaces du dessous. Ceci affecte seulement la couche externe visible, et non les coques pleines adjacentes."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Experimental option which modifies (in solid infill) fill flow to have the exact amount of plastic inside the volume to fill "
+ "(it generally changes the flow from -7% to +4%, depending on the size of the surface to fill and the overlap parameters, "
+ "but it can go as high as +50% for infill in very small areas where rectilinear doesn't have good coverage). It has the advantage "
+ "to remove the over-extrusion seen in thin infill areas, from the overlap ratio"
+msgstr "Option expérimentale qui modifie le débit dans les couches pleines pour s'assurer que le volume extrudé est égal au volume à remplir. En génral, le débit n'ets modifié que de 4-7% mais cela peut aller jusqu'a +50% dans les très petites zones où il est difficile de circuler. Le pricipal avantage est de retirer l'effet de sur-extrusion souvent vues dans les zones de remplissage étroites."
+
+#: supermerill's add: PrintConfig.cpp
+msgid This parameter grows the top/bottom/solid layers by the specified MM to anchor them into the part. Put 0 to deactivate it."
+msgstr "Ce paramètre agrandi les couches pleines par X mm pour bien les ancrer dans la pièce. Mettre 0 pour désactiver cette fonction."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "This parameter grows the bridged solid infill layers by the specified MM to anchor them into the part. Put 0 to deactivate it."
+msgstr "Ce paramètre agrandi les couches de pont par X mm pour bien les ancrer dans la pièce. Mettre 0 pour désactiver cette fonction."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Join the perimeters to create only one continuous extrusion without any z-hop."
+ " Long inside travel (from external to holes) are not extruded to give some space to the infill."
+msgstr "Rabouter les périmètres pour en créer une unique et longue extrusion. Lors d'un passage de périmètre extérieur vers intérieur, si l'espace est grand, un déplacemnt sera tout de même utilisé."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Position of perimeters starting points."
+msgstr "Position des point de départ des jonctions entre périmètres"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Use only one perimeter on flat top surface, to let more space to the top infill pattern."
+msgstr "Utiliser seulement une seule ligne de périmètre sur les surfaces du dessus, afin de laisser le plus de place possible au motif de remplissage du dessus."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "If expressed as absolute value in mm/s, this speed will be applied to all the print moves "
+ "but infill of the first layer, it can be overwrite by the 'default' (default depends of the type of the path) "
+ "speed if it's lower than that. If expressed as a percentage "
+ "(for example: 40%) it will scale the 'default' speeds."
+msgstr "Si exprimée avec une valeur absolue en mm/s, cette vitesse sera appliquée à toutes les impressions de la première couche, sauf les remplissages (et si la vitesse par défaut est plus petite, elle sera utilisée à la place). Si exprimée comme un pourcentage (par exemple 40%), cela modulera la vitesse par défaut."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "If expressed as absolute value in mm/s, this speed will be applied to infill moves "
+ "of the first layer, it can be overwrite by the 'default' (solid infill or infill if not bottom) "
+ "speed if it's lower than that. If expressed as a percentage "
+ "(for example: 40%) it will scale the 'default' speed."
+msgstr "Si exprimée avec une valeur absolue en mm/s, cette vitesse sera appliquée aux impressions de remplissage de la première couche (et si la vitesse par défaut est plus petite, elle sera utilisée à la place). Si exprimée comme un pourcentage (par exemple 40%), cela modulera la vitesse par défaut."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Enable gap fill algorithm. It will extrude small lines between perimeters "
+ "when there is not enough space for another perimeter or an infill."
+msgstr "Active les impression de remplissage des petits trous qui peuvent subsister entre les périmètres et sui sont trop petits pour faire du remplissage."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Enables the creation of a support layer under the first solid layer. This allows you to use a lower infill ratio without compromising the top quality."
+ " The dense infill is laid out with a 50% infill density."
+msgstr "Active le remplacement du motif de remplissage sous les remplissage plein afin de permettre un meilleur support de ceux-ci. Cela permet de choisir un ratio de remplissage plus petit."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "If checked, the infill algorithm will try to not connect the lines near the infill. Can be useful for art or with high infill/perimeter overlap."
+msgstr "Si coché, l'algorithme de dessin des patrons de remplissage va essayer de ne pas connecter ses lignes entre elles, en bordure des périmètres."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Choose the way the dense layer is lay out."
+ " The automatic option let it try to draw the smallest surface with only strait lines inside the sparse infill."
+ " The anchored just enlarge a bit (by bridged anchor) the surfaces that need a better support."
+msgstr "Choisissez la façon dont la couche de support est dessinée. L'option eutomatique essayera de trouver une surface sans virage au milieu du vide. L'option ancrée utilisera une surface un peu plus grande que celle supoortée."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Automatic"
+msgstr "Automatique"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Automatic, only for small areas"
+msgstr "Automatique, sur les zones étroites"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Anchored"
+msgstr "Ancré"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "This setting controls the height of last object layers to put the last layer at the exact highest height possible. Experimental."
+msgstr "Ce paramètre fonctionne mal, ne l'utilisez pas. Il aurait dû placer la dernière couche exactement à la hauteur de l'objet, mais ça marche mal."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Experimental option to remove perimeters where there is nothing under it and where a bridged infill should be better. Computationally intensive!"
+msgstr "option très expérimentale pour permettre de ne pas mettre de périmètres s'il n'y a pas de couches en support en-dessous."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Number of perimeters exluded from this option."
+msgstr "Nombre de périmètre qui ne sont pas retirés par cette fonction"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Only remove perimeters over areas marked as 'bridge'. Can be useful to let perimeter run over overhangs, but it's not very reliable."
+msgstr "Ne retirer les périmètres qu'au dessus des endroit où il peut y avoir des ponts. Utile pour garder les surplombs."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Use a solid layer instead of a raft for the layer that touch the build plate."
+msgstr "Dépose une couche peinle sur le plateur à la place d'un quadriallage."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Add a big cost to travel paths when possible (when going into a loop), so it will prefer a less optimal seam posistion if it's nearer."
+msgstr "Ajoute un fort coût aux déplacement pour les minimiser davantage."
+
+#: supermerill's add: PrintConfig.cpp
+msgid "The convex holes will be grown / shrunk in the XY plane by the configured value"
+ " (negative = inwards, positive = outwards, should be positive as the holes are always a bit smaller)."
+ " This might be useful for fine-tuning hole sizes."
+msgstr "Les trous convexes vont être agrandis/rétécis en XY par cette valeur pour compenser la rétractation du palstique. (negatif = vers l'intérieur de la pièce, positif = vers l'extérieur) !!! Devrait être négative (<0) afin d'agrandir le trou!!!"
+
+#: supermerill's add: PrintConfig.cpp
+msgid "Invalid value for --over-bridge-flow-ratio"
+msgstr "Valeur invalide pour --over-bridge-flow-ratio"
+
+#: supermerill's add: others Tab.hpp
+msgid "Hardware Settings"
+msgstr "Paramètres du matériel"
-#: src/libslic3r/PrintConfig.cpp:3099
-msgid "Rotate around Y"
-msgstr ""
+msgid "Rectilinear"
+msgstr "Rectilinéaire"
-#: src/libslic3r/PrintConfig.cpp:3100
-msgid "Rotation angle around the Y axis in degrees (0-360, default: 0)."
-msgstr ""
+msgid "Grid"
+msgstr "Grille"
-#: src/libslic3r/PrintConfig.cpp:3105
-msgid "Save config file"
-msgstr ""
+msgid "Stars"
+msgstr "Etoiles"
-#: src/libslic3r/PrintConfig.cpp:3106
-msgid "Save configuration to the specified file."
-msgstr ""
+msgid "Cubic"
+msgstr "Tri-Cubique"
-#: src/libslic3r/PrintConfig.cpp:3112
-msgid "Scaling factor (default: 1)."
-msgstr ""
+msgid "Line"
+msgstr "Lignes"
-#: src/libslic3r/PrintConfig.cpp:3125
-msgid "Print center"
-msgstr ""
+msgid "Concentric"
+msgstr "Concentrique"
-#: src/libslic3r/PrintConfig.cpp:3126
-msgid "Center the print around the given center (default: 100, 100)."
-msgstr ""
+msgid "Honeycomb"
+msgstr "Hexagones"
-#: src/libslic3r/GCode/PreviewData.cpp:176
-msgid "Mixed"
-msgstr ""
+msgid "3D Honeycomb"
+msgstr "Hexagonal 3D"
-#: src/libslic3r/GCode/PreviewData.cpp:396
-msgid "Height (mm)"
-msgstr "Hauteur (mm)"
+msgid "Gyroid"
+msgstr "Gyroide"
-#: src/libslic3r/GCode/PreviewData.cpp:398
-msgid "Width (mm)"
-msgstr "Largeur (mm)"
+msgid "Hilbert Curve"
+msgstr "Hilbert (Fractale)"
-#: src/libslic3r/GCode/PreviewData.cpp:400
-msgid "Speed (mm/s)"
-msgstr "Vitesse (mm/s)"
+msgid "Ironing"
+msgstr "Lissée"
-#: src/libslic3r/GCode/PreviewData.cpp:402
-msgid "Volumetric flow rate (mm3/s)"
-msgstr "Débit volumétrique (mm3/s)"
+msgid "Concentric"
+msgstr "Concentrique"
-#: src/libslic3r/GCode/PreviewData.cpp:491
-msgid "Default print color"
-msgstr ""
+msgid "Nearest"
+msgstr "Au plus près"
-#: src/libslic3r/GCode/PreviewData.cpp:495
-#, c-format
-msgid "up to %.2f mm"
-msgstr ""
+msgid "Random"
+msgstr "Aléatoire"
-#: src/libslic3r/GCode/PreviewData.cpp:499
-#, c-format
-msgid "above %.2f mm"
-msgstr ""
+msgid "Aligned"
+msgstr "Aligné"
-#: src/libslic3r/GCode/PreviewData.cpp:504
-#, c-format
-msgid "%.2f - %.2f mm"
-msgstr ""
+msgid "Concentric"
+msgstr "Concentrique"
diff --git a/resources/localization/zh_CN/Slic3rPE_zh.po b/resources/localization/zh_CN/Slic3rPE_zh.po
index 5c1df8478..b48ca4b0b 100644
--- a/resources/localization/zh_CN/Slic3rPE_zh.po
+++ b/resources/localization/zh_CN/Slic3rPE_zh.po
@@ -3017,7 +3017,7 @@ msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:66
msgid ""
-" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"
+" - Remember to check for updates at http://github.com/supermerill/slic3r/releases"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:118
@@ -3289,11 +3289,11 @@ msgid "Open the Prusa3D drivers download page in your browser"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:388
-msgid "Prusa Edition Releases"
+msgid "Slic3r++ Releases"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:388
-msgid "Open the Prusa Edition releases page in your browser"
+msgid "Open the Slic3r++ releases page in your browser"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:395
@@ -3325,7 +3325,7 @@ msgid "Report an Issue"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:405
-msgid "Report an issue on the Slic3r Prusa Edition"
+msgid "Report an issue on the Slic3r Slic3r++"
msgstr ""
#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:408
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index 57c401419..60f0a0499 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -60,6 +60,7 @@ avoid_crossing_perimeters = 0
bridge_acceleration = 1000
bridge_angle = 0
bridge_flow_ratio = 0.8
+over_bridge_flow_ratio = 1.2
bridge_speed = 20
brim_width = 0
clip_multipart_objects = 1
@@ -69,10 +70,12 @@ default_acceleration = 1000
dont_support_bridges = 1
elefant_foot_compensation = 0
ensure_vertical_shell_thickness = 1
-external_fill_pattern = rectilinear
+top_fill_pattern = rectilinear
+bottom_fill_pattern = rectilinear
external_perimeters_first = 0
external_perimeter_extrusion_width = 0.45
extra_perimeters = 0
+only_one_perimeter_top = 0
extruder_clearance_height = 20
extruder_clearance_radius = 20
extrusion_width = 0.45
diff --git a/src/avrdude/main.c b/src/avrdude/main.c
index 9ada27be3..2518b7e12 100644
--- a/src/avrdude/main.c
+++ b/src/avrdude/main.c
@@ -56,7 +56,7 @@
/* Get VERSION from ac_cfg.h */
-char * version = VERSION "-prusa3d";
+char * version = VERSION "++";
char * progname;
char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
diff --git a/src/libslic3r/BridgeDetector.cpp b/src/libslic3r/BridgeDetector.cpp
index ccc3505ce..6fa2ea649 100644
--- a/src/libslic3r/BridgeDetector.cpp
+++ b/src/libslic3r/BridgeDetector.cpp
@@ -115,6 +115,7 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
}
double total_length = 0;
+ uint32_t nbLines = 0;
double max_length = 0;
{
Lines clipped_lines = intersection_ln(lines, clip_area);
@@ -125,10 +126,11 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
double len = line.length();
total_length += len;
max_length = std::max(max_length, len);
+ nbLines++;
}
}
}
- if (total_length == 0.)
+ if (total_length == 0. || nbLines == 0)
continue;
have_coverage = true;
@@ -139,6 +141,7 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
// $directions_coverage{$angle} = sum(map $_->area, @{$self->coverage($angle)}) // 0;
// max length of bridged lines
candidates[i_angle].max_length = max_length;
+ candidates[i_angle].mean_length = total_length / nbLines;
}
// if no direction produced coverage, then there's no bridge direction
@@ -149,10 +152,12 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
std::sort(candidates.begin(), candidates.end());
// if any other direction is within extrusion width of coverage, prefer it if shorter
+ // shorter = shorter max length, or if in espilon (10) range, the shorter mean length.
// TODO: There are two options here - within width of the angle with most coverage, or within width of the currently perferred?
size_t i_best = 0;
for (size_t i = 1; i < candidates.size() && candidates[i_best].coverage - candidates[i].coverage < this->spacing; ++ i)
- if (candidates[i].max_length < candidates[i_best].max_length)
+ if (candidates[i].max_length < candidates[i_best].max_length ||
+ (candidates[i].max_length < candidates[i_best].max_length - 10 && candidates[i].mean_length < candidates[i_best].mean_length))
i_best = i;
this->angle = candidates[i_best].angle;
@@ -203,8 +208,8 @@ std::vector<double> BridgeDetector::bridge_direction_candidates() const
return angles;
}
-Polygons BridgeDetector::coverage(double angle) const
-{
+Polygons BridgeDetector::coverage(double angle, bool precise) const {
+
if (angle == -1)
angle = this->angle;
@@ -213,52 +218,92 @@ Polygons BridgeDetector::coverage(double angle) const
if (angle != -1) {
// Get anchors, convert them to Polygons and rotate them.
Polygons anchors = to_polygons(this->_anchor_regions);
- polygons_rotate(anchors, PI/2.0 - angle);
-
+ polygons_rotate(anchors, PI / 2.0 - angle);
+ //same for region which do not need bridging
+ //Polygons supported_area = diff(this->lower_slices.expolygons, this->_anchor_regions, true);
+ //polygons_rotate(anchors, PI / 2.0 - angle);
+
for (ExPolygon expolygon : this->expolygons) {
// Clone our expolygon and rotate it so that we work with vertical lines.
- expolygon.rotate(PI/2.0 - angle);
+ expolygon.rotate(PI / 2.0 - angle);
// Outset the bridge expolygon by half the amount we used for detecting anchors;
// we'll use this one to generate our trapezoids and be sure that their vertices
// are inside the anchors and not on their contours leading to false negatives.
for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) {
// Compute trapezoids according to a vertical orientation
Polygons trapezoids;
- expoly.get_trapezoids2(&trapezoids, PI/2.0);
- for (const Polygon &trapezoid : trapezoids) {
+ if (!precise) expoly.get_trapezoids2(&trapezoids, PI / 2);
+ else expoly.get_trapezoids3_half(&trapezoids, float(this->spacing));
+ for (Polygon &trapezoid : trapezoids) {
// not nice, we need a more robust non-numeric check
+ // imporvment 1: take into account when we go in the supported area.
size_t n_supported = 0;
- for (const Line &supported_line : intersection_ln(trapezoid.lines(), anchors))
- if (supported_line.length() >= this->spacing)
- ++ n_supported;
- if (n_supported >= 2)
+ if (!precise) {
+ for (const Line &supported_line : intersection_ln(trapezoid.lines(), anchors))
+ if (supported_line.length() >= this->spacing)
+ ++n_supported;
+ } else {
+ Polygons intersects = intersection(trapezoid, anchors);
+ n_supported = intersects.size();
+
+ if (n_supported >= 2) {
+ // trim it to not allow to go outside of the intersections
+ BoundingBox center_bound = intersects[0].bounding_box();
+ coord_t min_y = center_bound.center()(1), max_y = center_bound.center()(1);
+ for (Polygon &poly_bound : intersects) {
+ center_bound = poly_bound.bounding_box();
+ if (min_y > center_bound.center()(1)) min_y = center_bound.center()(1);
+ if (max_y < center_bound.center()(1)) max_y = center_bound.center()(1);
+ }
+ coord_t min_x = trapezoid[0](0), max_x = trapezoid[0](0);
+ for (Point &p : trapezoid.points) {
+ if (min_x > p(0)) min_x = p(0);
+ if (max_x < p(0)) max_x = p(0);
+ }
+ //add what get_trapezoids3 has removed (+EPSILON)
+ min_x -= (this->spacing / 4 + 1);
+ max_x += (this->spacing / 4 + 1);
+ coord_t mid_x = (min_x + max_x) / 2;
+ for (Point &p : trapezoid.points) {
+ if (p(1) < min_y) p(1) = min_y;
+ if (p(1) > max_y) p(1) = max_y;
+ if (p(0) > min_x && p(0) < mid_x) p(0) = min_x;
+ if (p(0) < max_x && p(0) > mid_x) p(0) = max_x;
+ }
+ }
+ }
+
+ if (n_supported >= 2) {
+ //add it
covered.push_back(std::move(trapezoid));
+ }
}
}
}
- // Unite the trapezoids before rotation, as the rotation creates tiny gaps and intersections between the trapezoids
- // instead of exact overlaps.
- covered = union_(covered);
- // Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
- polygons_rotate(covered, -(PI/2.0 - angle));
- covered = intersection(covered, to_polygons(this->expolygons));
+ // Unite the trapezoids before rotation, as the rotation creates tiny gaps and intersections between the trapezoids
+ // instead of exact overlaps.
+ covered = union_(covered);
+ // Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
+ polygons_rotate(covered, -(PI/2.0 - angle));
+ covered = intersection(covered, to_polygons(this->expolygons));
#if 0
- {
- my @lines = map @{$_->lines}, @$trapezoids;
- $_->rotate(-(PI/2 - $angle), [0,0]) for @lines;
-
- require "Slic3r/SVG.pm";
- Slic3r::SVG::output(
- "coverage_" . rad2deg($angle) . ".svg",
- expolygons => [$self->expolygon],
- green_expolygons => $self->_anchor_regions,
- red_expolygons => $coverage,
- lines => \@lines,
- );
+ {
+ my @lines = map @{$_->lines}, @$trapezoids;
+ $_->rotate(-(PI/2 - $angle), [0,0]) for @lines;
+
+ require "Slic3r/SVG.pm";
+ Slic3r::SVG::output(
+ "coverage_" . rad2deg($angle) . ".svg",
+ expolygons => [$self->expolygon],
+ green_expolygons => $self->_anchor_regions,
+ red_expolygons => $coverage,
+ lines => \@lines,
+ );
}
#endif
}
+
return covered;
}
diff --git a/src/libslic3r/BridgeDetector.hpp b/src/libslic3r/BridgeDetector.hpp
index 5c55276be..0c08546ac 100644
--- a/src/libslic3r/BridgeDetector.hpp
+++ b/src/libslic3r/BridgeDetector.hpp
@@ -33,7 +33,7 @@ public:
BridgeDetector(const ExPolygons &_expolygons, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
// If bridge_direction_override != 0, then the angle is used instead of auto-detect.
bool detect_angle(double bridge_direction_override = 0.);
- Polygons coverage(double angle = -1) const;
+ Polygons coverage(double angle = -1, bool precise = false) const;
void unsupported_edges(double angle, Polylines* unsupported) const;
Polylines unsupported_edges(double angle = -1) const;
@@ -53,8 +53,9 @@ private:
double angle;
double coverage;
double max_length;
+ double mean_length;
};
-
+public:
// Get possible briging direction candidates.
std::vector<double> bridge_direction_candidates() const;
diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index baf860bd4..069521ee0 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -51,6 +51,8 @@ add_library(libslic3r STATIC
Fill/FillRectilinear2.hpp
Fill/FillRectilinear3.cpp
Fill/FillRectilinear3.hpp
+ Fill/FillSmooth.cpp
+ Fill/FillSmooth.hpp
Flow.cpp
Flow.hpp
Format/3mf.cpp
@@ -105,6 +107,8 @@ add_library(libslic3r STATIC
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
Line.cpp
Line.hpp
+ MedialAxis.cpp
+ MedialAxis.hpp
Model.cpp
Model.hpp
ModelArrange.hpp
diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp
index a5ab4e99b..cd3dc165d 100644
--- a/src/libslic3r/ClipperUtils.hpp
+++ b/src/libslic3r/ClipperUtils.hpp
@@ -213,6 +213,14 @@ inline Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject, bool safety_
return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject), Slic3r::Polygons(), safety_offset_);
}
+inline Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject1, const Slic3r::ExPolygons &subject2, bool safety_offset_ = false) {
+ Polygons poly_union;
+ polygons_append(poly_union, to_polygons(subject1));
+ polygons_append(poly_union, to_polygons(subject2));
+ return _clipper_ex(ClipperLib::ctUnion, poly_union, Slic3r::Polygons(), safety_offset_);
+ //OR that, i don't know what is the best
+ //return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject1), to_polygons(subject2), safety_offset_);
+}
ClipperLib::PolyTree union_pt(const Slic3r::Polygons &subject, bool safety_offset_ = false);
Slic3r::Polygons union_pt_chained(const Slic3r::Polygons &subject, bool safety_offset_ = false);
diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp
index f9c470450..d0f6d3fdc 100644
--- a/src/libslic3r/ExPolygon.cpp
+++ b/src/libslic3r/ExPolygon.cpp
@@ -1,5 +1,6 @@
#include "BoundingBox.hpp"
#include "ExPolygon.hpp"
+#include "MedialAxis.hpp"
#include "Geometry.hpp"
#include "Polygon.hpp"
#include "Line.hpp"
@@ -152,13 +153,15 @@ ExPolygon::overlaps(const ExPolygon &other) const
return ! other.contour.points.empty() && this->contains_b(other.contour.points.front());
}
-void ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
+void
+ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
{
Polygons pp = this->simplify_p(tolerance);
polygons->insert(polygons->end(), pp.begin(), pp.end());
}
-Polygons ExPolygon::simplify_p(double tolerance) const
+Polygons
+ExPolygon::simplify_p(double tolerance) const
{
Polygons pp;
pp.reserve(this->holes.size() + 1);
@@ -180,133 +183,53 @@ Polygons ExPolygon::simplify_p(double tolerance) const
return simplify_polygons(pp);
}
-ExPolygons ExPolygon::simplify(double tolerance) const
+ExPolygons
+ExPolygon::simplify(double tolerance) const
{
return union_ex(this->simplify_p(tolerance));
}
-void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const
+void
+ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const
{
append(*expolygons, this->simplify(tolerance));
}
+/// remove point that are at SCALED_EPSILON * 2 distance.
+//simplier than simplify
void
-ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polylines) const
-{
- // init helper object
- Slic3r::Geometry::MedialAxis ma(max_width, min_width, this);
- ma.lines = this->lines();
-
- // compute the Voronoi diagram and extract medial axis polylines
- ThickPolylines pp;
- ma.build(&pp);
-
- /*
- SVG svg("medial_axis.svg");
- svg.draw(*this);
- svg.draw(pp);
- svg.Close();
- */
-
- /* Find the maximum width returned; we're going to use this for validating and
- filtering the output segments. */
- double max_w = 0;
- for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it)
- max_w = fmaxf(max_w, *std::max_element(it->width.begin(), it->width.end()));
-
- /* Loop through all returned polylines in order to extend their endpoints to the
- expolygon boundaries */
- bool removed = false;
- for (size_t i = 0; i < pp.size(); ++i) {
- ThickPolyline& polyline = pp[i];
-
- // extend initial and final segments of each polyline if they're actual endpoints
- /* We assign new endpoints to temporary variables because in case of a single-line
- polyline, after we extend the start point it will be caught by the intersection()
- call, so we keep the inner point until we perform the second intersection() as well */
- Point new_front = polyline.points.front();
- Point new_back = polyline.points.back();
- if (polyline.endpoints.first && !this->has_boundary_point(new_front)) {
- Vec2d p1 = polyline.points.front().cast<double>();
- Vec2d p2 = polyline.points[1].cast<double>();
- // prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2)
- p2 = (p1 + p2) * 0.5;
- // Extend the start of the segment.
- p1 -= (p2 - p1).normalized() * max_width;
- this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_front);
- }
- if (polyline.endpoints.second && !this->has_boundary_point(new_back)) {
- Vec2d p1 = (polyline.points.end() - 2)->cast<double>();
- Vec2d p2 = polyline.points.back().cast<double>();
- // prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2)
- p1 = (p1 + p2) * 0.5;
- // Extend the start of the segment.
- p2 += (p2 - p1).normalized() * max_width;
- this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_back);
+ExPolygon::remove_point_too_near(const coord_t tolerance) {
+ size_t id = 1;
+ while (id < this->contour.points.size() - 1) {
+ size_t newdist = min(this->contour.points[id].distance_to(this->contour.points[id - 1])
+ , this->contour.points[id].distance_to(this->contour.points[id + 1]));
+ if (newdist < tolerance) {
+ this->contour.points.erase(this->contour.points.begin() + id);
+ newdist = this->contour.points[id].distance_to(this->contour.points[id - 1]);
}
- polyline.points.front() = new_front;
- polyline.points.back() = new_back;
-
- /* remove too short polylines
- (we can't do this check before endpoints extension and clipping because we don't
- know how long will the endpoints be extended since it depends on polygon thickness
- which is variable - extension will be <= max_width/2 on each side) */
- if ((polyline.endpoints.first || polyline.endpoints.second)
- && polyline.length() < max_w*2) {
- pp.erase(pp.begin() + i);
- --i;
- removed = true;
- continue;
+ //go to next one
+ //if you removed a point, it check if the next one isn't too near from the previous one.
+ // if not, it byepass it.
+ if (newdist > tolerance) {
+ ++id;
}
}
-
- /* If we removed any short polylines we now try to connect consecutive polylines
- in order to allow loop detection. Note that this algorithm is greedier than
- MedialAxis::process_edge_neighbors() as it will connect random pairs of
- polylines even when more than two start from the same point. This has no
- drawbacks since we optimize later using nearest-neighbor which would do the
- same, but should we use a more sophisticated optimization algorithm we should
- not connect polylines when more than two meet. */
- if (removed) {
- for (size_t i = 0; i < pp.size(); ++i) {
- ThickPolyline& polyline = pp[i];
- if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization
-
- // find another polyline starting here
- for (size_t j = i+1; j < pp.size(); ++j) {
- ThickPolyline& other = pp[j];
- if (polyline.last_point() == other.last_point()) {
- other.reverse();
- } else if (polyline.first_point() == other.last_point()) {
- polyline.reverse();
- other.reverse();
- } else if (polyline.first_point() == other.first_point()) {
- polyline.reverse();
- } else if (polyline.last_point() != other.first_point()) {
- continue;
- }
-
- polyline.points.insert(polyline.points.end(), other.points.begin() + 1, other.points.end());
- polyline.width.insert(polyline.width.end(), other.width.begin(), other.width.end());
- polyline.endpoints.second = other.endpoints.second;
- assert(polyline.width.size() == polyline.points.size()*2 - 2);
-
- pp.erase(pp.begin() + j);
- j = i; // restart search from i+1
- }
- }
+ if (this->contour.points.front().distance_to(this->contour.points.back()) < tolerance) {
+ this->contour.points.erase(this->contour.points.end() -1);
}
-
- polylines->insert(polylines->end(), pp.begin(), pp.end());
+}
+
+void
+ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines, double height) const {
+ Slic3r::MedialAxis ma(*this, bounds, max_width, min_width, height);
+ ma.build(polylines);
}
void
ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines) const
{
ThickPolylines tp;
- this->medial_axis(max_width, min_width, &tp);
+ this->medial_axis(*this, max_width, min_width, &tp, max_width/2.0);
polylines->insert(polylines->end(), tp.begin(), tp.end());
}
@@ -372,10 +295,57 @@ void ExPolygon::get_trapezoids2(Polygons* polygons) const
void ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const
{
ExPolygon clone = *this;
- clone.rotate(PI/2 - angle, Point(0,0));
+ clone.rotate(PI / 2 - angle, Point(0, 0));
clone.get_trapezoids2(polygons);
for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon)
- polygon->rotate(-(PI/2 - angle), Point(0,0));
+ polygon->rotate(-(PI / 2 - angle), Point(0, 0));
+}
+
+void
+ExPolygon::get_trapezoids3_half(Polygons* polygons, float spacing) const {
+
+ // get all points of this ExPolygon
+ Points pp = *this;
+
+ if (pp.empty()) return;
+
+ // build our bounding box
+ BoundingBox bb(pp);
+
+ // get all x coordinates
+ int min_x = pp[0].x(), max_x = pp[0].x();
+ std::vector<coord_t> xx;
+ for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p) {
+ if (min_x > p->x()) min_x = p->x();
+ if (max_x < p->x()) max_x = p->x();
+ }
+ for (int x = min_x; x < max_x-spacing/2; x += spacing) {
+ xx.push_back(x);
+ }
+ xx.push_back(max_x);
+ //std::sort(xx.begin(), xx.end());
+
+ // find trapezoids by looping from first to next-to-last coordinate
+ for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end() - 1; ++x) {
+ coord_t next_x = *(x + 1);
+ if (*x == next_x) continue;
+
+ // build rectangle
+ Polygon poly;
+ poly.points.resize(4);
+ poly[0].x() = *x + spacing / 4;
+ poly[0].y() = bb.min(1);
+ poly[1].x() = next_x - spacing / 4;
+ poly[1].y() = bb.min(1);
+ poly[2].x() = next_x - spacing / 4;
+ poly[2].y() = bb.max(1);
+ poly[3].x() = *x + spacing / 4;
+ poly[3].y() = bb.max(1);
+
+ // intersect with this expolygon
+ // append results to return value
+ polygons_append(*polygons, intersection(poly, to_polygons(*this)));
+ }
}
// While this triangulates successfully, it's NOT a constrained triangulation
@@ -580,17 +550,17 @@ void ExPolygon::triangulate_p2t(Polygons* polygons) const
// perform triangulation
try {
- cdt.Triangulate();
- std::vector<p2t::Triangle*> triangles = cdt.GetTriangles();
-
- for (std::vector<p2t::Triangle*>::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) {
- Polygon p;
- for (int i = 0; i <= 2; ++i) {
- p2t::Point* point = (*triangle)->GetPoint(i);
- p.points.push_back(Point(point->x, point->y));
- }
- polygons->push_back(p);
+ cdt.Triangulate();
+ std::vector<p2t::Triangle*> triangles = cdt.GetTriangles();
+
+ for (std::vector<p2t::Triangle*>::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) {
+ Polygon p;
+ for (int i = 0; i <= 2; ++i) {
+ p2t::Point* point = (*triangle)->GetPoint(i);
+ p.points.push_back(Point(point->x, point->y));
}
+ polygons->push_back(p);
+ }
} catch (const std::runtime_error & /* err */) {
assert(false);
// just ignore, don't triangulate
diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp
index afbc0931e..c5d15a5fe 100644
--- a/src/libslic3r/ExPolygon.hpp
+++ b/src/libslic3r/ExPolygon.hpp
@@ -56,12 +56,14 @@ public:
Polygons simplify_p(double tolerance) const;
ExPolygons simplify(double tolerance) const;
void simplify(double tolerance, ExPolygons* expolygons) const;
- void medial_axis(double max_width, double min_width, ThickPolylines* polylines) const;
+ void remove_point_too_near(const coord_t tolerance);
+ void medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines, double height) const;
void medial_axis(double max_width, double min_width, Polylines* polylines) const;
// void get_trapezoids(Polygons* polygons) const;
// void get_trapezoids(Polygons* polygons, double angle) const;
void get_trapezoids2(Polygons* polygons) const;
void get_trapezoids2(Polygons* polygons, double angle) const;
+ void get_trapezoids3_half(Polygons* polygons, float spacing) const;
void triangulate(Polygons* polygons) const;
// Triangulate into triples of points.
void triangulate_pp(Points *triangles) const;
diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp
index a62a189ce..7c9495207 100644
--- a/src/libslic3r/ExtrusionEntity.hpp
+++ b/src/libslic3r/ExtrusionEntity.hpp
@@ -208,6 +208,7 @@ public:
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
};
+
// Single continuous extrusion loop, possibly with varying extrusion thickness, extrusion height or bridging / non bridging.
class ExtrusionLoop : public ExtrusionEntity
{
@@ -286,9 +287,15 @@ inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines
dst.reserve(dst.size() + polylines.size());
for (Polyline &polyline : polylines)
if (polyline.is_valid()) {
- ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
- dst.push_back(extrusion_path);
- extrusion_path->polyline = polyline;
+ if (polyline.points.back() == polyline.points.front()) {
+ ExtrusionPath path(role, mm3_per_mm, width, height);
+ path.polyline.points = polyline.points;
+ dst.emplace_back(new ExtrusionLoop(std::move(path)));
+ } else {
+ ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
+ dst.push_back(extrusion_path);
+ extrusion_path->polyline = polyline;
+ }
}
}
@@ -297,13 +304,31 @@ inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines
dst.reserve(dst.size() + polylines.size());
for (Polyline &polyline : polylines)
if (polyline.is_valid()) {
- ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
- dst.push_back(extrusion_path);
- extrusion_path->polyline = std::move(polyline);
+ if (polyline.points.back() == polyline.points.front()) {
+ ExtrusionPath path(role, mm3_per_mm, width, height);
+ path.polyline.points = polyline.points;
+ dst.emplace_back(new ExtrusionLoop(std::move(path)));
+ } else {
+ ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height);
+ dst.push_back(extrusion_path);
+ extrusion_path->polyline = std::move(polyline);
+ }
}
polylines.clear();
}
+inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &loops, ExtrusionRole role, double mm3_per_mm, float width, float height) {
+ dst.reserve(dst.size() + loops.size());
+ for (Polygon &poly : loops) {
+ if (poly.is_valid()) {
+ ExtrusionPath path(role, mm3_per_mm, width, height);
+ path.polyline.points = poly.points;
+ path.polyline.points.push_back(path.polyline.points.front());
+ dst.emplace_back(new ExtrusionLoop(std::move(path)));
+ }
+ }
+}
+
inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &&loops, ExtrusionRole role, double mm3_per_mm, float width, float height)
{
dst.reserve(dst.size() + loops.size());
diff --git a/src/libslic3r/ExtrusionEntityCollection.cpp b/src/libslic3r/ExtrusionEntityCollection.cpp
index 7a086bcbf..c54541a7d 100644
--- a/src/libslic3r/ExtrusionEntityCollection.cpp
+++ b/src/libslic3r/ExtrusionEntityCollection.cpp
@@ -118,7 +118,7 @@ void ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEnt
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
if (role != erMixed) {
// The caller wants only paths with a specific extrusion role.
- auto role2 = (*it)->role();
+ ExtrusionRole role2 = (*it)->role();
if (role != role2) {
// This extrusion entity does not match the role asked.
assert(role2 != erMixed);
@@ -208,6 +208,45 @@ ExtrusionEntityCollection::flatten() const
return coll;
}
+/* Returns a vector of chained (new) pointers to all non-collection items contained in this one */
+void
+ExtrusionEntityCollection::flattenIfSortable(ExtrusionEntityCollection* retval) const
+{
+ if (no_sort){
+ ExtrusionEntityCollection *unsortable = new ExtrusionEntityCollection(*this);
+ retval->append(*unsortable);
+ unsortable->entities.clear();
+ for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
+ if ((*it)->is_collection()) {
+ ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
+ collection->flattenIfSortable(unsortable);
+ }
+ else {
+ unsortable->append(**it);
+ }
+ }
+ }
+ else{
+ for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
+ if ((*it)->is_collection()) {
+ ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
+ retval->append(collection->flattenIfSortable().entities);
+ }
+ else {
+ retval->append(**it);
+ }
+ }
+ }
+}
+
+ExtrusionEntityCollection
+ExtrusionEntityCollection::flattenIfSortable() const
+{
+ ExtrusionEntityCollection coll;
+ this->flattenIfSortable(&coll);
+ return coll;
+}
+
double
ExtrusionEntityCollection::min_mm3_per_mm() const
{
diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp
index 230c04160..d65d307ef 100644
--- a/src/libslic3r/ExtrusionEntityCollection.hpp
+++ b/src/libslic3r/ExtrusionEntityCollection.hpp
@@ -82,7 +82,9 @@ public:
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
size_t items_count() const;
void flatten(ExtrusionEntityCollection* retval) const;
- ExtrusionEntityCollection flatten() const;
+ ExtrusionEntityCollection flatten() const;
+ void flattenIfSortable(ExtrusionEntityCollection* retval) const;
+ ExtrusionEntityCollection flattenIfSortable() const;
double min_mm3_per_mm() const;
double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 016d162d8..ce5ff7a91 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -34,10 +34,11 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
{
// Slic3r::debugf "Filling layer %d:\n", $layerm->layer->id;
- double fill_density = layerm.region()->config().fill_density;
- Flow infill_flow = layerm.flow(frInfill);
- Flow solid_infill_flow = layerm.flow(frSolidInfill);
- Flow top_solid_infill_flow = layerm.flow(frTopSolidInfill);
+ double fill_density = layerm.region()->config().fill_density;
+ Flow infill_flow = layerm.flow(frInfill);
+ Flow solid_infill_flow = layerm.flow(frSolidInfill);
+ Flow top_solid_infill_flow = layerm.flow(frTopSolidInfill);
+ const float perimeter_spacing = layerm.flow(frPerimeter).spacing();
Surfaces surfaces;
@@ -56,6 +57,39 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
//FIXME: Use some smart heuristics to merge similar surfaces to eliminate tiny regions.
std::vector<SurfacesPtr> groups;
layerm.fill_surfaces.group(&groups);
+
+ //if internal infill can be dense, place it on his own group
+ if (layerm.region()->config().infill_dense.getBool() && layerm.region()->config().fill_density<40) {
+ SurfacesPtr *denseGroup = NULL;
+ const uint32_t nbGroups = groups.size();
+ for (uint32_t num_group = 0; num_group < nbGroups; ++num_group) {
+ for (uint32_t num_srf = 0; num_srf < groups[num_group].size(); ++num_srf) {
+ Surface *srf = groups[num_group][num_srf];
+ //if solid, wrong group
+ if (srf->is_solid()) break;
+ //find surface that can be used as dense infill
+ if (srf->maxNbSolidLayersOnTop <= 1
+ && srf->maxNbSolidLayersOnTop > 0) {
+ //remove from the group
+ groups[num_group].erase(groups[num_group].begin() + num_srf);
+ --num_srf;
+ //add to the "dense" group
+ if (denseGroup == NULL) {
+ groups.resize(groups.size() + 1);
+ denseGroup = &groups.back();
+ }
+ denseGroup->push_back(srf);
+ }
+ }
+ }
+ //remove empty groups
+ for (size_t i = 0; i < groups.size(); ++i) {
+ if (groups[i].empty()) {
+ groups.erase(groups.begin() + i);
+ i--;
+ }
+ }
+ }
// merge compatible groups (we can generate continuous infill for them)
{
@@ -63,13 +97,14 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// (we'll use them for comparing compatible groups)
std::vector<SurfaceGroupAttrib> group_attrib(groups.size());
for (size_t i = 0; i < groups.size(); ++ i) {
- // we can only merge solid non-bridge surfaces, so discard
+ // we can only merge solid non-bridge non-overextruded surfaces, so discard
// non-solid surfaces
const Surface &surface = *groups[i].front();
- if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0)) {
+ if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0) && !surface.is_overBridge()) {
group_attrib[i].is_solid = true;
- group_attrib[i].flow_width = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width;
- group_attrib[i].pattern = surface.is_external() ? layerm.region()->config().external_fill_pattern.value : ipRectilinear;
+ group_attrib[i].flow_width = (surface.is_top()) ? top_solid_infill_flow.width : solid_infill_flow.width;
+ group_attrib[i].pattern = (surface.is_top() && surface.is_external()) ? layerm.region()->config().top_fill_pattern.value : ipRectilinear;
+ group_attrib[i].pattern = (surface.is_bottom() && surface.is_external()) ? layerm.region()->config().bottom_fill_pattern.value : ipRectilinear;
}
}
// Loop through solid groups, find compatible groups and append them to this one.
@@ -90,7 +125,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// Give priority to bridges. Process the bridges in the first round, the rest of the surfaces in the 2nd round.
for (size_t round = 0; round < 2; ++ round) {
- for (std::vector<SurfacesPtr>::iterator it_group = groups.begin(); it_group != groups.end(); ++ it_group) {
+ for (std::vector<SurfacesPtr>::iterator it_group = groups.begin(); it_group != groups.end(); ++it_group) {
const SurfacesPtr &group = *it_group;
bool is_bridge = group.front()->bridge_angle >= 0;
if (is_bridge != (round == 0))
@@ -98,12 +133,13 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// Make a union of polygons defining the infiill regions of a group, use a safety offset.
Polygons union_p = union_(to_polygons(*it_group), true);
// Subtract surfaces having a defined bridge_angle from any other, use a safety offset.
- if (! polygons_bridged.empty() && ! is_bridge)
+ if (!polygons_bridged.empty() && !is_bridge)
union_p = diff(union_p, polygons_bridged, true);
// subtract any other surface already processed
//FIXME Vojtech: Because the bridge surfaces came first, they are subtracted twice!
// Using group.front() as a template.
surfaces_append(surfaces, diff_ex(union_p, to_polygons(surfaces), true), *group.front());
+
}
}
}
@@ -148,23 +184,33 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// red_expolygons => [ map $_->expolygon, grep $_->is_solid, @surfaces ],
// );
}
-
for (const Surface &surface : surfaces) {
if (surface.surface_type == stInternalVoid)
continue;
InfillPattern fill_pattern = layerm.region()->config().fill_pattern.value;
double density = fill_density;
- FlowRole role = (surface.surface_type == stTop) ? frTopSolidInfill :
+ FlowRole role = (surface.is_top()) ? frTopSolidInfill :
(surface.is_solid() ? frSolidInfill : frInfill);
bool is_bridge = layerm.layer()->id() > 0 && surface.is_bridge();
-
+ bool is_denser = false;
+
if (surface.is_solid()) {
density = 100.;
fill_pattern = (surface.is_external() && ! is_bridge) ?
- layerm.region()->config().external_fill_pattern.value :
+ (surface.is_top() ? layerm.region()->config().top_fill_pattern.value : layerm.region()->config().bottom_fill_pattern.value) :
ipRectilinear;
- } else if (density <= 0)
- continue;
+ } else {
+ if (layerm.region()->config().infill_dense.getBool()
+ && layerm.region()->config().fill_density<40
+ && surface.maxNbSolidLayersOnTop <= 1
+ && surface.maxNbSolidLayersOnTop > 0) {
+ density = 42;
+ is_denser = true;
+ fill_pattern = ipRectiWithPerimeter;
+ }
+ if (density <= 0)
+ continue;
+ }
// get filler object
std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(fill_pattern));
@@ -215,21 +261,32 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
f->layer_id = layerm.layer()->id();
f->z = layerm.layer()->print_z;
- f->angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
+ if (is_denser)f->angle = 0;
+ else f->angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
// Maximum length of the perimeter segment linking two infill lines.
f->link_max_length = scale_(link_max_length);
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
f->loop_clipping = scale_(flow.nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER;
-// f->layer_height = h;
-
+ //give the overlap size to let the infill do his overlap
+ //add overlap if at least one perimeter
+ if (layerm.region()->config().perimeters > 0) {
+ f->overlap = layerm.region()->config().get_abs_value("infill_overlap", (perimeter_spacing + (f->spacing)) / 2);
+ if (f->overlap!=0) {
+ f->no_overlap_expolygons = intersection_ex(layerm.fill_no_overlap_expolygons, ExPolygons() = { surface.expolygon });
+ } else {
+ f->no_overlap_expolygons.push_back(surface.expolygon);
+ }
+ } else {
+ f->overlap = 0;
+ f->no_overlap_expolygons.push_back(surface.expolygon);
+ }
+
// apply half spacing using this flow's own spacing and generate infill
FillParams params;
params.density = 0.01 * density;
-// params.dont_adjust = true;
params.dont_adjust = false;
- Polylines polylines = f->fill_surface(&surface, params);
- if (polylines.empty())
- continue;
+ params.fill_exactly = layerm.region()->config().enforce_full_fill_volume.getBool();
+ params.dont_connect = layerm.region()->config().infill_not_connected.getBool();
// calculate actual flow from spacing (which might have been adjusted by the infill
// pattern generator)
@@ -240,20 +297,14 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
} else {
flow = Flow::new_from_spacing(f->spacing, flow.nozzle_diameter, h, is_bridge || f->use_bridge_flow());
}
-
- // Save into layer.
- auto *eec = new ExtrusionEntityCollection();
- out.entities.push_back(eec);
- // Only concentric fills are not sorted.
- eec->no_sort = f->no_sort();
- extrusion_entities_append_paths(
- eec->entities, std::move(polylines),
- is_bridge ?
- erBridgeInfill :
- (surface.is_solid() ?
- ((surface.surface_type == stTop) ? erTopSolidInfill : erSolidInfill) :
- erInternalInfill),
- flow.mm3_per_mm(), flow.width, flow.height);
+
+ float flow_percent = 1;
+ if(surface.is_overBridge()){
+ params.density = layerm.region()->config().over_bridge_flow_ratio;
+ //params.flow_mult = layerm.region()->config().over_bridge_flow_ratio;
+ }
+
+ f->fill_surface_extrusion(&surface, params, flow, erNone, out.entities);
}
// add thin fill regions
diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp
index 6a37e4369..7da18d9e3 100644
--- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp
+++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp
@@ -161,43 +161,38 @@ void Fill3DHoneycomb::_fill_surface_single(
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it)
it->translate(bb.min(0), bb.min(1));
- // clip pattern to boundaries
- polylines = intersection_pl(polylines, (Polygons)expolygon);
-
- // connect lines
- if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
- ExPolygon expolygon_off;
- {
- ExPolygons expolygons_off = offset_ex(expolygon, SCALED_EPSILON);
- if (! expolygons_off.empty()) {
- // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
- assert(expolygons_off.size() == 1);
- std::swap(expolygon_off, expolygons_off.front());
+ // clip pattern to boundaries, keeping the polyline order & ordering the fragment to be able to join them easily
+ Polylines polylines_chained;
+ for (size_t idx_polyline = 0; idx_polyline < polylines.size(); ++idx_polyline) {
+ Polyline &poly_to_cut = polylines[idx_polyline];
+ Polylines polylines_to_sort = intersection_pl(Polylines() = { poly_to_cut }, (Polygons)expolygon);
+ for (Polyline &polyline : polylines_to_sort) {
+ //TODO: replace by closest_index_point()
+ if (poly_to_cut.points.front().distance_to_square(polyline.points.front()) > poly_to_cut.points.front().distance_to_square(polyline.points.back())) {
+ polyline.reverse();
}
}
- Polylines chained = PolylineCollection::chained_path_from(
- std::move(polylines),
- PolylineCollection::leftmost_point(polylines), false); // reverse allowed
- bool first = true;
- for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) {
- if (! first) {
- // Try to connect the lines.
- Points &pts_end = polylines_out.back().points;
- const Point &first_point = it_polyline->points.front();
- const Point &last_point = pts_end.back();
- // TODO: we should also check that both points are on a fill_boundary to avoid
- // connecting paths on the boundaries of internal regions
- if ((last_point - first_point).cast<double>().norm() <= 1.5 * distance &&
- expolygon_off.contains(Line(last_point, first_point))) {
- // Append the polyline.
- pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
- continue;
+ if (polylines_to_sort.size() > 1) {
+ Point nearest = poly_to_cut.points.front();
+ //Bubble sort
+ for (size_t idx_sort = polylines_to_sort.size() - 1; idx_sort > 0; idx_sort--) {
+ for (size_t idx_bubble = 0; idx_bubble < idx_sort; idx_bubble++) {
+ if (polylines_to_sort[idx_bubble + 1].points.front().distance_to_square(nearest) < polylines_to_sort[idx_bubble].points.front().distance_to_square(nearest)) {
+ iter_swap(polylines_to_sort.begin() + idx_bubble, polylines_to_sort.begin() + idx_bubble + 1);
+ }
}
}
- // The lines cannot be connected.
- polylines_out.emplace_back(std::move(*it_polyline));
- first = false;
}
+ polylines_chained.insert(polylines_chained.end(), polylines_to_sort.begin(), polylines_to_sort.end());
+ }
+ // connect lines if needed
+ if (!polylines_chained.empty()) {
+ if (params.dont_connect) {
+ polylines_out.insert(polylines_out.end(), polylines_chained.begin(), polylines_chained.end());
+ } else {
+ this->connect_infill(polylines_chained, expolygon, polylines_out);
+ }
+
}
}
diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp
index 7a99e84f7..61fe00375 100644
--- a/src/libslic3r/Fill/FillBase.cpp
+++ b/src/libslic3r/Fill/FillBase.cpp
@@ -3,6 +3,7 @@
#include "../ClipperUtils.hpp"
#include "../Surface.hpp"
#include "../PrintConfig.hpp"
+#include "../ExtrusionEntityCollection.hpp"
#include "FillBase.hpp"
#include "FillConcentric.hpp"
@@ -13,6 +14,7 @@
#include "FillRectilinear.hpp"
#include "FillRectilinear2.hpp"
#include "FillRectilinear3.hpp"
+#include "FillSmooth.hpp"
namespace Slic3r {
@@ -20,11 +22,13 @@ Fill* Fill::new_from_type(const InfillPattern type)
{
switch (type) {
case ipConcentric: return new FillConcentric();
+ case ipConcentricGapFill: return new FillConcentricWGapFill();
case ipHoneycomb: return new FillHoneycomb();
case ip3DHoneycomb: return new Fill3DHoneycomb();
case ipGyroid: return new FillGyroid();
case ipRectilinear: return new FillRectilinear2();
// case ipRectilinear: return new FillRectilinear();
+ case ipScatteredRectilinear:return new FillScatteredRectilinear();
case ipLine: return new FillLine();
case ipGrid: return new FillGrid2();
case ipTriangles: return new FillTriangles();
@@ -34,7 +38,11 @@ Fill* Fill::new_from_type(const InfillPattern type)
case ipArchimedeanChords: return new FillArchimedeanChords();
case ipHilbertCurve: return new FillHilbertCurve();
case ipOctagramSpiral: return new FillOctagramSpiral();
- default: throw std::invalid_argument("unknown type");;
+ case ipSmooth: return new FillSmooth();
+ case ipSmoothTriple: return new FillSmoothTriple();
+ case ipSmoothHilbert: return new FillSmoothHilbert();
+ case ipRectiWithPerimeter: return new FillRectilinear2Peri();
+ default: throw std::invalid_argument("unknown type");
}
}
@@ -48,7 +56,7 @@ Fill* Fill::new_from_type(const std::string &type)
Polylines Fill::fill_surface(const Surface *surface, const FillParams &params)
{
// Perform offset.
- Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing)));
+ Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing)));
// Create the infills for each of the regions.
Polylines polylines_out;
for (size_t i = 0; i < expp.size(); ++ i)
@@ -71,10 +79,10 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
assert(width >= 0);
assert(distance > 0);
// floor(width / distance)
- coord_t number_of_intervals = (width - EPSILON) / distance;
+ coord_t number_of_intervals = (coord_t)((width - EPSILON) / distance);
coord_t distance_new = (number_of_intervals == 0) ?
distance :
- ((width - EPSILON) / number_of_intervals);
+ (coord_t)(((width - EPSILON) / number_of_intervals));
const coordf_t factor = coordf_t(distance_new) / coordf_t(distance);
assert(factor > 1. - 1e-5);
// How much could the extrusion width be increased? By 20%.
@@ -91,8 +99,8 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
// set infill angle
float out_angle = this->angle;
- if (out_angle == FLT_MAX) {
- //FIXME Vojtech: Add a warning?
+ if (out_angle == FLT_MAX) {
+ //FIXME Vojtech: Add a warning?
printf("Using undefined infill angle\n");
out_angle = 0.f;
}
@@ -100,7 +108,7 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
// Bounding box is the bounding box of a perl object Slic3r::Print::Object (c++ object Slic3r::PrintObject)
// The bounding box is only undefined in unit tests.
Point out_shift = empty(this->bounding_box) ?
- surface->expolygon.contour.bounding_box().center() :
+ surface->expolygon.contour.bounding_box().center() :
this->bounding_box.center();
#if 0
@@ -112,22 +120,376 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
#endif
if (surface->bridge_angle >= 0) {
- // use bridge angle
- //FIXME Vojtech: Add a debugf?
+ // use bridge angle
+ //FIXME Vojtech: Add a debugf?
// Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle);
#ifdef SLIC3R_DEBUG
printf("Filling bridge with angle %f\n", surface->bridge_angle);
#endif /* SLIC3R_DEBUG */
- out_angle = surface->bridge_angle;
+ out_angle = (float)(surface->bridge_angle);
} else if (this->layer_id != size_t(-1)) {
// alternate fill direction
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
} else {
-// printf("Layer_ID undefined!\n");
+// printf("Layer_ID undefined!\n");
}
out_angle += float(M_PI/2.);
return std::pair<float, Point>(out_angle, out_shift);
}
+void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) {
+ //add overlap & call fill_surface
+ Polylines polylines = this->fill_surface(surface, params);
+ if (polylines.empty())
+ return;
+ // ensure it doesn't over or under-extrude
+ double multFlow = 1;
+ if (!params.dont_adjust && params.full_infill() && !flow.bridge && params.fill_exactly){
+ // compute the path of the nozzle -> extruded volume
+ double lengthTot = 0;
+ int nbLines = 0;
+ for (auto pline = polylines.begin(); pline != polylines.end(); ++pline){
+ Lines lines = pline->lines();
+ for (auto line = lines.begin(); line != lines.end(); ++line){
+ lengthTot += unscaled(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+ // compute real volume
+ double poylineVolume = 0;
+ for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) {
+ poylineVolume += flow.height*unscaled(unscaled(poly->area()));
+ // add external "perimeter gap"
+ double perimeterRoundGap = unscaled(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ // add holes "perimeter gaps"
+ double holesGaps = 0;
+ for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole) {
+ holesGaps += unscaled(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ }
+ poylineVolume += perimeterRoundGap + holesGaps;
+ }
+ //printf("process want %f mm3 extruded for a volume of %f space : we mult by %f %i\n",
+ // extrudedVolume,
+ // (poylineVolume),
+ // (poylineVolume) / extrudedVolume,
+ // this->no_overlap_expolygons.size());
+ if (extrudedVolume != 0 && poylineVolume != 0) multFlow = poylineVolume / extrudedVolume;
+ //failsafe, it can happen
+ if (multFlow > 1.3) multFlow = 1.3;
+ if (multFlow < 0.8) multFlow = 0.8;
+ }
+
+ // Save into layer.
+ auto *eec = new ExtrusionEntityCollection();
+ /// pass the no_sort attribute to the extrusion path
+ eec->no_sort = this->no_sort();
+ /// add it into the collection
+ out.push_back(eec);
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = (flow.bridge ? erBridgeInfill :
+ (surface->is_solid() ?
+ ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
+ erInternalInfill));
+ }
+ /// push the path
+ extrusion_entities_append_paths(
+ eec->entities, std::move(polylines),
+ good_role,
+ flow.mm3_per_mm() * params.flow_mult * multFlow,
+ flow.width * params.flow_mult * multFlow,
+ flow.height);
+
+}
+
+
+
+
+/// cut poly between poly.point[idx_1] & poly.point[idx_1+1]
+/// add p1+-width to one part and p2+-width to the other one.
+/// add the "new" polyline to polylines (to part cut from poly)
+/// p1 & p2 have to be between poly.point[idx_1] & poly.point[idx_1+1]
+/// if idx_1 is ==0 or == size-1, then we don't need to create a new polyline.
+void cut_polyline(Polyline &poly, Polylines &polylines, size_t idx_1, Point p1, Point p2) {
+ //reorder points
+ if (p1.distance_to_square(poly.points[idx_1]) > p2.distance_to_square(poly.points[idx_1])) {
+ Point temp = p2;
+ p2 = p1;
+ p1 = temp;
+ }
+ if (idx_1 == 0) {
+ poly.points.insert(poly.points.begin(), p2);
+ } else if (idx_1 == poly.points.size() - 1) {
+ poly.points.push_back(p1);
+ } else {
+ // create new polyline
+ Polyline new_poly;
+ //put points in new_poly
+ new_poly.points.push_back(p2);
+ new_poly.points.insert(new_poly.points.end(), poly.points.begin() + idx_1 + 1, poly.points.end());
+ //erase&put points in poly
+ poly.points.erase(poly.points.begin() + idx_1 + 1, poly.points.end());
+ poly.points.push_back(p1);
+ polylines.emplace_back(new_poly);
+ }
+}
+
+/// the poly is like a polygon but with first_point != last_point (already removed)
+void cut_polygon(Polyline &poly, size_t idx_1, Point p1, Point p2) {
+ //reorder points
+ if (p1.distance_to_square(poly.points[idx_1]) > p2.distance_to_square(poly.points[idx_1])) {
+ Point temp = p2;
+ p2 = p1;
+ p1 = temp;
+ }
+ //check if we need to rotate before cutting
+ if (idx_1 != poly.size() - 1) {
+ //put points in new_poly
+ poly.points.insert(poly.points.end(), poly.points.begin(), poly.points.begin() + idx_1 + 1);
+ poly.points.erase(poly.points.begin(), poly.points.begin() + idx_1 + 1);
+ }
+ //put points in poly
+ poly.points.push_back(p1);
+ poly.points.insert(poly.points.begin(), p2);
+}
+
+/// check if the polyline from pts_to_check may be at 'width' distance of a point in polylines_blocker
+/// it use equally_spaced_points with width/2 precision, so don't worry with pts_to_check number of points.
+/// it use the given polylines_blocker points, be sure to put enough of them to be reliable.
+/// complexity : N(pts_to_check.equally_spaced_points(width / 2)) x N(polylines_blocker.points)
+bool collision(const Points &pts_to_check, const Polylines &polylines_blocker, const coordf_t width) {
+ //check if it's not too close to a polyline
+ coordf_t min_dist = width * width * 0.9 - SCALED_EPSILON;
+ Polyline better_polylines(pts_to_check);
+ Points better_pts = better_polylines.equally_spaced_points(width / 2);
+ for (const Point &p : better_pts) {
+ for (const Polyline &poly2 : polylines_blocker) {
+ for (const Point &p2 : poly2.points) {
+ if (p.distance_to_square(p2) < min_dist) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/// Try to find a path inside polylines that allow to go from p1 to p2.
+/// width if the width of the extrusion
+/// polylines_blockers are the array of polylines to check if the path isn't blocked by something.
+/// complexity: N(polylines.points) + a collision check after that if we finded a path: N(2(p2-p1)/width) x N(polylines_blocker.points)
+Points getFrontier(Polylines &polylines, const Point& p1, const Point& p2, const coord_t width, const Polylines &polylines_blockers) {
+ for (size_t idx_poly = 0; idx_poly < polylines.size(); ++idx_poly) {
+ Polyline &poly = polylines[idx_poly];
+ if (poly.size() <= 1) continue;
+
+ //loop?
+ if (poly.first_point() == poly.last_point()) {
+ //polygon : try to find a line for p1 & p2.
+ size_t idx_11, idx_12, idx_21, idx_22;
+ idx_11 = poly.closest_point_index(p1);
+ idx_12 = idx_11;
+ if (Line(poly.points[idx_11], poly.points[(idx_11 + 1) % (poly.points.size() - 1)]).distance_to(p1) < SCALED_EPSILON) {
+ idx_12 = (idx_11 + 1) % (poly.points.size() - 1);
+ } else if (Line(poly.points[(idx_11 > 0) ? (idx_11 - 1) : (poly.points.size() - 2)], poly.points[idx_11]).distance_to(p1) < SCALED_EPSILON) {
+ idx_11 = (idx_11 > 0) ? (idx_11 - 1) : (poly.points.size() - 2);
+ } else {
+ continue;
+ }
+ idx_21 = poly.closest_point_index(p2);
+ idx_22 = idx_21;
+ if (Line(poly.points[idx_21], poly.points[(idx_21 + 1) % (poly.points.size() - 1)]).distance_to(p2) < SCALED_EPSILON) {
+ idx_22 = (idx_21 + 1) % (poly.points.size() - 1);
+ } else if (Line(poly.points[(idx_21 > 0) ? (idx_21 - 1) : (poly.points.size() - 2)], poly.points[idx_21]).distance_to(p2) < SCALED_EPSILON) {
+ idx_21 = (idx_21 > 0) ? (idx_21 - 1) : (poly.points.size() - 2);
+ } else {
+ continue;
+ }
+
+
+ //edge case: on the same line
+ if (idx_11 == idx_21 && idx_12 == idx_22) {
+ if (collision(Points() = { p1, p2 }, polylines_blockers, width)) return Points();
+ //break loop
+ poly.points.erase(poly.points.end() - 1);
+ cut_polygon(poly, idx_11, p1, p2);
+ return Points() = { Line(p1, p2).midpoint() };
+ }
+
+ //compute distance & array for the ++ path
+ Points ret_1_to_2;
+ double dist_1_to_2 = p1.distance_to(poly.points[idx_12]);
+ ret_1_to_2.push_back(poly.points[idx_12]);
+ size_t max = idx_12 <= idx_21 ? idx_21 : poly.points.size() - 2;
+ for (size_t i = idx_12 + 1; i < max; i++) {
+ dist_1_to_2 += poly.points[i - 1].distance_to(poly.points[i]);
+ ret_1_to_2.push_back(poly.points[i]);
+ }
+ if (idx_12 > idx_21) {
+ dist_1_to_2 += poly.points.back().distance_to(poly.points.front());
+ ret_1_to_2.push_back(poly.points[0]);
+ for (size_t i = 1; i <= idx_21; i++) {
+ dist_1_to_2 += poly.points[i - 1].distance_to(poly.points[i]);
+ ret_1_to_2.push_back(poly.points[i]);
+ }
+ }
+ dist_1_to_2 += p2.distance_to(poly.points[idx_21]);
+
+ //compute distance & array for the -- path
+ Points ret_2_to_1;
+ double dist_2_to_1 = p1.distance_to(poly.points[idx_11]);
+ ret_2_to_1.push_back(poly.points[idx_11]);
+ size_t min = idx_22 <= idx_11 ? idx_22 : 0;
+ for (size_t i = idx_11; i > min; i--) {
+ dist_2_to_1 += poly.points[i - 1].distance_to(poly.points[i]);
+ ret_2_to_1.push_back(poly.points[i - 1]);
+ }
+ if (idx_22 > idx_11) {
+ dist_2_to_1 += poly.points.back().distance_to(poly.points.front());
+ ret_2_to_1.push_back(poly.points[poly.points.size() - 1]);
+ for (size_t i = poly.points.size() - 2; i > idx_22; i--) {
+ dist_2_to_1 += poly.points[i - 1].distance_to(poly.points[i]);
+ ret_2_to_1.push_back(poly.points[i - 1]);
+ }
+ }
+ dist_2_to_1 += p2.distance_to(poly.points[idx_22]);
+
+ //choose between the two direction (keep the short one)
+ if (dist_1_to_2 < dist_2_to_1) {
+ if (collision(ret_1_to_2, polylines_blockers, width)) return Points();
+ //break loop
+ poly.points.erase(poly.points.end() - 1);
+ //remove points
+ if (idx_12 <= idx_21) {
+ poly.points.erase(poly.points.begin() + idx_12, poly.points.begin() + idx_21 + 1);
+ cut_polygon(poly, idx_11, p1, p2);
+ } else {
+ poly.points.erase(poly.points.begin() + idx_12, poly.points.end());
+ poly.points.erase(poly.points.begin(), poly.points.begin() + idx_21);
+ cut_polygon(poly, poly.points.size() - 1, p1, p2);
+ }
+ return ret_1_to_2;
+ } else {
+ if (collision(ret_2_to_1, polylines_blockers, width)) return Points();
+ //break loop
+ poly.points.erase(poly.points.end() - 1);
+ //remove points
+ if (idx_22 <= idx_11) {
+ poly.points.erase(poly.points.begin() + idx_22, poly.points.begin() + idx_11 + 1);
+ cut_polygon(poly, idx_21, p1, p2);
+ } else {
+ poly.points.erase(poly.points.begin() + idx_22, poly.points.end());
+ poly.points.erase(poly.points.begin(), poly.points.begin() + idx_11);
+ cut_polygon(poly, poly.points.size() - 1, p1, p2);
+ }
+ return ret_2_to_1;
+ }
+ } else {
+ //polyline : try to find a line for p1 & p2.
+ size_t idx_1, idx_2;
+ idx_1 = poly.closest_point_index(p1);
+ if (idx_1 < poly.points.size() - 1 && Line(poly.points[idx_1], poly.points[idx_1 + 1]).distance_to(p1) < SCALED_EPSILON) {
+ } else if (idx_1 > 0 && Line(poly.points[idx_1 - 1], poly.points[idx_1]).distance_to(p1) < SCALED_EPSILON) {
+ idx_1 = idx_1 - 1;
+ } else {
+ continue;
+ }
+ idx_2 = poly.closest_point_index(p2);
+ if (idx_2 < poly.points.size() - 1 && Line(poly.points[idx_2], poly.points[idx_2 + 1]).distance_to(p2) < SCALED_EPSILON) {
+ } else if (idx_2 > 0 && Line(poly.points[idx_2 - 1], poly.points[idx_2]).distance_to(p2) < SCALED_EPSILON) {
+ idx_2 = idx_2 - 1;
+ } else {
+ continue;
+ }
+
+ //edge case: on the same line
+ if (idx_1 == idx_2) {
+ if (collision(Points() = { p1, p2 }, polylines_blockers, width)) return Points();
+ cut_polyline(poly, polylines, idx_1, p1, p2);
+ return Points() = { Line(p1, p2).midpoint() };
+ }
+
+ //create ret array
+ size_t first_idx = idx_1;
+ size_t last_idx = idx_2 + 1;
+ if (idx_1 > idx_2) {
+ first_idx = idx_2;
+ last_idx = idx_1 + 1;
+ }
+ Points p_ret;
+ p_ret.insert(p_ret.end(), poly.points.begin() + first_idx + 1, poly.points.begin() + last_idx);
+ if (collision(p_ret, polylines_blockers, width)) return Points();
+ //cut polyline
+ poly.points.erase(poly.points.begin() + first_idx + 1, poly.points.begin() + last_idx);
+ cut_polyline(poly, polylines, first_idx, p1, p2);
+ //order the returned array to be p1->p2
+ if (idx_1 > idx_2) {
+ std::reverse(p_ret.begin(), p_ret.end());
+ }
+ return p_ret;
+ }
+
+ }
+
+ return Points();
+}
+
+/// Connect the infill_ordered polylines, in this order, from the back point to the next front point.
+/// It uses only the boundary polygons to do so, and can't pass two times at the same place.
+/// It avoid passing over the infill_ordered's polylines (preventing local over-extrusion).
+/// return the connected polylines in polylines_out. Can output polygons (stored as polylines with first_point = last_point).
+/// complexity: worst: N(infill_ordered.points) x N(boundary.points)
+/// typical: N(infill_ordered) x ( N(boundary.points) + N(infill_ordered.points) )
+void Fill::connect_infill(const Polylines &infill_ordered, const ExPolygon &boundary, Polylines &polylines_out) {
+
+ //TODO: fallback to the quick & dirty old algorithm when n(points) is too high.
+ Polylines polylines_frontier = to_polylines(((Polygons)boundary));
+
+ Polylines polylines_blocker;
+ coord_t clip_size = scale_(this->spacing) * 2;
+ for (const Polyline &polyline : infill_ordered) {
+ if (polyline.length() > 1.8 * clip_size) {
+ polylines_blocker.push_back(polyline);
+ polylines_blocker.back().clip_end(clip_size);
+ polylines_blocker.back().clip_start(clip_size);
+ }
+ }
+
+
+ Polylines polylines_connected;
+ bool first = true;
+ for (const Polyline &polyline : infill_ordered) {
+ if (!first) {
+ // Try to connect the lines.
+ Points &pts_end = polylines_connected.back().points;
+ const Point &first_point = polyline.points.front();
+ const Point &last_point = pts_end.back();
+
+ Points pts = getFrontier(polylines_frontier, last_point, first_point, scale_(this->spacing), polylines_blocker);
+ if (!pts.empty()) {
+ pts_end.insert(pts_end.end(), pts.begin(), pts.end());
+ pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
+ continue;
+ }
+ }
+ // The lines cannot be connected.
+ polylines_connected.emplace_back(std::move(polyline));
+
+ first = false;
+ }
+
+ //try to create some loops if possible
+ for (Polyline &polyline : polylines_connected) {
+ Points pts = getFrontier(polylines_frontier, polyline.last_point(), polyline.first_point(), scale_(this->spacing), polylines_blocker);
+ if (!pts.empty()) {
+ polyline.points.insert(polyline.points.end(), pts.begin(), pts.end());
+ polyline.points.insert(polyline.points.begin(), polyline.points.back());
+ }
+ polylines_out.emplace_back(polyline);
+ }
+}
+
} // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp
index 8bf6c3689..11006a6b7 100644
--- a/src/libslic3r/Fill/FillBase.hpp
+++ b/src/libslic3r/Fill/FillBase.hpp
@@ -12,6 +12,7 @@
#include "../BoundingBox.hpp"
#include "../PrintConfig.hpp"
#include "../Utils.hpp"
+#include "../Flow.hpp"
namespace Slic3r {
@@ -23,12 +24,17 @@ struct FillParams
memset(this, 0, sizeof(FillParams));
// Adjustment does not work.
dont_adjust = true;
+ flow_mult = 1.f;
+ fill_exactly = false;
}
- bool full_infill() const { return density > 0.9999f; }
+ bool full_infill() const { return density > 0.9999f && density < 1.0001f; }
- // Fill density, fraction in <0, 1>
- float density;
+ // Fill density, fraction in <0, 1>
+ float density;
+
+ // Fill extruding flow multiplier, fraction in <0, 1>. Used by "over bridge compensation"
+ float flow_mult;
// Don't connect the fill lines around the inner perimeter.
bool dont_connect;
@@ -36,6 +42,9 @@ struct FillParams
// Don't adjust spacing to fill the space evenly.
bool dont_adjust;
+ // Try to extrude the exact amount of plastic to fill the volume requested
+ bool fill_exactly;
+
// For Honeycomb.
// we were requested to complete each loop;
// in this case we don't try to make more continuous paths
@@ -52,8 +61,9 @@ public:
coordf_t z;
// in unscaled coordinates
coordf_t spacing;
- // infill / perimeter overlap, in unscaled coordinates
+ // infill / perimeter overlap, in unscaled coordinates
coordf_t overlap;
+ ExPolygons no_overlap_expolygons;
// in radians, ccw, 0 = East
float angle;
// In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines.
@@ -79,6 +89,11 @@ public:
// Do not sort the fill lines to optimize the print head path?
virtual bool no_sort() const { return false; }
+ // This method have to fill the ExtrusionEntityCollection. It call fill_surface by default
+ // if role == erNone or ERCustom, this method have to choose the best role itself, else it must use the argument's role.
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out);
+
// Perform the fill.
virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
@@ -109,6 +124,8 @@ protected:
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
+ void connect_infill(const Polylines &infill_ordered, const ExPolygon &boundary, Polylines &polylines_out);
+
public:
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
diff --git a/src/libslic3r/Fill/FillConcentric.cpp b/src/libslic3r/Fill/FillConcentric.cpp
index 8a3a7ea89..b3e01b361 100644
--- a/src/libslic3r/Fill/FillConcentric.cpp
+++ b/src/libslic3r/Fill/FillConcentric.cpp
@@ -1,10 +1,13 @@
#include "../ClipperUtils.hpp"
#include "../ExPolygon.hpp"
#include "../Surface.hpp"
+#include "../ExtrusionEntityCollection.hpp"
+#include "../MedialAxis.hpp"
#include "FillConcentric.hpp"
namespace Slic3r {
+
void FillConcentric::_fill_surface_single(
const FillParams &params,
@@ -61,4 +64,98 @@ void FillConcentric::_fill_surface_single(
// We want the loops to be split inside the G-code generator to get optimum path planning.
}
+void FillConcentricWGapFill::fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) {
+
+ // Perform offset.
+ Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing)));
+ // Create the infills for each of the regions.
+ Polylines polylines_out;
+ for (size_t i = 0; i < expp.size(); ++i) {
+ //_fill_surface_single(
+ //params,
+ //surface->thickness_layers,
+ //_infill_direction(surface),
+ //expp[i],
+ //polylines_out);
+ ExPolygon expolygon = expp[i];
+
+ coordf_t init_spacing = this->spacing;
+
+ // no rotation is supported for this infill pattern
+ BoundingBox bounding_box = expolygon.contour.bounding_box();
+
+ coord_t min_spacing = scale_(this->spacing);
+ coord_t distance = coord_t(min_spacing / params.density);
+
+ if (params.density > 0.9999f && !params.dont_adjust) {
+ distance = this->_adjust_solid_spacing(bounding_box.size().x(), distance);
+ this->spacing = unscaled(distance);
+ }
+
+ ExPolygons gaps;
+ Polygons loops = (Polygons)expolygon;
+ Polygons last = loops;
+ while (!last.empty()) {
+ Polygons next_onion = offset2(last, -(distance + min_spacing / 2), +min_spacing / 2);
+ loops.insert(loops.end(), next_onion.begin(), next_onion.end());
+ append(gaps, diff_ex(
+ offset(last, -0.5f * distance),
+ offset(next_onion, 0.5f * distance + 10))); // safety offset
+ last = next_onion;
+ }
+
+ // generate paths from the outermost to the innermost, to avoid
+ // adhesion problems of the first central tiny loops
+ //note: useless if we don't apply no_sort flag
+ //loops = union_pt_chained(loops, false);
+
+
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = (flow.bridge ? erBridgeInfill :
+ (surface->is_solid() ?
+ ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
+ erInternalInfill));
+ }
+
+ ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
+ coll_nosort->no_sort = true; //can be sorted inside the pass
+ extrusion_entities_append_loops(
+ coll_nosort->entities, loops,
+ good_role,
+ flow.mm3_per_mm() * params.flow_mult,
+ flow.width * params.flow_mult,
+ flow.height);
+
+ //add gapfills
+ if (!gaps.empty() && params.density >= 1) {
+ // collapse
+ double min = 0.2 * distance * (1 - INSET_OVERLAP_TOLERANCE);
+ double max = 2. * distance;
+ ExPolygons gaps_ex = diff_ex(
+ offset2_ex(gaps, -min / 2, +min / 2),
+ offset2_ex(gaps, -max / 2, +max / 2),
+ true);
+ ThickPolylines polylines;
+ for (const ExPolygon &ex : gaps_ex) {
+ //remove too small gaps that are too hard to fill.
+ //ie one that are smaller than an extrusion with width of min and a length of max.
+ if (ex.area() > min*max) {
+ ex.medial_axis(ex, max, min, &polylines, flow.height);
+ }
+ }
+ if (!polylines.empty()) {
+ ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, flow);
+ coll_nosort->append(gap_fill.entities);
+ }
+ }
+
+ if (!coll_nosort->entities.empty())
+ out.push_back(coll_nosort);
+ else delete coll_nosort;
+ }
+}
+
} // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillConcentric.hpp b/src/libslic3r/Fill/FillConcentric.hpp
index 1286858ea..918a370a7 100644
--- a/src/libslic3r/Fill/FillConcentric.hpp
+++ b/src/libslic3r/Fill/FillConcentric.hpp
@@ -12,16 +12,29 @@ public:
protected:
virtual Fill* clone() const { return new FillConcentric(*this); };
- virtual void _fill_surface_single(
- const FillParams &params,
- unsigned int thickness_layers,
- const std::pair<float, Point> &direction,
- ExPolygon &expolygon,
- Polylines &polylines_out);
+ virtual void _fill_surface_single(
+ const FillParams &params,
+ unsigned int thickness_layers,
+ const std::pair<float, Point> &direction,
+ ExPolygon &expolygon,
+ Polylines &polylines_out);
virtual bool no_sort() const { return true; }
};
+
+class FillConcentricWGapFill : public Fill {
+public:
+ virtual ~FillConcentricWGapFill() {}
+
+protected:
+ virtual Fill* clone() const { return new FillConcentricWGapFill(*this); };
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out);
+
+ virtual bool no_sort() const { return true; }
+};
+
} // namespace Slic3r
#endif // slic3r_FillConcentric_hpp_
diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp
index 04319bb26..9972e210c 100644
--- a/src/libslic3r/Fill/FillGyroid.cpp
+++ b/src/libslic3r/Fill/FillGyroid.cpp
@@ -109,16 +109,20 @@ static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double
std::swap(width,height);
}
- std::vector<Vec2d> one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time
+ std::vector<Vec2d> one_period_odd = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time
+ flip = !flip; // even polylines are a bit shifted
+ std::vector<Vec2d> one_period_even = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip);
Polylines result;
- for (double y0 = lower_bound; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates odd polylines
- result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
-
- flip = !flip; // even polylines are a bit shifted
- one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // updates the one period sample
- for (double y0 = lower_bound + M_PI; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates even polylines
- result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
+ for (double y0 = lower_bound; y0 < upper_bound + EPSILON; y0 += M_PI) {
+ // creates odd polylines
+ result.emplace_back(make_wave(one_period_odd, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
+ // creates even polylines
+ y0 += M_PI;
+ if (y0 < upper_bound + EPSILON) {
+ result.emplace_back(make_wave(one_period_even, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
+ }
+ }
return result;
}
@@ -141,7 +145,7 @@ void FillGyroid::_fill_surface_single(
bb.merge(_align_to_grid(bb.min, Point(2.*M_PI*distance, 2.*M_PI*distance)));
// generate pattern
- Polylines polylines = make_gyroid_waves(
+ Polylines polylines_square = make_gyroid_waves(
scale_(this->z),
density_adjusted,
this->spacing,
@@ -149,46 +153,51 @@ void FillGyroid::_fill_surface_single(
ceil(bb.size()(1) / distance) + 1.);
// move pattern in place
- for (Polyline &polyline : polylines)
+ for (Polyline &polyline : polylines_square)
polyline.translate(bb.min(0), bb.min(1));
- // clip pattern to boundaries
- polylines = intersection_pl(polylines, (Polygons)expolygon);
-
- // connect lines
- if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
- ExPolygon expolygon_off;
- {
- ExPolygons expolygons_off = offset_ex(expolygon, (float)SCALED_EPSILON);
- if (! expolygons_off.empty()) {
- // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
- assert(expolygons_off.size() == 1);
- std::swap(expolygon_off, expolygons_off.front());
+ // clip pattern to boundaries, keeping the polyline order & ordering the fragment to be able to join them easily
+ //Polylines polylines = intersection_pl(polylines_square, (Polygons)expolygon);
+ Polylines polylines_chained;
+ for (size_t idx_polyline = 0; idx_polyline < polylines_square.size(); ++idx_polyline) {
+ Polyline &poly_to_cut = polylines_square[idx_polyline];
+ Polylines polylines_to_sort = intersection_pl(Polylines() = { poly_to_cut }, (Polygons)expolygon);
+ for (Polyline &polyline : polylines_to_sort) {
+ //TODO: replace by closest_index_point()
+ if (idx_polyline % 2 == 0) {
+ if (poly_to_cut.points.front().distance_to_square(polyline.points.front()) > poly_to_cut.points.front().distance_to_square(polyline.points.back())) {
+ polyline.reverse();
+ }
+ } else {
+ if (poly_to_cut.points.back().distance_to_square(polyline.points.front()) > poly_to_cut.points.back().distance_to_square(polyline.points.back())) {
+ polyline.reverse();
+ }
}
}
- Polylines chained = PolylineCollection::chained_path_from(
- std::move(polylines),
- PolylineCollection::leftmost_point(polylines), false); // reverse allowed
- bool first = true;
- for (Polyline &polyline : chained) {
- if (! first) {
- // Try to connect the lines.
- Points &pts_end = polylines_out.back().points;
- const Point &first_point = polyline.points.front();
- const Point &last_point = pts_end.back();
- // TODO: we should also check that both points are on a fill_boundary to avoid
- // connecting paths on the boundaries of internal regions
- // TODO: avoid crossing current infill path
- if ((last_point - first_point).cast<double>().norm() <= 5 * distance &&
- expolygon_off.contains(Line(last_point, first_point))) {
- // Append the polyline.
- pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
- continue;
+ if (polylines_to_sort.size() > 1) {
+ Point nearest = poly_to_cut.points.front();
+ if (idx_polyline % 2 != 0) {
+ nearest = poly_to_cut.points.back();
+ }
+ //Bubble sort
+ for (size_t idx_sort = polylines_to_sort.size() - 1; idx_sort > 0; idx_sort--) {
+ for (size_t idx_bubble = 0; idx_bubble < idx_sort; idx_bubble++) {
+ if (polylines_to_sort[idx_bubble + 1].points.front().distance_to_square(nearest) < polylines_to_sort[idx_bubble].points.front().distance_to_square(nearest)) {
+ iter_swap(polylines_to_sort.begin() + idx_bubble, polylines_to_sort.begin() + idx_bubble + 1);
+ }
}
}
- // The lines cannot be connected.
- polylines_out.emplace_back(std::move(polyline));
- first = false;
+ }
+ polylines_chained.insert(polylines_chained.end(), polylines_to_sort.begin(), polylines_to_sort.end());
+ }
+
+ if (!polylines_chained.empty()) {
+
+ // connect lines
+ if (params.dont_connect) {
+ polylines_out.insert(polylines_out.end(), polylines_chained.begin(), polylines_chained.end());
+ } else {
+ this->connect_infill(polylines_chained, expolygon, polylines_out);
}
}
}
diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp
index 205eb1b66..cc2d10624 100644
--- a/src/libslic3r/Fill/FillRectilinear.cpp
+++ b/src/libslic3r/Fill/FillRectilinear.cpp
@@ -18,7 +18,7 @@ void FillRectilinear::_fill_surface_single(
expolygon.rotate(- direction.first);
this->_min_spacing = scale_(this->spacing);
- assert(params.density > 0.0001f && params.density <= 1.f);
+ assert(params.density > 0.0001f);
this->_line_spacing = coord_t(coordf_t(this->_min_spacing) / params.density);
this->_diagonal_distance = this->_line_spacing * 2;
this->_line_oscillation = this->_line_spacing - this->_min_spacing; // only for Line infill
@@ -81,7 +81,7 @@ void FillRectilinear::_fill_surface_single(
size_t n_polylines_out_old = polylines_out.size();
// connect lines
- if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
+ if (! polylines.empty()) { // prevent calling leftmost_point() on empty collections
// offset the expolygon by max(min_spacing/2, extra)
ExPolygon expolygon_off;
{
@@ -97,7 +97,7 @@ void FillRectilinear::_fill_surface_single(
PolylineCollection::leftmost_point(polylines), false); // reverse allowed
bool first = true;
for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) {
- if (! first) {
+ if (!params.dont_connect && !first) {
// Try to connect the lines.
Points &pts_end = polylines_out.back().points;
const Point &first_point = it_polyline->points.front();
diff --git a/src/libslic3r/Fill/FillRectilinear2.cpp b/src/libslic3r/Fill/FillRectilinear2.cpp
index 65440d0ef..23a404098 100644
--- a/src/libslic3r/Fill/FillRectilinear2.cpp
+++ b/src/libslic3r/Fill/FillRectilinear2.cpp
@@ -6,7 +6,11 @@
#include <limits>
#include <boost/static_assert.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/random/uniform_real_distribution.hpp>
+#include "../ExtrusionEntityCollection.hpp"
#include "../ClipperUtils.hpp"
#include "../ExPolygon.hpp"
#include "../Geometry.hpp"
@@ -284,9 +288,9 @@ public:
// for the infill pattern, don't cut the corners.
// default miterLimt = 3
//double mitterLimit = 10.;
- assert(aoffset1 < 0);
- assert(aoffset2 < 0);
- assert(aoffset2 < aoffset1);
+ //assert(aoffset1 < 0);
+ //assert(aoffset2 < 0);
+ //assert(aoffset2 < aoffset1);
bool sticks_removed = remove_sticks(polygons_src);
// if (sticks_removed) printf("Sticks removed!\n");
polygons_outer = offset(polygons_src, aoffset1,
@@ -758,55 +762,9 @@ enum DirectionMask
DIR_BACKWARD = 2
};
-bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillParams &params, float angleBase, float pattern_shift, Polylines &polylines_out)
+// Intersect a set of equally spaced vertical lines with expolygon.
+std::vector<SegmentedIntersectionLine> FillRectilinear2::_vert_lines_for_polygon(const ExPolygonWithOffset &poly_with_offset, const BoundingBox &bounding_box, const FillParams &params, coord_t line_spacing) const
{
- // At the end, only the new polylines will be rotated back.
- size_t n_polylines_out_initial = polylines_out.size();
-
- // Shrink the input polygon a bit first to not push the infill lines out of the perimeters.
-// const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
- const float INFILL_OVERLAP_OVER_SPACING = 0.45f;
- assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f);
-
- // Rotate polygons so that we can work with vertical lines here
- std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
- rotate_vector.first += angleBase;
-
- assert(params.density > 0.0001f && params.density <= 1.f);
- coord_t line_spacing = coord_t(scale_(this->spacing) / params.density);
-
- // On the polygons of poly_with_offset, the infill lines will be connected.
- ExPolygonWithOffset poly_with_offset(
- surface->expolygon,
- - rotate_vector.first,
- scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
- scale_(this->overlap - 0.5 * this->spacing));
- if (poly_with_offset.n_contours_inner == 0) {
- // Not a single infill line fits.
- //FIXME maybe one shall trigger the gap fill here?
- return true;
- }
-
- BoundingBox bounding_box = poly_with_offset.bounding_box_src();
-
- // define flow spacing according to requested density
- if (params.full_infill() && !params.dont_adjust) {
- line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
- this->spacing = unscale<double>(line_spacing);
- } else {
- // extend bounding box so that our pattern will be aligned with other layers
- // Transform the reference point to the rotated coordinate system.
- Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
- // _align_to_grid will not work correctly with positive pattern_shift.
- coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
- refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
- bounding_box.merge(_align_to_grid(
- bounding_box.min,
- Point(line_spacing, line_spacing),
- refpt));
- }
-
- // Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
coord_t x0 = bounding_box.min(0);
@@ -901,6 +859,65 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
}
}
+ return segs;
+}
+
+coord_t FillRectilinear2::_line_spacing_for_density(float density) const
+{
+ return coord_t(scale_(this->spacing) / density);
+}
+
+bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillParams &params, float angleBase, float pattern_shift, Polylines &polylines_out)
+{
+ // At the end, only the new polylines will be rotated back.
+ size_t n_polylines_out_initial = polylines_out.size();
+
+ // Shrink the input polygon a bit first to not push the infill lines out of the perimeters.
+// const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
+ const float INFILL_OVERLAP_OVER_SPACING = 0.45f;
+ assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f);
+
+ // Rotate polygons so that we can work with vertical lines here
+ std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
+ rotate_vector.first += angleBase;
+
+ assert(params.density > 0.0001f);
+ coord_t line_spacing = _line_spacing_for_density(params.density);
+
+ // On the polygons of poly_with_offset, the infill lines will be connected.
+ ExPolygonWithOffset poly_with_offset(
+ surface->expolygon,
+ - rotate_vector.first,
+ scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
+ scale_(this->overlap - 0.5 * this->spacing));
+ if (poly_with_offset.n_contours_inner == 0) {
+ // Not a single infill line fits.
+ //FIXME maybe one shall trigger the gap fill here?
+ return true;
+ }
+
+ BoundingBox bounding_box = poly_with_offset.bounding_box_src();
+
+ // define flow spacing according to requested density
+ if (params.full_infill() && !params.dont_adjust) {
+ line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
+ this->spacing = unscale<double>(line_spacing);
+ } else {
+ // extend bounding box so that our pattern will be aligned with other layers
+ // Transform the reference point to the rotated coordinate system.
+ Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
+ // _align_to_grid will not work correctly with positive pattern_shift.
+ coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
+ refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
+ bounding_box.merge(_align_to_grid(
+ bounding_box.min,
+ Point(line_spacing, line_spacing),
+ refpt));
+ }
+
+ // Intersect a set of equally spaced vertical lines with expolygon.
+ std::vector<SegmentedIntersectionLine> segs = _vert_lines_for_polygon(poly_with_offset, bounding_box, params, line_spacing);
+
// Sort the intersections along their segments, specify the intersection types.
for (size_t i_seg = 0; i_seg < segs.size(); ++ i_seg) {
SegmentedIntersectionLine &sil = segs[i_seg];
@@ -1472,4 +1489,164 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams &para
return polylines_out;
}
+
+void
+FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out)
+{
+ ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
+ //you don't want to sort the extrusions: big infill first, small second
+ eecroot->no_sort = true;
+
+ // === extrude perimeter ===
+ Polylines polylines_1;
+ //generate perimeter:
+ ExPolygons path_perimeter = offset2_ex(surface->expolygon, scale_(-this->spacing), scale_(this->spacing / 2));
+ for (ExPolygon &expolygon : path_perimeter) {
+ expolygon.contour.make_counter_clockwise();
+ polylines_1.push_back(expolygon.contour.split_at_index(0));
+ for (Polygon hole : expolygon.holes) {
+ hole.make_clockwise();
+ polylines_1.push_back(hole.split_at_index(0));
+ }
+ }
+
+ if (!polylines_1.empty()) {
+ // Save into layer.
+ ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
+ /// pass the no_sort attribute to the extrusion path
+ eec->no_sort = this->no_sort();
+ /// add it into the collection
+ eecroot->entities.push_back(eec);
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = flow.bridge ?
+ erBridgeInfill :
+ (surface->is_solid() ?
+ ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
+ erInternalInfill);
+ }
+ /// push the path
+ extrusion_entities_append_paths(
+ eec->entities,
+ polylines_1,
+ good_role,
+ flow.mm3_per_mm() * params.flow_mult,
+ flow.width * params.flow_mult,
+ flow.height);
+ }
+
+
+ // === extrude dense infill ===
+ Polylines polylines_2;
+ bool canFill = true;
+ //50% overlap with the new perimeter
+ ExPolygons path_inner = offset2_ex(surface->expolygon, scale_(-this->spacing * 1.5), scale_(this->spacing));
+ for (ExPolygon &expolygon : path_inner) {
+ Surface surfInner(*surface, expolygon);
+ if (!fill_surface_by_lines(&surfInner, params, 0.f, 0.f, polylines_2)) {
+ printf("FillRectilinear2::fill_surface() failed to fill a region.\n");
+ canFill = false;
+ }
+ }
+ if (canFill && !polylines_2.empty()) {
+ // Save into layer.
+ ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
+ /// pass the no_sort attribute to the extrusion path
+ eec->no_sort = this->no_sort();
+ /// add it into the collection
+ eecroot->entities.push_back(eec);
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = flow.bridge ?
+ erBridgeInfill :
+ (surface->is_solid() ?
+ ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) :
+ erInternalInfill);
+ }
+ /// push the path
+ extrusion_entities_append_paths(
+ eec->entities,
+ polylines_2,
+ good_role,
+ flow.mm3_per_mm() * params.flow_mult,
+ flow.width * params.flow_mult,
+ flow.height);
+ }
+
+ // === end ===
+ if (!eecroot->empty()) {
+ out.push_back(eecroot);
+ } else {
+ delete eecroot;
+ }
+
+}
+
+/* Returns a float uniformly distributed in the range [0..1.0) using the given integer as the seed
+*
+* N.B. calling this is super slow as it must rebuild the initial state for a Mersenne Twister with each call, so
+* don't call this in a loop if you can avoid it.
+*/
+static float randomFloatFromSeed(uint32_t x)
+{
+ boost::random::mt19937 rng(x);
+ boost::random::uniform_real_distribution<> dist;
+
+ return (float) dist(rng);
+}
+
+float FillScatteredRectilinear::_layer_angle(size_t idx) const
+{
+ // Angle chosen at random using the layer index as a key
+ return randomFloatFromSeed((uint32_t) idx) * (float) M_PI;
+}
+
+coord_t FillScatteredRectilinear::_line_spacing_for_density(float density) const
+{
+ /* The density argument is ignored, we first generate lines at 100% density, then prune some generated lines
+ * later to achieve the target density
+ */
+ (void) density;
+
+ return coord_t(scale_(this->spacing) / 1.0);
+}
+
+Polylines FillScatteredRectilinear::fill_surface(const Surface *surface, const FillParams &params)
+{
+ Polylines polylines_out;
+
+ // Offset the pattern randomly using the current layer index as the generator
+ float offset = randomFloatFromSeed((uint32_t) layer_id) * 0.5f * (float) this->spacing;
+
+ if (!fill_surface_by_lines(surface, params, 0.f, offset, polylines_out)) {
+ printf("FillScatteredRectilinear::fill_surface() failed to fill a region.\n");
+ }
+ return polylines_out;
+}
+
+std::vector<SegmentedIntersectionLine> FillScatteredRectilinear::_vert_lines_for_polygon(const ExPolygonWithOffset &poly_with_offset, const BoundingBox &bounding_box, const FillParams &params, coord_t line_spacing) const
+{
+ std::vector<SegmentedIntersectionLine> segs = FillRectilinear2::_vert_lines_for_polygon(poly_with_offset, bounding_box, params, line_spacing);
+
+ if (!params.full_infill()) {
+ boost::random::mt19937 rng((uint32_t) layer_id);
+ boost::random::uniform_real_distribution<> dist;
+
+ // Remove generated lines with a probability that'll achieve the required density on average
+ for (auto iter = segs.begin(); iter != segs.end(); ) {
+ if (dist(rng) >= params.density) {
+ iter = segs.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+ }
+
+ return segs;
+}
+
+
} // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillRectilinear2.hpp b/src/libslic3r/Fill/FillRectilinear2.hpp
index 4459919b0..21afacc71 100644
--- a/src/libslic3r/Fill/FillRectilinear2.hpp
+++ b/src/libslic3r/Fill/FillRectilinear2.hpp
@@ -8,6 +8,8 @@
namespace Slic3r {
class Surface;
+class SegmentedIntersectionLine;
+struct ExPolygonWithOffset;
class FillRectilinear2 : public Fill
{
@@ -17,6 +19,9 @@ public:
virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
protected:
+ virtual std::vector<SegmentedIntersectionLine> _vert_lines_for_polygon(const ExPolygonWithOffset &poly_with_offset, const BoundingBox &bounding_box, const FillParams &params, coord_t line_spacing) const;
+ virtual coord_t _line_spacing_for_density(float density) const;
+
bool fill_surface_by_lines(const Surface *surface, const FillParams &params, float angleBase, float pattern_shift, Polylines &polylines_out);
};
@@ -68,6 +73,34 @@ protected:
virtual float _layer_angle(size_t idx) const { return 0.f; }
};
+class FillRectilinear2Peri : public FillRectilinear2 {
+public:
+ // require bridge flow since it's a pre-bridge over very sparse infill
+ virtual bool use_bridge_flow() const { return true; }
+
+ virtual Fill* clone() const { return new FillRectilinear2Peri(*this); };
+ virtual ~FillRectilinear2Peri() {}
+ //virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out);
+
+};
+
+
+class FillScatteredRectilinear : public FillRectilinear2
+{
+public:
+ virtual Fill* clone() const { return new FillScatteredRectilinear(*this); };
+ virtual ~FillScatteredRectilinear() {}
+virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
+
+protected:
+ virtual float _layer_angle(size_t idx) const;
+ virtual std::vector<SegmentedIntersectionLine> _vert_lines_for_polygon(const ExPolygonWithOffset &poly_with_offset, const BoundingBox &bounding_box, const FillParams &params, coord_t line_spacing) const;
+ virtual coord_t _line_spacing_for_density(float density) const;
+};
+
+
}; // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillRectilinear3.cpp b/src/libslic3r/Fill/FillRectilinear3.cpp
index 8a0b90ead..d682d0cdd 100644
--- a/src/libslic3r/Fill/FillRectilinear3.cpp
+++ b/src/libslic3r/Fill/FillRectilinear3.cpp
@@ -380,7 +380,7 @@ static bool prepare_infill_hatching_segments(
out.direction.rotate(out.angle + 0.5 * M_PI);
out.segs.clear();
- assert(params.density > 0.0001f && params.density <= 1.f);
+ assert(params.density > 0.0001f);
coord_t line_spacing = coord_t(scale_(fill_dir_params.spacing) / params.density);
// Bounding box around the source contour, aligned with out.angle.
@@ -1531,7 +1531,7 @@ static bool fill_hatching_segments_legacy(
bool FillRectilinear3::fill_surface_by_lines(const Surface *surface, const FillParams &params, std::vector<FillDirParams> &fill_dir_params, Polylines &polylines_out)
{
- assert(params.density > 0.0001f && params.density <= 1.f);
+ assert(params.density > 0.0001f);
const float INFILL_OVERLAP_OVER_SPACING = 0.45f;
assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f);
diff --git a/src/libslic3r/Fill/FillSmooth.cpp b/src/libslic3r/Fill/FillSmooth.cpp
new file mode 100644
index 000000000..6497af7f6
--- /dev/null
+++ b/src/libslic3r/Fill/FillSmooth.cpp
@@ -0,0 +1,278 @@
+#include "../ClipperUtils.hpp"
+#include "../PolylineCollection.hpp"
+#include "../ExtrusionEntityCollection.hpp"
+#include "../Surface.hpp"
+#include <cmath>
+#include <algorithm>
+#include <iostream>
+
+#include "FillSmooth.hpp"
+
+namespace Slic3r {
+
+ Polylines FillSmooth::fill_surface(const Surface *surface, const FillParams &params)
+ {
+ //ERROR: you shouldn't call that. Default to the rectilinear one.
+ printf("FillSmooth::fill_surface() : you call the wrong method (fill_surface instead of fill_surface_extrusion).\n");
+ Polylines polylines_out;
+ return polylines_out;
+ }
+
+
+ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out)
+ {
+ coordf_t init_spacing = this->spacing;
+
+ //printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
+ //second pass with half layer width
+ FillParams params1 = params;
+ FillParams params2 = params;
+ FillParams params3 = params;
+ params1.density *= percentWidth[0];
+ params2.density *= percentWidth[1];
+ params3.density *= percentWidth[2];
+
+ // compute the volume to extrude
+ double volumeToOccupy = 0;
+ for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) {
+ // add external "perimeter gap"
+ double poylineVolume = flow.height*unscaled(unscaled(poly->area()));
+ double perimeterRoundGap = unscaled(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ // add holes "perimeter gaps"
+ double holesGaps = 0;
+ for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole) {
+ holesGaps += unscaled(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ }
+ poylineVolume += perimeterRoundGap + holesGaps;
+
+ //extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
+ volumeToOccupy += poylineVolume;
+ }
+ //if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
+ // return;
+
+ //create root node
+ ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
+ //you don't want to sort the extrusions: big infill first, small second
+ eecroot->no_sort = true;
+
+ ExtrusionEntityCollection *eec;
+
+
+ // first infill
+ std::unique_ptr<Fill> f1 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
+ f1->bounding_box = this->bounding_box;
+ f1->spacing = init_spacing;
+ f1->layer_id = this->layer_id;
+ f1->z = this->z;
+ f1->angle = anglePass[0];
+ // Maximum length of the perimeter segment linking two infill lines.
+ f1->link_max_length = this->link_max_length;
+ // Used by the concentric infill pattern to clip the loops to create extrusion paths.
+ f1->loop_clipping = this->loop_clipping;
+ Surface surfaceNoOverlap(*surface);
+ if (flow.bridge) {
+
+ Polylines polylines_layer1 = f1->fill_surface(surface, params1);
+
+ if (!polylines_layer1.empty()) {
+ if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer1[0].points.size() > 3) {
+ polylines_layer1[0].points.erase(polylines_layer1[0].points.begin());
+ polylines_layer1[polylines_layer1.size() - 1].points.pop_back();
+ }
+
+ //compute the path of the nozzle
+ double lengthTot = 0;
+ int nbLines = 0;
+ for (auto pline = polylines_layer1.begin(); pline != polylines_layer1.end(); ++pline) {
+ Lines lines = pline->lines();
+ for (auto line = lines.begin(); line != lines.end(); ++line) {
+ lengthTot += unscaled(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+ if (extrudedVolume == 0) extrudedVolume = 1;
+
+ // Save into layer smoothing path.
+ // print thin
+
+ eec = new ExtrusionEntityCollection();
+ eecroot->entities.push_back(eec);
+ eec->no_sort = false; //can be sorted inside the pass
+ extrusion_entities_append_paths(
+ eec->entities, std::move(polylines_layer1),
+ flow.bridge ? erBridgeInfill : rolePass[0],
+ //reduced flow height for a better view (it's only a gui thing)
+ params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
+ (float)(flow.width*percentFlow[0] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1)), (float)flow.height*0.8);
+ } else {
+ return;
+ }
+
+ } else {
+ for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) {
+ surfaceNoOverlap.expolygon = *poly;
+ Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
+ if (!polylines_layer1.empty()) {
+
+ double lengthTot = 0;
+ int nbLines = 0;
+ for (auto pline = polylines_layer1.begin(); pline != polylines_layer1.end(); ++pline) {
+ Lines lines = pline->lines();
+ for (auto line = lines.begin(); line != lines.end(); ++line) {
+ lengthTot += unscaled(line->length());
+ nbLines++;
+ }
+ }
+
+ // add external "perimeter gap"
+ double poylineVolume = flow.height*unscaled(unscaled(poly->area()));
+ double perimeterRoundGap = unscaled(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ // add holes "perimeter gaps"
+ double holesGaps = 0;
+ for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole) {
+ holesGaps += unscaled(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
+ }
+ poylineVolume += perimeterRoundGap + holesGaps;
+
+ //extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+
+ eec = new ExtrusionEntityCollection();
+ eecroot->entities.push_back(eec);
+ eec->no_sort = false; //can be sorted inside the pass
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = flow.bridge ? erBridgeInfill : rolePass[0];
+ }
+ extrusion_entities_append_paths(
+ eec->entities, std::move(polylines_layer1),
+ good_role,
+ //reduced flow height for a better view (it's only a gui thing)
+ params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1),
+ (float)(flow.width*percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1)), (float)flow.height*0.8);
+ } else {
+ return;
+ }
+ }
+ }
+
+ //second infill
+ if (nbPass > 1){
+
+ std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[1]));
+ f2->bounding_box = this->bounding_box;
+ f2->spacing = init_spacing;
+ f2->layer_id = this->layer_id;
+ f2->z = this->z;
+ f2->angle = anglePass[1];
+ // Maximum length of the perimeter segment linking two infill lines.
+ f2->link_max_length = this->link_max_length;
+ // Used by the concentric infill pattern to clip the loops to create extrusion paths.
+ f2->loop_clipping = this->loop_clipping;
+ Polylines polylines_layer2 = f2->fill_surface(surface, params2);
+
+ if (!polylines_layer2.empty()){
+ if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer2[0].points.size() > 3){
+ polylines_layer2[0].points.erase(polylines_layer2[0].points.begin());
+ polylines_layer2[polylines_layer2.size() - 1].points.pop_back();
+ }
+
+ //compute the path of the nozzle
+ double lengthTot = 0;
+ int nbLines = 0;
+ for (auto pline = polylines_layer2.begin(); pline != polylines_layer2.end(); ++pline){
+ Lines lines = pline->lines();
+ for (auto line = lines.begin(); line != lines.end(); ++line){
+ lengthTot += unscaled(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+ if (extrudedVolume == 0) extrudedVolume = 1;
+
+ // Save into layer smoothing path.
+ eec = new ExtrusionEntityCollection();
+ eecroot->entities.push_back(eec);
+ eec->no_sort = false;
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = rolePass[1];
+ }
+ // print thin
+ extrusion_entities_append_paths(
+ eec->entities, std::move(polylines_layer2),
+ good_role,
+ params.flow_mult * flow.mm3_per_mm() * percentFlow[1] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
+ //min-reduced flow width for a better view (it's only a gui thing)
+ (float)(flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1])), (float)flow.height);
+ }
+ else{
+ return;
+ }
+ }
+
+ // third infill
+ if (nbPass > 2){
+ std::unique_ptr<Fill> f3 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
+ f3->bounding_box = this->bounding_box;
+ f3->spacing = init_spacing;
+ f3->layer_id = this->layer_id;
+ f3->z = this->z;
+ f3->angle = anglePass[2];
+ // Maximum length of the perimeter segment linking two infill lines.
+ f3->link_max_length = this->link_max_length;
+ // Used by the concentric infill pattern to clip the loops to create extrusion paths.
+ f3->loop_clipping = this->loop_clipping;
+ Polylines polylines_layer3 = f3->fill_surface(surface, params1);
+
+ if (!polylines_layer3.empty()){
+
+ //remove some points that are not inside the area
+ if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer3[0].points.size() > 3){
+ polylines_layer3[0].points.erase(polylines_layer3[0].points.begin());
+ polylines_layer3[polylines_layer3.size() - 1].points.pop_back();
+ }
+
+ //compute the path of the nozzle
+ double lengthTot = 0;
+ int nbLines = 0;
+ for (auto pline = polylines_layer3.begin(); pline != polylines_layer3.end(); ++pline){
+ Lines lines = pline->lines();
+ for (auto line = lines.begin(); line != lines.end(); ++line){
+ lengthTot += unscaled(line->length());
+ nbLines++;
+ }
+ }
+ double extrudedVolume = flow.mm3_per_mm() * lengthTot;
+
+ // Save into layer smoothing path. layer 3
+ eec = new ExtrusionEntityCollection();
+ eecroot->entities.push_back(eec);
+ eec->no_sort = false;
+ //get the role
+ ExtrusionRole good_role = role;
+ if (good_role == erNone || good_role == erCustom) {
+ good_role = rolePass[2];
+ }
+ // print thin
+ extrusion_entities_append_paths(
+ eec->entities, std::move(polylines_layer3),
+ good_role, //slow (if last)
+ //reduced flow width for a better view (it's only a gui thing)
+ params.flow_mult * flow.mm3_per_mm() * percentFlow[2] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
+ (float)(flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2])), (float)flow.height);
+ }
+ }
+
+ if (!eecroot->entities.empty())
+ out.push_back(eecroot);
+ else delete eecroot;
+
+ }
+
+} // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillSmooth.hpp b/src/libslic3r/Fill/FillSmooth.hpp
new file mode 100644
index 000000000..eb558f088
--- /dev/null
+++ b/src/libslic3r/Fill/FillSmooth.hpp
@@ -0,0 +1,112 @@
+#ifndef slic3r_FillSmooth_hpp_
+#define slic3r_FillSmooth_hpp_
+
+#include "../libslic3r.h"
+
+#include "FillBase.hpp"
+
+namespace Slic3r {
+
+class FillSmooth : public Fill
+{
+public:
+ FillSmooth() {
+ nbPass = 2;
+ anglePass[0] = float(M_PI/4);
+ anglePass[1] = -float(M_PI/4);
+ anglePass[2] = 0;
+ fillPattern[0] = InfillPattern::ipRectilinear;
+ fillPattern[1] = InfillPattern::ipRectilinear;
+ fillPattern[2] = InfillPattern::ipRectilinear;
+ rolePass[0] = erSolidInfill;
+ rolePass[1] = erTopSolidInfill;
+ rolePass[2] = erSolidInfill;
+ percentWidth[0] = 0.9;
+ percentWidth[1] = 2;
+ percentWidth[2] = 1.0;
+ percentFlow[0] = 0.7;
+ percentFlow[1] = 0.3;
+ percentFlow[2] = 0.0;
+ double extrusionMult = 1.0;
+ percentFlow[0] *= extrusionMult;
+ percentFlow[1] *= extrusionMult;
+ percentFlow[2] *= extrusionMult;
+ }
+ virtual Fill* clone() const { return new FillSmooth(*this); }
+
+ virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out);
+
+protected:
+ int nbPass=2;
+ double percentWidth[3];
+ double percentFlow[3];
+ float anglePass[3];
+ ExtrusionRole rolePass[3];
+ InfillPattern fillPattern[3];
+};
+
+
+class FillSmoothTriple : public FillSmooth
+{
+public:
+ FillSmoothTriple() {
+ nbPass = 3;
+ anglePass[0] = float(M_PI / 4);
+ anglePass[1] = -float(M_PI / 4);
+ anglePass[2] = float(M_PI / 12); //align with nothing
+ fillPattern[0] = InfillPattern::ipRectilinear;
+ fillPattern[1] = InfillPattern::ipConcentric;
+ fillPattern[2] = InfillPattern::ipRectilinear;
+ rolePass[0] = erSolidInfill;
+ rolePass[1] = erSolidInfill;
+ rolePass[2] = erTopSolidInfill;
+ percentWidth[0] = 0.8;
+ percentWidth[1] = 1.5;
+ percentWidth[2] = 2.8;
+ percentFlow[0] = 0.7;
+ percentFlow[1] = 0.2;
+ percentFlow[2] = 0.1;
+ double extrusionMult = 1.0;
+ percentFlow[0] *= extrusionMult;
+ percentFlow[1] *= extrusionMult;
+ percentFlow[2] *= extrusionMult;
+ }
+ virtual Fill* clone() const { return new FillSmoothTriple(*this); }
+
+};
+
+class FillSmoothHilbert : public FillSmooth
+{
+public:
+ FillSmoothHilbert() {
+ nbPass = 2;
+ anglePass[0] = 0;
+ anglePass[1] = -float(M_PI / 4);
+ anglePass[2] = float(M_PI / 4);
+ fillPattern[0] = InfillPattern::ipHilbertCurve; //ipHilbertCurve
+ fillPattern[1] = InfillPattern::ipRectilinear;
+ fillPattern[2] = InfillPattern::ipRectilinear;
+ rolePass[0] = erSolidInfill;
+ rolePass[1] = erSolidInfill;
+ rolePass[2] = erTopSolidInfill;
+ percentWidth[0] = 1.0;
+ percentWidth[1] = 1.0;
+ percentWidth[2] = 1.0;
+ percentFlow[0] = 0.8;
+ percentFlow[1] = 0.1;
+ percentFlow[2] = 0.1;
+ double extrusionMult = 1.0;
+ percentFlow[0] *= extrusionMult;
+ percentFlow[1] *= extrusionMult;
+ percentFlow[2] *= extrusionMult;
+ }
+ virtual Fill* clone() const { return new FillSmoothHilbert(*this); }
+
+};
+
+
+} // namespace Slic3r
+
+#endif // slic3r_FillSmooth_hpp_
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 67264b16f..f6255bb1e 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -283,7 +283,7 @@ std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gco
std::string WipeTowerIntegration::prime(GCode &gcodegen)
{
- assert(m_layer_idx == 0);
+ //assert(m_layer_idx == 0);
std::string gcode;
if (&m_priming != nullptr && ! m_priming.extrusions.empty()) {
@@ -406,7 +406,7 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
// Assign an average print_z to the set of layers with nearly equal print_z.
merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z);
merged.second.assign(print.objects().size(), LayerToPrint());
- for (; i < j; ++i) {
+ for (; i < j; ++ i) {
const OrderingItem &oi = ordering[i];
assert(merged.second[oi.object_idx].layer() == nullptr);
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
@@ -729,9 +729,9 @@ void GCode::_do_export(Print &print, FILE *file)
break;
}
} else {
- // Find tool ordering for all the objects at once, and the initial extruder ID.
+ // Find tool ordering for all the objects at once, and the initial extruder ID.
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
- tool_ordering = print.wipe_tower_data().tool_ordering.empty() ?
+ tool_ordering = print.wipe_tower_data().tool_ordering.empty() ?
ToolOrdering(print, initial_extruder_id) :
print.wipe_tower_data().tool_ordering;
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
@@ -941,7 +941,8 @@ void GCode::_do_export(Print &print, FILE *file)
m_wipe_tower.reset(new WipeTowerIntegration(print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()));
_write(file, m_writer.travel_to_z(first_layer_height + m_config.z_offset.value, "Move to the first layer height"));
if (print.config().single_extruder_multi_material_priming) {
- _write(file, m_wipe_tower->prime(*this));
+ //m_wipe_tower->next_layer();
+ _write(file, m_wipe_tower->prime(*this));
// Verify, whether the print overaps the priming extrusions.
BoundingBoxf bbox_print(get_print_extrusions_extents(print));
coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON;
@@ -1476,8 +1477,8 @@ void GCode::process_layer(
if (layerm == nullptr)
continue;
const PrintRegion &region = *print.regions()[region_id];
-
-
+
+
// Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
// It is also necessary to save which extrusions are part of MM wiping and which are not.
// The process is almost the same for perimeters and infills - we will do it in a cycle that repeats twice:
@@ -1515,16 +1516,19 @@ void GCode::process_layer(
extruder,
&layer_to_print - layers.data(),
layers.size(), n_slices+1);
- for (size_t i = 0; i <= n_slices; ++i)
+ for (size_t i = 0; i <= n_slices; ++i) {
if (// fill->first_point does not fit inside any slice
i == n_slices ||
// fill->first_point fits inside ith slice
point_inside_surface(i, fill->first_point())) {
- if (islands[i].by_region.empty())
+ if (islands[i].by_region.empty()) {
islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
+ }
+ //don't do fill->entities because it will discard no_sort
islands[i].by_region[region_id].append(entity_type, fill, entity_overrides, layer_to_print.object()->copies().size());
break;
}
+ }
}
}
}
@@ -1538,7 +1542,7 @@ void GCode::process_layer(
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
std::vector<std::unique_ptr<EdgeGrid::Grid>> lower_layer_edge_grids(layers.size());
for (unsigned int extruder_id : layer_tools.extruders)
- {
+ {
gcode += (layer_tools.has_wipe_tower && m_wipe_tower) ?
m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()) :
this->set_extruder(extruder_id);
@@ -1572,13 +1576,13 @@ void GCode::process_layer(
m_avoid_crossing_perimeters.disable_once = true;
}
}
-
+
// Extrude brim with the extruder of the 1st region.
if (! m_brim_done) {
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp = true;
for (const ExtrusionEntity *ee : print.brim().entities)
- gcode += this->extrude_loop(*dynamic_cast<const ExtrusionLoop*>(ee), "brim", m_config.support_material_speed.value);
+ gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value);
m_brim_done = true;
m_avoid_crossing_perimeters.use_external_mp = false;
// Allow a straight travel move to the first object point.
@@ -1599,23 +1603,27 @@ void GCode::process_layer(
for (ObjectByExtruder &object_by_extruder : objects_by_extruder_it->second) {
const size_t layer_id = &object_by_extruder - objects_by_extruder_it->second.data();
const PrintObject *print_object = layers[layer_id].object();
- if (print_object == nullptr)
- // This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
- continue;
-
+ if (print_object == nullptr)
+ // This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
+ continue;
+
m_config.apply(print_object->config(), true);
m_layer = layers[layer_id].layer();
if (m_config.avoid_crossing_perimeters)
m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true));
Points copies;
- if (single_object_idx == size_t(-1))
+ if (single_object_idx == size_t(-1))
copies = print_object->copies();
else
copies.push_back(print_object->copies()[single_object_idx]);
- // Sort the copies by the closest point starting with the current print position.
-
+ //FIXME: Sort the copies by the closest point starting with the current print position.
+ // be careful to set a good copy_idx (used to identify the copy).
+
unsigned int copy_id = 0;
for (const Point &copy : copies) {
+ if (this->config().label_printed_objects) {
+ gcode += ((std::ostringstream&)(std::ostringstream() << "; printing object " << print_object->model_object()->name << " id:" << layer_id << " copy " << copy_id << "\n")).str();
+ }
// When starting a new object, use the external motion planner for the first travel move.
std::pair<const PrintObject*, Point> this_object_copy(print_object, copy);
if (m_last_obj_copy != this_object_copy)
@@ -1632,13 +1640,12 @@ void GCode::process_layer(
for (ObjectByExtruder::Island &island : object_by_extruder.islands) {
const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(copy_id, extruder_id, print_wipe_extrusions) : island.by_region;
- if (print.config().infill_first) {
- gcode += this->extrude_infill(print, by_region_specific);
- gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
- } else {
- gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
- gcode += this->extrude_infill(print,by_region_specific);
- }
+ gcode += this->extrude_infill(print, by_region_specific, true);
+ gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
+ gcode += this->extrude_infill(print, by_region_specific, false);
+ }
+ if (this->config().label_printed_objects) {
+ gcode += ((std::ostringstream&)(std::ostringstream() << "; stop printing object " << print_object->model_object()->name << " id:" << layer_id << " copy " << copy_id << "\n")).str();
}
++copy_id;
}
@@ -1663,7 +1670,7 @@ void GCode::process_layer(
if (m_pressure_equalizer)
gcode = m_pressure_equalizer->process(gcode.c_str(), false);
// printf("G-code after filter:\n%s\n", out.c_str());
-
+
_write(file, gcode);
BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z <<
", time estimator memory: " <<
@@ -1696,7 +1703,7 @@ void GCode::append_full_config(const Print& print, std::string& str)
const ConfigOption *opt = full_config.option(key);
if (opt != nullptr)
str += std::string("; ") + key + " = " + opt->serialize() + "\n";
- }
+ }
}
void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
@@ -1983,9 +1990,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
#endif
}
}
-
+
// extrude all loops ccw
- bool was_clockwise = loop.make_counter_clockwise();
+ //no! this was decided in perimeter_generator
+ bool was_clockwise = false;// loop.make_counter_clockwise();
SeamPosition seam_position = m_config.seam_position;
if (loop.loop_role() == elrSkirt)
@@ -1996,7 +2004,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
Point last_pos = this->last_pos();
if (m_config.spiral_vase) {
loop.split_at(last_pos, false);
- } else if (seam_position == spNearest || seam_position == spAligned || seam_position == spRear) {
+ } else if (seam_position == spNearest || seam_position == spAligned || seam_position == spRear || seam_position == spHidden) {
Polygon polygon = loop.polygon();
const coordf_t nozzle_dmr = EXTRUDER_CONFIG(nozzle_diameter);
const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5);
@@ -2011,11 +2019,18 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
last_pos_weight = 1.f;
}
break;
+ case spNearest:
+ last_pos_weight = 5.f;
+ break;
case spRear:
last_pos = m_layer->object()->bounding_box().center();
last_pos(1) += coord_t(3. * m_layer->object()->bounding_box().radius());
last_pos_weight = 5.f;
break;
+ case spHidden:
+ last_pos_weight = 0.1f;
+ break;
+
}
// Insert a projection of last_pos into the polygon.
@@ -2037,7 +2052,16 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
const float penaltySeam = 1.3f;
const float penaltyOverhangHalf = 10.f;
// Penalty for visible seams.
- for (size_t i = 0; i < polygon.points.size(); ++ i) {
+ float dist_max = 0.1f * lengths.back();// 5.f * nozzle_dmr
+ if (this->config().seam_travel) {
+ dist_max = 0;
+ for (size_t i = 0; i < polygon.points.size(); ++i) {
+ dist_max = std::max(dist_max, (float)polygon.points[i].distance_to(last_pos_proj));
+ }
+ }
+ //TODO: ignore the angle penalty if the new point is not in an external path (bot/top/ext_peri)
+ for (size_t i = 0; i < polygon.points.size(); ++i) {
+ //std::cout << "check point @" << unscale(polygon.points[i].x) << ":" << unscale(polygon.points[i].y);
float ccwAngle = penalties[i];
if (was_clockwise)
ccwAngle = - ccwAngle;
@@ -2058,13 +2082,15 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// Interpolate penalty between maximum and the penalty for a convex vertex.
penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.));
}
- // Give a negative penalty for points close to the last point or the prefered seam location.
- //float dist_to_last_pos_proj = last_pos_proj.distance_to(polygon.points[i]);
- float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
- std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
- std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
- float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr
- penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
+ if (this->config().seam_travel) {
+ penalty += last_pos_weight * polygon.points[i].distance_to(last_pos_proj) / dist_max;
+ }else{
+ // Give a negative penalty for points close to the last point or the prefered seam location.
+ float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
+ std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
+ std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
+ penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
+ }
penalties[i] = std::max(0.f, penalty);
}
@@ -2248,7 +2274,16 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string des
return this->extrude_multi_path(*multipath, description, speed);
else if (const ExtrusionLoop* loop = dynamic_cast<const ExtrusionLoop*>(&entity))
return this->extrude_loop(*loop, description, speed, lower_layer_edge_grid);
- else {
+ else if (const ExtrusionEntityCollection* coll = dynamic_cast<const ExtrusionEntityCollection*>(&entity)){
+ std::string gcode;
+ ExtrusionEntityCollection chained;
+ if (coll->no_sort) chained = *coll;
+ else chained = coll->chained_path_from(m_last_pos, false);
+ for (ExtrusionEntity *next_entity : chained.entities) {
+ gcode += extrude_entity(*next_entity, description, speed, lower_layer_edge_grid);
+ }
+ return gcode;
+ } else {
throw std::invalid_argument("Invalid argument supplied to extrude()");
return "";
}
@@ -2281,20 +2316,14 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
}
// Chain the paths hierarchically by a greedy algorithm to minimize a travel distance.
-std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region)
+std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool is_infill_first)
{
std::string gcode;
for (const ObjectByExtruder::Island::Region &region : by_region) {
- m_config.apply(print.regions()[&region - &by_region.front()]->config());
- ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
- for (ExtrusionEntity *fill : chained.entities) {
- auto *eec = dynamic_cast<ExtrusionEntityCollection*>(fill);
- if (eec) {
- ExtrusionEntityCollection chained2 = eec->chained_path_from(m_last_pos, false);
- for (ExtrusionEntity *ee : chained2.entities)
- gcode += this->extrude_entity(*ee, "infill");
- } else
- gcode += this->extrude_entity(*fill, "infill");
+ if (print.regions()[&region - &by_region.front()]->config().infill_first == is_infill_first) {
+ m_config.apply(print.regions()[&region - &by_region.front()]->config());
+ ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
+ gcode += extrude_entity(chained, "infill");
}
}
return gcode;
@@ -2311,6 +2340,10 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
for (const ExtrusionEntity *ee : support_fills.entities) {
ExtrusionRole role = ee->role();
assert(role == erSupportMaterial || role == erSupportMaterialInterface);
+ if (const ExtrusionEntityCollection* coll = dynamic_cast<const ExtrusionEntityCollection*>(ee)) {
+ gcode += extrude_support(*coll);
+ continue;
+ }
const char *label = (role == erSupportMaterial) ? support_label : support_interface_label;
const double speed = (role == erSupportMaterial) ? support_speed : support_interface_speed;
const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ee);
@@ -2433,12 +2466,17 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
speed = m_config.get_abs_value("top_solid_infill_speed");
} else if (path.role() == erGapFill) {
speed = m_config.get_abs_value("gap_fill_speed");
+ } else if (path.role() == erNone) {
+ speed = m_config.get_abs_value("travel_speed");
} else {
throw std::invalid_argument("Invalid speed");
}
}
if (this->on_first_layer())
- speed = m_config.get_abs_value("first_layer_speed", speed);
+ if (path.role() == erInternalInfill || path.role() == erSolidInfill)
+ speed = std::min(m_config.get_abs_value("first_layer_infill_speed", speed), speed);
+ else
+ speed = std::min(m_config.get_abs_value("first_layer_speed", speed), speed);
if (m_volumetric_speed != 0. && speed == 0)
speed = m_volumetric_speed / path.mm3_per_mm;
if (m_config.max_volumetric_speed.value > 0) {
@@ -2462,15 +2500,15 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
{
if (path.role() != m_last_extrusion_role)
{
- m_last_extrusion_role = path.role();
if (m_enable_extrusion_role_markers)
{
char buf[32];
- sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(m_last_extrusion_role));
+ sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(path.role()));
gcode += buf;
}
}
}
+ m_last_extrusion_role = path.role();
// adds analyzer tags and updates analyzer's tracking data
if (m_enable_analyzer)
@@ -2515,6 +2553,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (m_enable_cooling_markers) {
if (is_bridge(path.role()))
gcode += ";_BRIDGE_FAN_START\n";
+ else if (ExtrusionRole::erTopSolidInfill == path.role())
+ gcode += ";_TOP_FAN_START\n";
else
comment = ";_EXTRUDE_SET_SPEED";
if (path.role() == erExternalPerimeter)
@@ -2536,7 +2576,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
}
}
if (m_enable_cooling_markers)
- gcode += is_bridge(path.role()) ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
+ if (is_bridge(path.role()))
+ gcode += ";_BRIDGE_FAN_END\n";
+ else if (ExtrusionRole::erTopSolidInfill == path.role())
+ gcode += ";_TOP_FAN_END\n";
+ else
+ gcode += ";_EXTRUDE_END\n";
+
this->set_last_pos(path.last_point());
return gcode;
@@ -2623,6 +2669,10 @@ std::string GCode::retract(bool toolchange)
if (m_writer.extruder() == nullptr)
return gcode;
+
+ // We need to reset e before any extrusion or wipe to allow the reset to happen at the real
+ // begining of an object gcode
+ gcode += m_writer.reset_e();
// wipe (if it's enabled for this extruder and we have a stored wipe path)
if (EXTRUDER_CONFIG(wipe) && m_wipe.has_path()) {
@@ -2635,10 +2685,9 @@ std::string GCode::retract(bool toolchange)
methods even if we performed wipe, since this will ensure the entire retraction
length is honored in case wipe path was too short. */
gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract();
-
- gcode += m_writer.reset_e();
- if (m_writer.extruder()->retract_length() > 0 || m_config.use_firmware_retraction)
- gcode += m_writer.lift();
+ if (toolchange || !this->m_config.retract_lift_not_last_layer.get_at(m_writer.extruder()->id()) || !(this->m_last_extrusion_role == ExtrusionRole::erTopSolidInfill))
+ if (m_writer.extruder()->retract_length() > 0 || m_config.use_firmware_retraction)
+ gcode += m_writer.lift();
return gcode;
}
@@ -2768,9 +2817,11 @@ void GCode::ObjectByExtruder::Island::Region::append(const std::string& type, co
// First we append the entities, there are eec->entities.size() of them:
- perimeters_or_infills->append(eec->entities);
+ //don't do fill->entities because it will discard no_sort, we must use flattenIfSortable()
+ ExtrusionEntitiesPtr entities = eec->flattenIfSortable().entities;
+ perimeters_or_infills->append(entities);
- for (unsigned int i=0;i<eec->entities.size();++i)
+ for (unsigned int i = 0; i<entities.size(); ++i)
perimeters_or_infills_overrides->push_back(copies_extruder);
}
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 86a6cacee..a754310b7 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -250,8 +250,8 @@ protected:
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, std::unique_ptr<EdgeGrid::Grid> &lower_layer_edge_grid);
- std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region);
- std::string extrude_support(const ExtrusionEntityCollection &support_fills);
+ std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool is_infill_first);
+ std::string extrude_support(const ExtrusionEntityCollection &support_fills);
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp
index 40ccc7b09..be3070d4d 100644
--- a/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -37,15 +37,17 @@ struct CoolingLine
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,
+ TYPE_TOP_FAN_START = 1 << 4,
+ TYPE_TOP_FAN_END = 1 << 5,
+ TYPE_G0 = 1 << 6,
+ TYPE_G1 = 1 << 7,
+ TYPE_ADJUSTABLE = 1 << 8,
+ TYPE_EXTERNAL_PERIMETER = 1 << 9,
// The line sets a feedrate.
- TYPE_HAS_F = 1 << 8,
- TYPE_WIPE = 1 << 9,
- TYPE_G4 = 1 << 10,
- TYPE_G92 = 1 << 11,
+ TYPE_HAS_F = 1 << 10,
+ TYPE_WIPE = 1 << 11,
+ TYPE_G4 = 1 << 12,
+ TYPE_G92 = 1 << 13,
};
CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
@@ -369,6 +371,10 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
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, ";_TOP_FAN_START")) {
+ line.type = CoolingLine::TYPE_TOP_FAN_START;
+ } else if (boost::starts_with(sline, ";_TOP_FAN_END")) {
+ line.type = CoolingLine::TYPE_TOP_FAN_END;
} else if (boost::starts_with(sline, "G4 ")) {
// Parse the wait time.
line.type = CoolingLine::TYPE_G4;
@@ -609,8 +615,10 @@ std::string CoolingBuffer::apply_layer_cooldown(
new_gcode.reserve(gcode.size() * 2);
int fan_speed = -1;
bool bridge_fan_control = false;
- int bridge_fan_speed = 0;
- auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() {
+ int bridge_fan_speed = 0;
+ bool top_fan_control = false;
+ int top_fan_speed = 0;
+ auto change_extruder_set_fan = [this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed, &top_fan_control, &top_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);
@@ -631,11 +639,15 @@ std::string CoolingBuffer::apply_layer_cooldown(
}
}
bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed);
+ top_fan_speed = EXTRUDER_CONFIG(top_fan_speed);
#undef EXTRUDER_CONFIG
bridge_fan_control = bridge_fan_speed > fan_speed_new;
+ top_fan_control = top_fan_speed != fan_speed_new;
} else {
bridge_fan_control = false;
bridge_fan_speed = 0;
+ top_fan_control = false;
+ top_fan_speed = 0;
fan_speed_new = 0;
}
if (fan_speed_new != fan_speed) {
@@ -666,6 +678,12 @@ std::string CoolingBuffer::apply_layer_cooldown(
} 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 & CoolingLine::TYPE_TOP_FAN_START) {
+ if (top_fan_control)
+ new_gcode += m_gcodegen.writer().set_fan(top_fan_speed, true);
+ } else if (line->type & CoolingLine::TYPE_TOP_FAN_END) {
+ if (top_fan_control)
+ new_gcode += m_gcodegen.writer().set_fan(fan_speed, true);
} else if (line->type & CoolingLine::TYPE_EXTRUDE_END) {
// Just remove this comment.
} else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) {
diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp
index e99eeac02..232bbc249 100644
--- a/src/libslic3r/GCode/PreviewData.cpp
+++ b/src/libslic3r/GCode/PreviewData.cpp
@@ -402,6 +402,8 @@ std::string GCodePreviewData::get_legend_title() const
return L("Volumetric flow rate (mm3/s)");
case Extrusion::Tool:
return L("Tool");
+ case Extrusion::Filament:
+ return L("Filament");
case Extrusion::ColorPrint:
return L("Color Print");
}
@@ -465,6 +467,7 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
break;
}
case Extrusion::Tool:
+ case Extrusion::Filament:
{
unsigned int tools_colors_count = tool_colors.size() / 4;
items.reserve(tools_colors_count);
diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp
index 4ca579d9a..6a214890f 100644
--- a/src/libslic3r/GCode/PreviewData.hpp
+++ b/src/libslic3r/GCode/PreviewData.hpp
@@ -76,6 +76,7 @@ public:
Feedrate,
VolumetricRate,
Tool,
+ Filament,
ColorPrint,
Num_View_Types
};
diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp
index e800cd53f..51622e39a 100644
--- a/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/src/libslic3r/GCode/ToolOrdering.cpp
@@ -485,7 +485,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
continue;
- if ((!print.config().infill_first ? perimeters_done : !perimeters_done) || (!object->config().wipe_into_objects && region.config().wipe_into_infill)) {
+ if ((!region.config().infill_first ? perimeters_done : !perimeters_done) || (!object->config().wipe_into_objects && region.config().wipe_into_infill)) {
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
@@ -498,7 +498,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
if (volume_to_wipe<=0)
continue;
- if (!object->config().wipe_into_objects && !print.config().infill_first && region.config().wipe_into_infill)
+ if (!object->config().wipe_into_objects && !region.config().infill_first && region.config().wipe_into_infill)
// In this case we must check that the original extruder is used on this layer before the one we are overridding
// (and the perimeters will be finished before the infill is printed):
if (!lt.is_extruder_order(region.config().perimeter_extruder - 1, new_extruder))
@@ -512,7 +512,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
}
// Now the same for perimeters - see comments above for explanation:
- if (object->config().wipe_into_objects && (print.config().infill_first ? perimeters_done : !perimeters_done))
+ if (object->config().wipe_into_objects && (region.config().infill_first ? perimeters_done : !perimeters_done))
{
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) {
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
@@ -572,12 +572,12 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
// printed before its perimeter, or not be printed at all (in case its original extruder has
// not been added to LayerTools
// Either way, we will now force-override it with something suitable:
- if (print.config().infill_first
+ if (region.config().infill_first
|| object->config().wipe_into_objects // in this case the perimeter is overridden, so we can override by the last one safely
|| lt.is_extruder_order(region.config().perimeter_extruder - 1, last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints
|| std::find(lt.extruders.begin(), lt.extruders.end(), region.config().infill_extruder - 1) == lt.extruders.end()) // we have to force override - this could violate infill_first (FIXME)
)
- set_extruder_override(fill, copy, (print.config().infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
+ set_extruder_override(fill, copy, (region.config().infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
else {
// In this case we can (and should) leave it to be printed normally.
// Force overriding would mean it gets printed before its perimeter.
@@ -591,7 +591,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|| is_entity_overridden(fill, copy) )
continue;
- set_extruder_override(fill, copy, (print.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
+ set_extruder_override(fill, copy, (region.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
}
}
}
diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index f87969505..eb41d6139 100644
--- a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -691,28 +691,30 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo
m_wipe_tower_width,
m_wipe_tower_depth);
- PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width);
+ //use first layer width parameter
+
+ PrusaMultiMaterial::Writer writer(m_layer_height, m_brim_width);
writer.set_extrusion_flow(m_extrusion_flow * 1.1f)
.set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop.
.set_initial_tool(m_current_tool)
.append(";-------------------------------------\n"
"; CP WIPE TOWER FIRST LAYER BRIM START\n");
- xy initial_position = wipeTower_box.lu - xy(m_perimeter_width * 6.f, 0);
+ xy initial_position = wipeTower_box.lu - xy(m_brim_width * 6.f, 0);
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
- writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
+ writer.extrude_explicit(wipeTower_box.ld - xy(m_brim_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.
box_coordinates box(wipeTower_box);
- box.expand(m_perimeter_width);
+ box.expand(m_brim_width);
for (size_t i = 0; i < 4; ++ i) {
writer.travel (box.ld, 7000)
.extrude(box.lu, 2100).extrude(box.ru)
.extrude(box.rd ).extrude(box.ld);
- box.expand(m_perimeter_width);
+ box.expand(m_brim_width);
}
writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner.
diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
index 70c9526e6..42e3417d3 100644
--- a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
+++ b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
@@ -46,7 +46,7 @@ public:
WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
float cooling_tube_length, float parking_pos_retraction, float extra_loading_move,
float bridging, bool set_extruder_trimpot,
- const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
+ const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool, float first_layer_width) :
m_wipe_tower_pos(x, y),
m_wipe_tower_width(width),
m_wipe_tower_rotation_angle(rotation_angle),
@@ -60,7 +60,8 @@ public:
m_bridging(bridging),
m_set_extruder_trimpot(set_extruder_trimpot),
m_current_tool(initial_tool),
- wipe_volumes(wiping_matrix)
+ wipe_volumes(wiping_matrix),
+ m_brim_width(first_layer_width)
{}
virtual ~WipeTowerPrusaMM() {}
@@ -223,7 +224,8 @@ private:
bool m_retain_speed_override = true;
bool m_adhesion = true;
- float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
+ float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
+ float m_brim_width = 0.4 * Width_To_Nozzle_Ratio * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
float m_extrusion_flow = 0.038; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp
index b84e2f13d..7f25446c5 100644
--- a/src/libslic3r/Geometry.cpp
+++ b/src/libslic3r/Geometry.cpp
@@ -893,273 +893,6 @@ private:
const Lines &lines;
};
-void
-MedialAxis::build(ThickPolylines* polylines)
-{
- construct_voronoi(this->lines.begin(), this->lines.end(), &this->vd);
-
- /*
- // DEBUG: dump all Voronoi edges
- {
- for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
- if (edge->is_infinite()) continue;
-
- ThickPolyline polyline;
- polyline.points.push_back(Point( edge->vertex0()->x(), edge->vertex0()->y() ));
- polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() ));
- polylines->push_back(polyline);
- }
- return;
- }
- */
-
- typedef const VD::vertex_type vert_t;
- typedef const VD::edge_type edge_t;
-
- // collect valid edges (i.e. prune those not belonging to MAT)
- // note: this keeps twins, so it inserts twice the number of the valid edges
- this->valid_edges.clear();
- {
- std::set<const VD::edge_type*> seen_edges;
- for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
- // if we only process segments representing closed loops, none if the
- // infinite edges (if any) would be part of our MAT anyway
- if (edge->is_secondary() || edge->is_infinite()) continue;
-
- // don't re-validate twins
- if (seen_edges.find(&*edge) != seen_edges.end()) continue; // TODO: is this needed?
- seen_edges.insert(&*edge);
- seen_edges.insert(edge->twin());
-
- if (!this->validate_edge(&*edge)) continue;
- this->valid_edges.insert(&*edge);
- this->valid_edges.insert(edge->twin());
- }
- }
- this->edges = this->valid_edges;
-
- // iterate through the valid edges to build polylines
- while (!this->edges.empty()) {
- const edge_t* edge = *this->edges.begin();
-
- // start a polyline
- ThickPolyline polyline;
- polyline.points.push_back(Point( edge->vertex0()->x(), edge->vertex0()->y() ));
- polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() ));
- polyline.width.push_back(this->thickness[edge].first);
- polyline.width.push_back(this->thickness[edge].second);
-
- // remove this edge and its twin from the available edges
- (void)this->edges.erase(edge);
- (void)this->edges.erase(edge->twin());
-
- // get next points
- this->process_edge_neighbors(edge, &polyline);
-
- // get previous points
- {
- ThickPolyline rpolyline;
- this->process_edge_neighbors(edge->twin(), &rpolyline);
- polyline.points.insert(polyline.points.begin(), rpolyline.points.rbegin(), rpolyline.points.rend());
- polyline.width.insert(polyline.width.begin(), rpolyline.width.rbegin(), rpolyline.width.rend());
- polyline.endpoints.first = rpolyline.endpoints.second;
- }
-
- assert(polyline.width.size() == polyline.points.size()*2 - 2);
-
- // prevent loop endpoints from being extended
- if (polyline.first_point() == polyline.last_point()) {
- polyline.endpoints.first = false;
- polyline.endpoints.second = false;
- }
-
- // append polyline to result
- polylines->push_back(polyline);
- }
-
- #ifdef SLIC3R_DEBUG
- {
- static int iRun = 0;
- dump_voronoi_to_svg(this->lines, this->vd, polylines, debug_out_path("MedialAxis-%d.svg", iRun ++).c_str());
- printf("Thick lines: ");
- for (ThickPolylines::const_iterator it = polylines->begin(); it != polylines->end(); ++ it) {
- ThickLines lines = it->thicklines();
- for (ThickLines::const_iterator it2 = lines.begin(); it2 != lines.end(); ++ it2) {
- printf("%f,%f ", it2->a_width, it2->b_width);
- }
- }
- printf("\n");
- }
- #endif /* SLIC3R_DEBUG */
-}
-
-void
-MedialAxis::build(Polylines* polylines)
-{
- ThickPolylines tp;
- this->build(&tp);
- polylines->insert(polylines->end(), tp.begin(), tp.end());
-}
-
-void
-MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* polyline)
-{
- while (true) {
- // Since rot_next() works on the edge starting point but we want
- // to find neighbors on the ending point, we just swap edge with
- // its twin.
- const VD::edge_type* twin = edge->twin();
-
- // count neighbors for this edge
- std::vector<const VD::edge_type*> neighbors;
- for (const VD::edge_type* neighbor = twin->rot_next(); neighbor != twin;
- neighbor = neighbor->rot_next()) {
- if (this->valid_edges.count(neighbor) > 0) neighbors.push_back(neighbor);
- }
-
- // if we have a single neighbor then we can continue recursively
- if (neighbors.size() == 1) {
- const VD::edge_type* neighbor = neighbors.front();
-
- // break if this is a closed loop
- if (this->edges.count(neighbor) == 0) return;
-
- Point new_point(neighbor->vertex1()->x(), neighbor->vertex1()->y());
- polyline->points.push_back(new_point);
- polyline->width.push_back(this->thickness[neighbor].first);
- polyline->width.push_back(this->thickness[neighbor].second);
- (void)this->edges.erase(neighbor);
- (void)this->edges.erase(neighbor->twin());
- edge = neighbor;
- } else if (neighbors.size() == 0) {
- polyline->endpoints.second = true;
- return;
- } else {
- // T-shaped or star-shaped joint
- return;
- }
- }
-}
-
-bool
-MedialAxis::validate_edge(const VD::edge_type* edge)
-{
- // prevent overflows and detect almost-infinite edges
- if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
- std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
- std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
- std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
- return false;
-
- // construct the line representing this edge of the Voronoi diagram
- const Line line(
- Point( edge->vertex0()->x(), edge->vertex0()->y() ),
- Point( edge->vertex1()->x(), edge->vertex1()->y() )
- );
-
- // discard edge if it lies outside the supplied shape
- // this could maybe be optimized (checking inclusion of the endpoints
- // might give false positives as they might belong to the contour itself)
- if (this->expolygon != NULL) {
- if (line.a == line.b) {
- // in this case, contains(line) returns a false positive
- if (!this->expolygon->contains(line.a)) return false;
- } else {
- if (!this->expolygon->contains(line)) return false;
- }
- }
-
- // retrieve the original line segments which generated the edge we're checking
- const VD::cell_type* cell_l = edge->cell();
- const VD::cell_type* cell_r = edge->twin()->cell();
- const Line &segment_l = this->retrieve_segment(cell_l);
- const Line &segment_r = this->retrieve_segment(cell_r);
-
- /*
- SVG svg("edge.svg");
- svg.draw(*this->expolygon);
- svg.draw(line);
- svg.draw(segment_l, "red");
- svg.draw(segment_r, "blue");
- svg.Close();
- */
-
- /* Calculate thickness of the cross-section at both the endpoints of this edge.
- Our Voronoi edge is part of a CCW sequence going around its Voronoi cell
- located on the left side. (segment_l).
- This edge's twin goes around segment_r. Thus, segment_r is
- oriented in the same direction as our main edge, and segment_l is oriented
- in the same direction as our twin edge.
- We used to only consider the (half-)distances to segment_r, and that works
- whenever segment_l and segment_r are almost specular and facing. However,
- at curves they are staggered and they only face for a very little length
- (our very short edge represents such visibility).
- Both w0 and w1 can be calculated either towards cell_l or cell_r with equal
- results by Voronoi definition.
- When cell_l or cell_r don't refer to the segment but only to an endpoint, we
- calculate the distance to that endpoint instead. */
-
- coordf_t w0 = cell_r->contains_segment()
- ? segment_r.distance_to(line.a)*2
- : (this->retrieve_endpoint(cell_r) - line.a).cast<double>().norm()*2;
-
- coordf_t w1 = cell_l->contains_segment()
- ? segment_l.distance_to(line.b)*2
- : (this->retrieve_endpoint(cell_l) - line.b).cast<double>().norm()*2;
-
- if (cell_l->contains_segment() && cell_r->contains_segment()) {
- // calculate the relative angle between the two boundary segments
- double angle = fabs(segment_r.orientation() - segment_l.orientation());
- if (angle > PI) angle = 2*PI - angle;
- assert(angle >= 0 && angle <= PI);
-
- // fabs(angle) ranges from 0 (collinear, same direction) to PI (collinear, opposite direction)
- // we're interested only in segments close to the second case (facing segments)
- // so we allow some tolerance.
- // this filter ensures that we're dealing with a narrow/oriented area (longer than thick)
- // we don't run it on edges not generated by two segments (thus generated by one segment
- // and the endpoint of another segment), since their orientation would not be meaningful
- if (PI - angle > PI/8) {
- // angle is not narrow enough
-
- // only apply this filter to segments that are not too short otherwise their
- // angle could possibly be not meaningful
- if (w0 < SCALED_EPSILON || w1 < SCALED_EPSILON || line.length() >= this->min_width)
- return false;
- }
- } else {
- if (w0 < SCALED_EPSILON || w1 < SCALED_EPSILON)
- return false;
- }
-
- if (w0 < this->min_width && w1 < this->min_width)
- return false;
-
- if (w0 > this->max_width && w1 > this->max_width)
- return false;
-
- this->thickness[edge] = std::make_pair(w0, w1);
- this->thickness[edge->twin()] = std::make_pair(w1, w0);
-
- return true;
-}
-
-const Line&
-MedialAxis::retrieve_segment(const VD::cell_type* cell) const
-{
- return this->lines[cell->source_index()];
-}
-
-const Point&
-MedialAxis::retrieve_endpoint(const VD::cell_type* cell) const
-{
- const Line& line = this->retrieve_segment(cell);
- if (cell->source_category() == SOURCE_CATEGORY_SEGMENT_START_POINT) {
- return line.a;
- } else {
- return line.b;
- }
-}
void assemble_transform(Transform3d& transform, const Vec3d& translation, const Vec3d& rotation, const Vec3d& scale, const Vec3d& mirror)
{
diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp
index deefaa789..743c3f22f 100644
--- a/src/libslic3r/Geometry.hpp
+++ b/src/libslic3r/Geometry.hpp
@@ -3,13 +3,11 @@
#include "libslic3r.h"
#include "BoundingBox.hpp"
+#include "MedialAxis.hpp"
#include "ExPolygon.hpp"
#include "Polygon.hpp"
#include "Polyline.hpp"
-#include "boost/polygon/voronoi.hpp"
-using boost::polygon::voronoi_builder;
-using boost::polygon::voronoi_diagram;
namespace Slic3r { namespace Geometry {
@@ -143,34 +141,6 @@ bool arrange(
// output
Pointfs &positions);
-class MedialAxis {
- public:
- Lines lines;
- const ExPolygon* expolygon;
- double max_width;
- double min_width;
- MedialAxis(double _max_width, double _min_width, const ExPolygon* _expolygon = NULL)
- : expolygon(_expolygon), max_width(_max_width), min_width(_min_width) {};
- void build(ThickPolylines* polylines);
- void build(Polylines* polylines);
-
- private:
- class VD : public voronoi_diagram<double> {
- public:
- typedef double coord_type;
- typedef boost::polygon::point_data<coordinate_type> point_type;
- typedef boost::polygon::segment_data<coordinate_type> segment_type;
- typedef boost::polygon::rectangle_data<coordinate_type> rect_type;
- };
- VD vd;
- std::set<const VD::edge_type*> edges, valid_edges;
- std::map<const VD::edge_type*, std::pair<coordf_t,coordf_t> > thickness;
- void process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* polyline);
- bool validate_edge(const VD::edge_type* edge);
- const Line& retrieve_segment(const VD::cell_type* cell) const;
- const Point& retrieve_endpoint(const VD::cell_type* cell) const;
-};
-
// Sets the given transform by assembling the given transformations in the following order:
// 1) mirror
// 2) scale
diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp
index fa5d29692..40f3d9988 100644
--- a/src/libslic3r/Layer.cpp
+++ b/src/libslic3r/Layer.cpp
@@ -109,8 +109,10 @@ void Layer::make_perimeters()
&& config.gap_fill_speed == other_config.gap_fill_speed
&& config.overhangs == other_config.overhangs
&& config.serialize("perimeter_extrusion_width").compare(other_config.serialize("perimeter_extrusion_width")) == 0
- && config.thin_walls == other_config.thin_walls
- && config.external_perimeters_first == other_config.external_perimeters_first) {
+ && config.thin_walls == other_config.thin_walls
+ && config.thin_walls_min_width == other_config.thin_walls_min_width
+ && config.external_perimeters_first == other_config.external_perimeters_first
+ && config.perimeter_loop == other_config.perimeter_loop) {
layerms.push_back(other_layerm);
done.insert(it - m_regions.begin());
}
diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp
index 78897a2db..0f75cd39a 100644
--- a/src/libslic3r/Layer.hpp
+++ b/src/libslic3r/Layer.hpp
@@ -35,6 +35,8 @@ public:
// Unspecified fill polygons, used for overhang detection ("ensure vertical wall thickness feature")
// and for re-starting of infills.
ExPolygons fill_expolygons;
+ // Unspecified fill polygons, used for interecting when we don't want the infill/perimeter overlap
+ ExPolygons fill_no_overlap_expolygons;
// collection of surfaces for infill generation
SurfaceCollection fill_surfaces;
@@ -110,8 +112,8 @@ public:
ExPolygonCollection slices;
size_t region_count() const { return m_regions.size(); }
- const LayerRegion* get_region(int idx) const { return m_regions.at(idx); }
- LayerRegion* get_region(int idx) { return m_regions[idx]; }
+ const LayerRegion* get_region(size_t idx) const { return m_regions.at(idx); }
+ LayerRegion* get_region(size_t idx) { return m_regions[idx]; }
LayerRegion* add_region(PrintRegion* print_region);
const LayerRegionPtrs& regions() const { return m_regions; }
// Test whether whether there are any slices assigned to this layer.
diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp
index 6f70fba65..7eaae5348 100644
--- a/src/libslic3r/LayerRegion.cpp
+++ b/src/libslic3r/LayerRegion.cpp
@@ -73,6 +73,8 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
if (this->layer()->lower_layer != NULL)
// Cummulative sum of polygons over all the regions.
g.lower_slices = &this->layer()->lower_layer->slices;
+ if (this->layer()->upper_layer != NULL)
+ g.upper_slices = &this->layer()->upper_layer->slices;
g.layer_id = this->layer()->id();
g.ext_perimeter_flow = this->flow(frExternalPerimeter);
@@ -80,6 +82,8 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
g.solid_infill_flow = this->flow(frSolidInfill);
g.process();
+
+ this->fill_no_overlap_expolygons = g.fill_no_overlap;
}
//#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 3.
@@ -89,13 +93,23 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
void LayerRegion::process_external_surfaces(const Layer* lower_layer)
{
const Surfaces &surfaces = this->fill_surfaces.surfaces;
- const double margin = scale_(EXTERNAL_INFILL_MARGIN);
-
+ const bool has_infill = this->region()->config().fill_density.value > 0.;
+ coord_t margin = scale_(this->region()->config().external_infill_margin.getFloat());
+ coord_t margin_bridged = scale_(this->region()->config().bridged_infill_margin.getFloat());
+ //if no infill, reduce the margin for averythign to only the perimeter
+ if (!has_infill) {
+ if ((this->region()->config().perimeters > 0)) {
+ const coord_t perimeter_width = scale_(this->region()->config().perimeter_extrusion_width.get_abs_value(this->layer()->object()->config().layer_height.value));
+ const coord_t first_perimeter_width = scale_(this->region()->config().external_perimeter_extrusion_width.get_abs_value(this->layer()->object()->config().layer_height.value));
+ margin = first_perimeter_width + perimeter_width * (this->region()->config().perimeters.value - 1);
+ } else margin = 0;
+ margin_bridged = margin;
+ }
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
export_region_fill_surfaces_to_svg_debug("3_process_external_surfaces-initial");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
- // 1) Collect bottom and bridge surfaces, each of them grown by a fixed 3mm offset
+ // 1) Collect bottom and bridge surfaces, each of them grown by a parametrised ~3mm offset
// for better anchoring.
// Bottom surfaces, grown.
Surfaces bottom;
@@ -117,7 +131,7 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
fill_boundaries.reserve(number_polygons(surfaces));
bool has_infill = this->region()->config().fill_density.value > 0.;
for (const Surface &surface : this->fill_surfaces.surfaces) {
- if (surface.surface_type == stTop) {
+ if (surface.is_top()) {
// Collect the top surfaces, inflate them and trim them by the bottom surfaces.
// This gives the priority to bottom surfaces.
surfaces_append(top, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
@@ -128,14 +142,20 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
if (! surface.empty())
bridges.push_back(surface);
}
- bool internal_surface = surface.surface_type != stTop && ! surface.is_bottom();
if (has_infill || surface.surface_type != stInternal) {
- if (internal_surface)
+ if (!surface.is_external())
// Make a copy as the following line uses the move semantics.
internal.push_back(surface);
polygons_append(fill_boundaries, std::move(surface.expolygon));
- } else if (internal_surface)
- internal.push_back(std::move(surface));
+ } else{
+ if (!surface.is_external())
+ internal.push_back(std::move(surface));
+ //push surface as perimeter-only inside the fill_boundaries
+ if (margin_bridged > 0) {
+ ExPolygons peri_poly = diff_ex(ExPolygons() = { surface.expolygon }, offset_ex(surface.expolygon, -margin_bridged));
+ polygons_append(fill_boundaries, peri_poly);
+ }
+ }
}
}
@@ -183,8 +203,8 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
idx_island = j;
break;
}
- // Grown by 3mm.
- Polygons polys = offset(to_polygons(bridges[i].expolygon), float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS);
+ // Grown by bridged_infill_margin.
+ Polygons polys = offset(to_polygons(bridges[i].expolygon), float(margin_bridged), EXTERNAL_SURFACES_OFFSET_PARAMETERS);
if (idx_island == -1) {
printf("Bridge did not fall into the source region!\r\n");
} else {
@@ -300,7 +320,7 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
s2.clear();
}
}
- if (s1.surface_type == stTop)
+ if (s1.is_top())
// Trim the top surfaces by the bottom surfaces. This gives the priority to the bottom surfaces.
polys = diff(polys, bottom_polygons);
surfaces_append(
@@ -352,13 +372,13 @@ void LayerRegion::prepare_fill_surfaces()
// if no solid layers are requested, turn top/bottom surfaces to internal
if (this->region()->config().top_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
- if (surface->surface_type == stTop)
+ if (surface->is_top())
surface->surface_type = (this->layer()->object()->config().infill_only_where_needed) ?
stInternalVoid : stInternal;
}
if (this->region()->config().bottom_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
- if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
+ if (surface->is_bottom())
surface->surface_type = stInternal;
}
}
diff --git a/src/libslic3r/Line.cpp b/src/libslic3r/Line.cpp
index 02f1cb7c2..c66a8885d 100644
--- a/src/libslic3r/Line.cpp
+++ b/src/libslic3r/Line.cpp
@@ -115,4 +115,15 @@ Vec3d Linef3::intersect_plane(double z) const
return Vec3d(this->a(0) + v(0) * t, this->a(1) + v(1) * t, z);
}
+Point Line::point_at(double distance) const {
+ Point point;
+ double len = this->length();
+ point = this->a;
+ if (this->a.x() != this->b.x())
+ point.x() = this->a.x() + (this->b.x() - this->a.x()) * distance / len;
+ if (this->a.y() != this->b.y())
+ point.y() = this->a.y() + (this->b.y() - this->a.y()) * distance / len;
+ return point;
+}
+
}
diff --git a/src/libslic3r/Line.hpp b/src/libslic3r/Line.hpp
index 559ca946a..a1f42d111 100644
--- a/src/libslic3r/Line.hpp
+++ b/src/libslic3r/Line.hpp
@@ -46,6 +46,10 @@ public:
static double distance_to_squared(const Point &point, const Point &a, const Point &b);
static double distance_to(const Point &point, const Point &a, const Point &b) { return sqrt(distance_to_squared(point, a, b)); }
+ Point point_at(double distance) const;
+ coord_t Line::dot(Line &l2) const { return vector().dot(l2.vector()); }
+ void extend_end(double distance) { Line line = *this; line.reverse(); this->b = line.point_at(-distance); }
+ void extend_start(double distance) { this->a = this->point_at(-distance); }
Point a;
Point b;
diff --git a/src/libslic3r/MedialAxis.cpp b/src/libslic3r/MedialAxis.cpp
new file mode 100644
index 000000000..c4ddd1399
--- /dev/null
+++ b/src/libslic3r/MedialAxis.cpp
@@ -0,0 +1,1644 @@
+#include "BoundingBox.hpp"
+#include "ExPolygon.hpp"
+#include "Geometry.hpp"
+#include "Polygon.hpp"
+#include "Line.hpp"
+#include "ClipperUtils.hpp"
+#include "SVG.hpp"
+#include "polypartition.h"
+#include "poly2tri/poly2tri.h"
+#include <algorithm>
+#include <cassert>
+#include <list>
+
+namespace Slic3r {
+
+int MedialAxis::id = 0;
+
+void
+MedialAxis::build(Polylines* polylines)
+{
+ ThickPolylines tp;
+ this->build(&tp);
+ polylines->insert(polylines->end(), tp.begin(), tp.end());
+}
+
+void
+MedialAxis::polyline_from_voronoi(const Lines& voronoi_edges, ThickPolylines* polylines)
+{
+ this->lines = voronoi_edges;
+ construct_voronoi(lines.begin(), lines.end(), &this->vd);
+
+ /*
+ // DEBUG: dump all Voronoi edges
+ {
+ for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
+ if (edge->is_infinite()) continue;
+
+ ThickPolyline polyline;
+ polyline.points.push_back(Point( edge->vertex0()->x(), edge->vertex0()->y() ));
+ polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() ));
+ polylines->push_back(polyline);
+ }
+ return;
+ }
+ */
+
+ typedef const VD::vertex_type vert_t;
+ typedef const VD::edge_type edge_t;
+
+ // collect valid edges (i.e. prune those not belonging to MAT)
+ // note: this keeps twins, so it inserts twice the number of the valid edges
+ this->valid_edges.clear();
+ {
+ std::set<const VD::edge_type*> seen_edges;
+ for (VD::const_edge_iterator edge = this->vd.edges().begin(); edge != this->vd.edges().end(); ++edge) {
+ // if we only process segments representing closed loops, none if the
+ // infinite edges (if any) would be part of our MAT anyway
+ if (edge->is_secondary() || edge->is_infinite()) continue;
+
+ // don't re-validate twins
+ if (seen_edges.find(&*edge) != seen_edges.end()) continue; // TODO: is this needed?
+ seen_edges.insert(&*edge);
+ seen_edges.insert(edge->twin());
+
+ if (!this->validate_edge(&*edge)) continue;
+ this->valid_edges.insert(&*edge);
+ this->valid_edges.insert(edge->twin());
+ }
+ }
+ this->edges = this->valid_edges;
+
+ // iterate through the valid edges to build polylines
+ while (!this->edges.empty()) {
+ const edge_t* edge = *this->edges.begin();
+
+ // start a polyline
+ ThickPolyline polyline;
+ polyline.points.push_back(Point( edge->vertex0()->x(), edge->vertex0()->y() ));
+ polyline.points.push_back(Point( edge->vertex1()->x(), edge->vertex1()->y() ));
+ polyline.width.push_back(this->thickness[edge].first);
+ polyline.width.push_back(this->thickness[edge].second);
+
+ // remove this edge and its twin from the available edges
+ (void)this->edges.erase(edge);
+ (void)this->edges.erase(edge->twin());
+
+ // get next points
+ this->process_edge_neighbors(edge, &polyline);
+
+ // get previous points
+ {
+ ThickPolyline rpolyline;
+ this->process_edge_neighbors(edge->twin(), &rpolyline);
+ polyline.points.insert(polyline.points.begin(), rpolyline.points.rbegin(), rpolyline.points.rend());
+ polyline.width.insert(polyline.width.begin(), rpolyline.width.rbegin(), rpolyline.width.rend());
+ polyline.endpoints.first = rpolyline.endpoints.second;
+ }
+
+ assert(polyline.width.size() == polyline.points.size());
+
+ // prevent loop endpoints from being extended
+ if (polyline.first_point().coincides_with(polyline.last_point())) {
+ polyline.endpoints.first = false;
+ polyline.endpoints.second = false;
+ }
+
+ // append polyline to result
+ polylines->push_back(polyline);
+ }
+
+ #ifdef SLIC3R_DEBUG
+ {
+ static int iRun = 0;
+ dump_voronoi_to_svg(this->lines, this->vd, polylines, debug_out_path("MedialAxis-%d.svg", iRun ++).c_str());
+ printf("Thick lines: ");
+ for (ThickPolylines::const_iterator it = polylines->begin(); it != polylines->end(); ++ it) {
+ ThickLines lines = it->thicklines();
+ for (ThickLines::const_iterator it2 = lines.begin(); it2 != lines.end(); ++ it2) {
+ printf("%f,%f ", it2->a_width, it2->b_width);
+ }
+ }
+ printf("\n");
+ }
+ #endif /* SLIC3R_DEBUG */
+}
+
+void
+MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* polyline)
+{
+ while (true) {
+ // Since rot_next() works on the edge starting point but we want
+ // to find neighbors on the ending point, we just swap edge with
+ // its twin.
+ const VD::edge_type* twin = edge->twin();
+
+ // count neighbors for this edge
+ std::vector<const VD::edge_type*> neighbors;
+ for (const VD::edge_type* neighbor = twin->rot_next(); neighbor != twin;
+ neighbor = neighbor->rot_next()) {
+ if (this->valid_edges.count(neighbor) > 0) neighbors.push_back(neighbor);
+ }
+
+ // if we have a single neighbor then we can continue recursively
+ if (neighbors.size() == 1) {
+ const VD::edge_type* neighbor = neighbors.front();
+
+ // break if this is a closed loop
+ if (this->edges.count(neighbor) == 0) return;
+
+ Point new_point(neighbor->vertex1()->x(), neighbor->vertex1()->y());
+ polyline->points.push_back(new_point);
+ polyline->width.push_back(this->thickness[neighbor].second);
+
+ (void)this->edges.erase(neighbor);
+ (void)this->edges.erase(neighbor->twin());
+ edge = neighbor;
+ } else if (neighbors.size() == 0) {
+ polyline->endpoints.second = true;
+ return;
+ } else {
+ // T-shaped or star-shaped joint
+ return;
+ }
+ }
+}
+
+bool
+MedialAxis::validate_edge(const VD::edge_type* edge)
+{
+ // prevent overflows and detect almost-infinite edges
+ if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
+ std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
+ std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
+ std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
+ return false;
+
+ // construct the line representing this edge of the Voronoi diagram
+ const Line line(
+ Point( edge->vertex0()->x(), edge->vertex0()->y() ),
+ Point( edge->vertex1()->x(), edge->vertex1()->y() )
+ );
+
+ // discard edge if it lies outside the supplied shape
+ // this could maybe be optimized (checking inclusion of the endpoints
+ // might give false positives as they might belong to the contour itself)
+ if (line.a.coincides_with(line.b)) {
+ // in this case, contains(line) returns a false positive
+ if (!this->expolygon.contains(line.a)) return false;
+ } else {
+ if (!this->expolygon.contains(line)) return false;
+ }
+
+ // retrieve the original line segments which generated the edge we're checking
+ const VD::cell_type* cell_l = edge->cell();
+ const VD::cell_type* cell_r = edge->twin()->cell();
+ const Line &segment_l = this->retrieve_segment(cell_l);
+ const Line &segment_r = this->retrieve_segment(cell_r);
+
+
+ //SVG svg("edge.svg");
+ //svg.draw(this->expolygon.expolygon);
+ //svg.draw(line);
+ //svg.draw(segment_l, "red");
+ //svg.draw(segment_r, "blue");
+ //svg.Close();
+ //
+
+ /* Calculate thickness of the cross-section at both the endpoints of this edge.
+ Our Voronoi edge is part of a CCW sequence going around its Voronoi cell
+ located on the left side. (segment_l).
+ This edge's twin goes around segment_r. Thus, segment_r is
+ oriented in the same direction as our main edge, and segment_l is oriented
+ in the same direction as our twin edge.
+ We used to only consider the (half-)distances to segment_r, and that works
+ whenever segment_l and segment_r are almost specular and facing. However,
+ at curves they are staggered and they only face for a very little length
+ (our very short edge represents such visibility).
+ Both w0 and w1 can be calculated either towards cell_l or cell_r with equal
+ results by Voronoi definition.
+ When cell_l or cell_r don't refer to the segment but only to an endpoint, we
+ calculate the distance to that endpoint instead. */
+
+ coordf_t w0 = cell_r->contains_segment()
+ ? line.a.distance_to(segment_r)*2
+ : line.a.distance_to(this->retrieve_endpoint(cell_r))*2;
+
+ coordf_t w1 = cell_l->contains_segment()
+ ? line.b.distance_to(segment_l)*2
+ : line.b.distance_to(this->retrieve_endpoint(cell_l))*2;
+
+ //don't remove the line that goes to the intersection of the contour
+ // we use them to create nicer thin wall lines
+ //if (cell_l->contains_segment() && cell_r->contains_segment()) {
+ // // calculate the relative angle between the two boundary segments
+ // double angle = fabs(segment_r.orientation() - segment_l.orientation());
+ // if (angle > PI) angle = 2*PI - angle;
+ // assert(angle >= 0 && angle <= PI);
+ //
+ // // fabs(angle) ranges from 0 (collinear, same direction) to PI (collinear, opposite direction)
+ // // we're interested only in segments close to the second case (facing segments)
+ // // so we allow some tolerance.
+ // // this filter ensures that we're dealing with a narrow/oriented area (longer than thick)
+ // // we don't run it on edges not generated by two segments (thus generated by one segment
+ // // and the endpoint of another segment), since their orientation would not be meaningful
+ // if (PI - angle > PI/8) {
+ // // angle is not narrow enough
+ //
+ // // only apply this filter to segments that are not too short otherwise their
+ // // angle could possibly be not meaningful
+ // if (w0 < SCALED_EPSILON || w1 < SCALED_EPSILON || line.length() >= this->min_width)
+ // return false;
+ // }
+ //} else {
+ // if (w0 < SCALED_EPSILON || w1 < SCALED_EPSILON)
+ // return false;
+ //}
+
+ // don't do that before we try to fusion them
+ //if (w0 < this->min_width && w1 < this->min_width)
+ // return false;
+ //
+
+ //shouldn't occur if perimeter_generator is well made
+ if (w0 > this->max_width && w1 > this->max_width)
+ return false;
+
+ this->thickness[edge] = std::make_pair(w0, w1);
+ this->thickness[edge->twin()] = std::make_pair(w1, w0);
+
+ return true;
+}
+
+const Line&
+MedialAxis::retrieve_segment(const VD::cell_type* cell) const
+{
+ return lines[cell->source_index()];
+}
+
+const Point&
+MedialAxis::retrieve_endpoint(const VD::cell_type* cell) const
+{
+ const Line& line = this->retrieve_segment(cell);
+ if (cell->source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) {
+ return line.a;
+ } else {
+ return line.b;
+ }
+}
+
+
+/// remove point that are at SCALED_EPSILON * 2 distance.
+void
+remove_point_too_near(ThickPolyline* to_reduce)
+{
+ const coord_t smallest = SCALED_EPSILON * 2;
+ size_t id = 1;
+ while (id < to_reduce->points.size() - 1) {
+ size_t newdist = min(to_reduce->points[id].distance_to(to_reduce->points[id - 1])
+ , to_reduce->points[id].distance_to(to_reduce->points[id + 1]));
+ if (newdist < smallest) {
+ to_reduce->points.erase(to_reduce->points.begin() + id);
+ to_reduce->width.erase(to_reduce->width.begin() + id);
+ newdist = to_reduce->points[id].distance_to(to_reduce->points[id - 1]);
+ //if you removed a point, it check if the next one isn't too near from the previous one.
+ // if not, it bypass it.
+ if (newdist > smallest) {
+ ++id;
+ }
+ }
+ //go to next one
+ else ++id;
+ }
+}
+
+/// add points from pattern to to_modify at the same % of the length
+/// so not add if an other point is present at the correct position
+void
+add_point_same_percent(ThickPolyline* pattern, ThickPolyline* to_modify)
+{
+ const double to_modify_length = to_modify->length();
+ const double percent_epsilon = SCALED_EPSILON / to_modify_length;
+ const double pattern_length = pattern->length();
+
+ double percent_length = 0;
+ for (size_t idx_point = 1; idx_point < pattern->points.size() - 1; ++idx_point) {
+ percent_length += pattern->points[idx_point-1].distance_to(pattern->points[idx_point]) / pattern_length;
+ //find position
+ size_t idx_other = 1;
+ double percent_length_other_before = 0;
+ double percent_length_other = 0;
+ while (idx_other < to_modify->points.size()) {
+ percent_length_other_before = percent_length_other;
+ percent_length_other += to_modify->points[idx_other-1].distance_to(to_modify->points[idx_other])
+ / to_modify_length;
+ if (percent_length_other > percent_length - percent_epsilon) {
+ //if higher (we have gone over it)
+ break;
+ }
+ ++idx_other;
+ }
+ if (percent_length_other > percent_length + percent_epsilon) {
+ //insert a new point before the position
+ double percent_dist = (percent_length - percent_length_other_before) / (percent_length_other - percent_length_other_before);
+ coordf_t new_width = to_modify->width[idx_other - 1] * (1 - percent_dist);
+ new_width += to_modify->width[idx_other] * (percent_dist);
+ Point new_point;
+ new_point.x() = (coord_t)((double)(to_modify->points[idx_other - 1].x()) * (1 - percent_dist));
+ new_point.x() += (coord_t)((double)(to_modify->points[idx_other].x()) * (percent_dist));
+ new_point.y() = (coord_t)((double)(to_modify->points[idx_other - 1].y()) * (1 - percent_dist));
+ new_point.y() += (coord_t)((double)(to_modify->points[idx_other].y()) * (percent_dist));
+ to_modify->width.insert(to_modify->width.begin() + idx_other, new_width);
+ to_modify->points.insert(to_modify->points.begin() + idx_other, new_point);
+ }
+ }
+}
+
+/// find the nearest angle in the contour (or 2 nearest if it's difficult to choose)
+/// return 1 for an angle of 90° and 0 for an angle of 0° or 180°
+/// find the nearest angle in the contour (or 2 nearest if it's difficult to choose)
+/// return 1 for an angle of 90° and 0 for an angle of 0° or 180°
+double
+get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t min_dist_between_point) {
+ double nearest_dist = point.distance_to(contour.contour.points.front());
+ Point point_nearest = contour.contour.points.front();
+ size_t id_nearest = 0;
+ double near_dist = nearest_dist;
+ Point point_near = point_nearest;
+ size_t id_near = 0;
+ for (size_t id_point = 1; id_point < contour.contour.points.size(); ++id_point) {
+ if (nearest_dist > point.distance_to(contour.contour.points[id_point])) {
+ //update point_near
+ id_near = id_nearest;
+ point_near = point_nearest;
+ near_dist = nearest_dist;
+ //update nearest
+ nearest_dist = point.distance_to(contour.contour.points[id_point]);
+ point_nearest = contour.contour.points[id_point];
+ id_nearest = id_point;
+ }
+ }
+ double angle = 0;
+ size_t id_before = id_nearest == 0 ? contour.contour.points.size() - 1 : id_nearest - 1;
+ Point point_before = id_nearest == 0 ? contour.contour.points.back() : contour.contour.points[id_nearest - 1];
+ //Search one point far enough to be relevant
+ while (point_nearest.distance_to(point_before) < min_dist_between_point) {
+ point_before = id_before == 0 ? contour.contour.points.back() : contour.contour.points[id_before - 1];
+ id_before = id_before == 0 ? contour.contour.points.size() - 1 : id_before - 1;
+ //don't loop
+ if (id_before == id_nearest) {
+ id_before = id_nearest == 0 ? contour.contour.points.size() - 1 : id_nearest - 1;
+ point_before = id_nearest == 0 ? contour.contour.points.back() : contour.contour.points[id_nearest - 1];
+ break;
+ }
+ }
+ size_t id_after = id_nearest == contour.contour.points.size() - 1 ? 0 : id_nearest + 1;
+ Point point_after = id_nearest == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_nearest + 1];
+ //Search one point far enough to be relevant
+ while (point_nearest.distance_to(point_after) < min_dist_between_point) {
+ point_after = id_after == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_after + 1];
+ id_after = id_after == contour.contour.points.size() - 1 ? 0 : id_after + 1;
+ //don't loop
+ if (id_after == id_nearest) {
+ id_after = id_nearest == contour.contour.points.size() - 1 ? 0 : id_nearest + 1;
+ point_after = id_nearest == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_nearest + 1];
+ break;
+ }
+ }
+ //compute angle
+ angle = point_nearest.ccw_angle(point_before, point_after);
+ if (angle >= PI) angle = 2 * PI - angle; // smaller angle
+ //compute the diff from 90°
+ angle = abs(angle - PI / 2);
+ if (point_near.coincides_with(point_nearest) && max(nearest_dist, near_dist) + SCALED_EPSILON < point_nearest.distance_to(point_near)) {
+ //not only nearest
+ Point point_before = id_near == 0 ? contour.contour.points.back() : contour.contour.points[id_near - 1];
+ Point point_after = id_near == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_near + 1];
+ double angle2 = min(point_nearest.ccw_angle(point_before, point_after), point_nearest.ccw_angle(point_after, point_before));
+ angle2 = abs(angle - PI / 2);
+ angle = (angle + angle2) / 2;
+ }
+
+ return 1 - (angle / (PI / 2));
+}
+
+double
+dot(Line l1, Line l2)
+{
+ Vec2d v_1(l1.b.x() - l1.a.x(), l1.b.y() - l1.a.y());
+ v_1.normalize();
+ Vec2d v_2(l2.b.x() - l2.a.x(), l2.b.y() - l2.a.y());
+ v_2.normalize();
+ return v_1.x()*v_2.x() + v_1.y()*v_2.y();
+}
+
+void
+MedialAxis::fusion_curve(ThickPolylines &pp)
+{
+ //fusion Y with only 1 '0' value => the "0" branch "pull" the cross-point
+ bool changes = false;
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ // only consider 2-point polyline with endpoint
+ if (polyline.points.size() != 2) continue;
+ if (polyline.endpoints.first) polyline.reverse();
+ else if (!polyline.endpoints.second) continue;
+ if (polyline.width.back() > EPSILON) continue;
+
+ //check my length is small
+ coord_t length = (coord_t)polyline.length();
+ if (length > max_width) continue;
+
+ size_t closest_point_idx = this->expolygon.contour.closest_point_index(polyline.points.back());
+
+ //check the 0-wodth point is on the contour.
+ if (closest_point_idx == (size_t)-1) continue;
+
+ size_t prev_idx = closest_point_idx == 0 ? this->expolygon.contour.points.size() - 1 : closest_point_idx - 1;
+ size_t next_idx = closest_point_idx == this->expolygon.contour.points.size() - 1 ? 0 : closest_point_idx + 1;
+ double mindot = 1;
+ mindot = min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]),
+ (Line(this->expolygon.contour.points[closest_point_idx], this->expolygon.contour.points[prev_idx])))));
+ mindot = min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]),
+ (Line(this->expolygon.contour.points[closest_point_idx], this->expolygon.contour.points[next_idx])))));
+
+ //compute angle
+ double coeff_contour_angle = this->expolygon.contour.points[closest_point_idx].ccw_angle(this->expolygon.contour.points[prev_idx], this->expolygon.contour.points[next_idx]);
+ if (coeff_contour_angle >= PI) coeff_contour_angle = 2 * PI - coeff_contour_angle; // smaller angle
+ //compute the diff from 90°
+ coeff_contour_angle = abs(coeff_contour_angle - PI / 2);
+
+
+ // look if other end is a cross point with almost 90° angle
+ double sum_dot = 0;
+ double min_dot = 0;
+ // look if other end is a cross point with multiple other branch
+ vector<size_t> crosspoint;
+ for (size_t j = 0; j < pp.size(); ++j) {
+ if (j == i) continue;
+ ThickPolyline& other = pp[j];
+ if (polyline.first_point().coincides_with(other.last_point())) {
+ other.reverse();
+ crosspoint.push_back(j);
+ double dot_temp = dot(Line(polyline.points[0], polyline.points[1]), (Line(other.points[0], other.points[1])));
+ min_dot = min(min_dot, abs(dot_temp));
+ sum_dot += dot_temp;
+ } else if (polyline.first_point().coincides_with(other.first_point())) {
+ crosspoint.push_back(j);
+ double dot_temp = dot(Line(polyline.points[0], polyline.points[1]), (Line(other.points[0], other.points[1])));
+ min_dot = min(min_dot, abs(dot_temp));
+ sum_dot += dot_temp;
+ }
+ }
+ //only consider very shallow angle for contour
+ if (mindot > 0.15 &&
+ (1 - (coeff_contour_angle / (PI / 2))) > 0.2) continue;
+
+ //check if it's a line that we can pull
+ if (crosspoint.size() != 2) continue;
+ if (sum_dot > 0.2) continue;
+ if (min_dot > 0.5) continue;
+
+ //don't pull, it distords the line if there are too many points.
+ //// pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve)
+ //coord_t length_pull = polyline.length();
+ //length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, polyline.length() / 2));
+
+ ////compute dir
+ //Vectorf pull_direction(polyline.points[1].x() - polyline.points[0].x(), polyline.points[1].y() - polyline.points[0].y());
+ //pull_direction = normalize(pull_direction);
+ //pull_direction.x() *= length_pull;
+ //pull_direction.y() *= length_pull;
+
+ ////pull the points
+ //Point &p1 = pp[crosspoint[0]].points[0];
+ //p1.x() = p1.x() + (coord_t)pull_direction.x();
+ //p1.y() = p1.y() + (coord_t)pull_direction.y();
+
+ //Point &p2 = pp[crosspoint[1]].points[0];
+ //p2.x() = p2.x() + (coord_t)pull_direction.x();
+ //p2.y() = p2.y() + (coord_t)pull_direction.y();
+
+ //delete the now unused polyline
+ pp.erase(pp.begin() + i);
+ --i;
+ changes = true;
+ }
+ if (changes) {
+ concatThickPolylines(pp);
+ ///reorder, in case of change
+ std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { return a.length() < b.length(); });
+ }
+}
+
+void
+MedialAxis::fusion_corners(ThickPolylines &pp)
+{
+
+ //fusion Y with only 1 '0' value => the "0" branch "pull" the cross-point
+ bool changes = false;
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ // only consider polyline with 0-end
+ if (polyline.points.size() != 2) continue;
+ if (polyline.endpoints.first) polyline.reverse();
+ else if (!polyline.endpoints.second) continue;
+ if (polyline.width.back() > 0) continue;
+
+ //check my length is small
+ coord_t length = polyline.length();
+ if (length > max_width) continue;
+
+ // look if other end is a cross point with multiple other branch
+ vector<size_t> crosspoint;
+ for (size_t j = 0; j < pp.size(); ++j) {
+ if (j == i) continue;
+ ThickPolyline& other = pp[j];
+ if (polyline.first_point().coincides_with(other.last_point())) {
+ other.reverse();
+ crosspoint.push_back(j);
+ } else if (polyline.first_point().coincides_with(other.first_point())) {
+ crosspoint.push_back(j);
+ }
+ }
+ //check if it's a line that we can pull
+ if (crosspoint.size() != 2) continue;
+
+ // check if i am at the external side of a curve
+ double angle1 = polyline.points[0].ccw_angle(polyline.points[1], pp[crosspoint[0]].points[1]);
+ if (angle1 >= PI) angle1 = 2 * PI - angle1; // smaller angle
+ double angle2 = polyline.points[0].ccw_angle(polyline.points[1], pp[crosspoint[1]].points[1]);
+ if (angle2 >= PI) angle2 = 2 * PI - angle2; // smaller angle
+ if (angle1 + angle2 < PI) continue;
+
+ //check if is smaller or the other ones are not endpoits
+ if (pp[crosspoint[0]].endpoints.second && length > pp[crosspoint[0]].length()) continue;
+ if (pp[crosspoint[1]].endpoints.second && length > pp[crosspoint[1]].length()) continue;
+
+ //FIXME: also pull (a bit less) points that are near to this one.
+ // if true, pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve)
+ coord_t length_pull = polyline.length();
+ length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
+
+ //compute dir
+ Vec2d pull_direction(polyline.points[1].x() - polyline.points[0].x(), polyline.points[1].y() - polyline.points[0].y());
+ pull_direction.normalize();
+ pull_direction.x() *= length_pull;
+ pull_direction.y() *= length_pull;
+
+ //pull the points
+ Point &p1 = pp[crosspoint[0]].points[0];
+ p1.x() = p1.x() + pull_direction.x();
+ p1.y() = p1.y() + pull_direction.y();
+
+ Point &p2 = pp[crosspoint[1]].points[0];
+ p2.x() = p2.x() + pull_direction.x();
+ p2.y() = p2.y() + pull_direction.y();
+
+ //delete the now unused polyline
+ pp.erase(pp.begin() + i);
+ --i;
+ changes = true;
+ }
+ if (changes) {
+ concatThickPolylines(pp);
+ ///reorder, in case of change
+ std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { return a.length() < b.length(); });
+ }
+}
+
+
+void
+MedialAxis::extends_line_both_side(ThickPolylines& pp) {
+ const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION);
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ this->extends_line(polyline, anchors, this->min_width);
+ polyline.reverse();
+ this->extends_line(polyline, anchors, this->min_width);
+ }
+}
+
+void
+MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width)
+{
+ // extend initial and final segments of each polyline if they're actual endpoints
+ // We assign new endpoints to temporary variables because in case of a single-line
+ // polyline, after we extend the start point it will be caught by the intersection()
+ // call, so we keep the inner point until we perform the second intersection() as well
+ if (polyline.endpoints.second && !bounds.has_boundary_point(polyline.points.back())) {
+ size_t first_idx = polyline.points.size() - 2;
+ Line line(*(polyline.points.begin() + first_idx), polyline.points.back());
+ while (line.length() < SCALED_RESOLUTION && first_idx>0) {
+ first_idx--;
+ line.a = *(polyline.points.begin() + first_idx);
+ }
+ // prevent the line from touching on the other side, otherwise intersection() might return that solution
+ if (polyline.points.size() == 2 && this->expolygon.contains(line.midpoint())) line.a = line.midpoint();
+
+ line.extend_end(max_width);
+ Point new_back;
+ if (this->expolygon.contour.has_boundary_point(polyline.points.back())) {
+ new_back = polyline.points.back();
+ } else {
+ bool finded = this->expolygon.contour.first_intersection(line, &new_back);
+ //verify also for holes.
+ Point new_back_temp;
+ for (Polygon hole : this->expolygon.holes) {
+ if (hole.first_intersection(line, &new_back_temp)) {
+ if (!finded || line.a.distance_to(new_back_temp) < line.a.distance_to(new_back)) {
+ finded = true;
+ new_back = new_back_temp;
+ }
+ }
+ }
+ // safety check if no intersection
+ if (!finded) {
+ if (!this->expolygon.contains(line.b)) {
+ //it's outside!!!
+ if (!this->expolygon.contains(line.a)) {
+ std::cout << "Error, a line is formed that start outside a polygon, end outside of it and don't cross it!\n";
+ } else {
+ std::cout << "Error, a line is formed that start in a polygon, end outside of it and don't cross it!\n";
+ }
+ }
+ new_back = line.b;
+ }
+ polyline.points.push_back(new_back);
+ polyline.width.push_back(polyline.width.back());
+ }
+ Point new_bound;
+ bool finded = bounds.contour.first_intersection(line, &new_bound);
+ //verify also for holes.
+ Point new_bound_temp;
+ for (Polygon hole : bounds.holes) {
+ if (hole.first_intersection(line, &new_bound_temp)) {
+ if (!finded || line.a.distance_to(new_bound_temp) < line.a.distance_to(new_bound)) {
+ finded = true;
+ new_bound = new_bound_temp;
+ }
+ }
+ }
+ // safety check if no intersection
+ if (!finded) {
+ if (line.b.coincides_with_epsilon(polyline.points.back())) {
+ return;
+ }
+ //check if we don't over-shoot inside us
+ bool is_in_anchor = false;
+ for (const ExPolygon& a : anchors) {
+ if (a.contains(line.b)) {
+ is_in_anchor = true;
+ break;
+ }
+ }
+ if (!is_in_anchor) std::cout << "not in anchor:\n";
+ if (!is_in_anchor) return;
+ new_bound = line.b;
+ }
+ /* if (new_bound.coincides_with_epsilon(new_back)) {
+ return;
+ }*/
+ // find anchor
+ Point best_anchor;
+ double shortest_dist = max_width;
+ for (const ExPolygon& a : anchors) {
+ Point p_maybe_inside = a.contour.centroid();
+ double test_dist = new_bound.distance_to(p_maybe_inside) + new_back.distance_to(p_maybe_inside);
+ //if (test_dist < max_width / 2 && (test_dist < shortest_dist || shortest_dist < 0)) {
+ double angle_test = new_back.ccw_angle(p_maybe_inside, line.a);
+ if (angle_test > PI) angle_test = 2 * PI - angle_test;
+ if (test_dist < max_width && test_dist<shortest_dist && abs(angle_test) > PI / 2) {
+ shortest_dist = test_dist;
+ best_anchor = p_maybe_inside;
+ }
+ }
+ if (best_anchor.x() != 0 && best_anchor.y() != 0) {
+ Point p_obj = best_anchor + new_bound;
+ p_obj.x() /= 2;
+ p_obj.y() /= 2;
+ Line l2 = Line(new_back, p_obj);
+ l2.extend_end(max_width);
+ (void)bounds.contour.first_intersection(l2, &new_bound);
+ }
+ if (new_bound.coincides_with_epsilon(new_back)) {
+ return;
+ }
+ polyline.points.push_back(new_bound);
+ //polyline.width.push_back(join_width);
+ //it thickens the line a bit too early, imo
+ polyline.width.push_back(polyline.width.back());
+ }
+}
+
+void
+MedialAxis::main_fusion(ThickPolylines& pp)
+{
+ //int idf = 0;
+
+ bool changes = true;
+ map<Point, double> coeff_angle_cache;
+ while (changes) {
+ concatThickPolylines(pp);
+ //reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length
+ std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) {
+ bool ahas0 = a.width.front() == 0 || a.width.back() == 0;
+ bool bhas0 = b.width.front() == 0 || b.width.back() == 0;
+ if (ahas0 && !bhas0) return true;
+ if (!ahas0 && bhas0) return false;
+ return a.length() < b.length();
+ });
+ changes = false;
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+
+ //simple check to see if i can be fusionned
+ if (!polyline.endpoints.first && !polyline.endpoints.second) continue;
+
+
+ ThickPolyline* best_candidate = nullptr;
+ float best_dot = -1;
+ size_t best_idx = 0;
+ double dot_poly_branch = 0;
+ double dot_candidate_branch = 0;
+
+ // find another polyline starting here
+ for (size_t j = i + 1; j < pp.size(); ++j) {
+ ThickPolyline& other = pp[j];
+ if (polyline.last_point().coincides_with(other.last_point())) {
+ polyline.reverse();
+ other.reverse();
+ } else if (polyline.first_point().coincides_with(other.last_point())) {
+ other.reverse();
+ } else if (polyline.first_point().coincides_with(other.first_point())) {
+ } else if (polyline.last_point().coincides_with(other.first_point())) {
+ polyline.reverse();
+ } else {
+ continue;
+ }
+ //std::cout << " try : " << i << ":" << j << " : " <<
+ // (polyline.points.size() < 2 && other.points.size() < 2) <<
+ // (!polyline.endpoints.second || !other.endpoints.second) <<
+ // ((polyline.points.back().distance_to(other.points.back())
+ // + (polyline.width.back() + other.width.back()) / 4)
+ // > max_width*1.05) <<
+ // (abs(polyline.length() - other.length()) > max_width) << "\n";
+
+ //// mergeable tests
+ if (polyline.points.size() < 2 && other.points.size() < 2) continue;
+ if (!polyline.endpoints.second || !other.endpoints.second) continue;
+ // test if the new width will not be too big if a fusion occur
+ //note that this isn't the real calcul. It's just to avoid merging lines too far apart.
+ if (
+ ((polyline.points.back().distance_to(other.points.back())
+ + (polyline.width.back() + other.width.back()) / 4)
+ > max_width*1.05))
+ continue;
+ // test if the lines are not too different in length.
+ if (abs(polyline.length() - other.length()) > max_width) continue;
+
+
+ //test if we don't merge with something too different and without any relevance.
+ double coeffSizePolyI = 1;
+ if (polyline.width.back() == 0) {
+ coeffSizePolyI = 0.1 + 0.9*get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
+ }
+ double coeffSizeOtherJ = 1;
+ if (other.width.back() == 0) {
+ coeffSizeOtherJ = 0.1 + 0.9*get_coeff_from_angle_countour(other.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
+ }
+ //std::cout << " try2 : " << i << ":" << j << " : "
+ // << (abs(polyline.length()*coeffSizePolyI - other.length()*coeffSizeOtherJ) > max_width / 2)
+ // << (abs(polyline.length()*coeffSizePolyI - other.length()*coeffSizeOtherJ) > max_width)
+ // << "\n";
+ if (abs(polyline.length()*coeffSizePolyI - other.length()*coeffSizeOtherJ) > max_width / 2) continue;
+
+
+ //compute angle to see if it's better than previous ones (straighter = better).
+ //we need to add how strait we are from our main.
+ float test_dot = dot(polyline.lines().front(), other.lines().front());
+
+ // Get the branch/line in wich we may merge, if possible
+ // with that, we can decide what is important, and how we can merge that.
+ // angle_poly - angle_candi =90° => one is useless
+ // both angle are equal => both are useful with same strength
+ // ex: Y => | both are useful to crete a nice line
+ // ex2: TTTTT => ----- these 90° useless lines should be discarded
+ bool find_main_branch = false;
+ size_t biggest_main_branch_id = 0;
+ coord_t biggest_main_branch_length = 0;
+ for (size_t k = 0; k < pp.size(); ++k) {
+ //std::cout << "try to find main : " << k << " ? " << i << " " << j << " ";
+ if (k == i || k == j) continue;
+ ThickPolyline& main = pp[k];
+ if (polyline.first_point().coincides_with(main.last_point())) {
+ main.reverse();
+ if (!main.endpoints.second)
+ find_main_branch = true;
+ else if (biggest_main_branch_length < main.length()) {
+ biggest_main_branch_id = k;
+ biggest_main_branch_length = main.length();
+ }
+ } else if (polyline.first_point().coincides_with(main.first_point())) {
+ if (!main.endpoints.second)
+ find_main_branch = true;
+ else if (biggest_main_branch_length < main.length()) {
+ biggest_main_branch_id = k;
+ biggest_main_branch_length = main.length();
+ }
+ }
+ if (find_main_branch) {
+ //use this variable to store the good index and break to compute it
+ biggest_main_branch_id = k;
+ break;
+ }
+ }
+ if (!find_main_branch && biggest_main_branch_length == 0) {
+ // nothing -> it's impossible!
+ dot_poly_branch = 0.707;
+ dot_candidate_branch = 0.707;
+ //std::cout << "no main branch... impossible!!\n";
+ } else if (!find_main_branch && (
+ (pp[biggest_main_branch_id].length() < polyline.length() && (polyline.width.back() != 0 || pp[biggest_main_branch_id].width.back() ==0))
+ || (pp[biggest_main_branch_id].length() < other.length() && (other.width.back() != 0 || pp[biggest_main_branch_id].width.back() == 0)))) {
+ //the main branch should have no endpoint or be bigger!
+ //here, it have an endpoint, and is not the biggest -> bad!
+ continue;
+ } else {
+ //compute the dot (biggest_main_branch_id)
+ dot_poly_branch = -dot(Line(polyline.points[0], polyline.points[1]), Line(pp[biggest_main_branch_id].points[0], pp[biggest_main_branch_id].points[1]));
+ dot_candidate_branch = -dot(Line(other.points[0], other.points[1]), Line(pp[biggest_main_branch_id].points[0], pp[biggest_main_branch_id].points[1]));
+ if (dot_poly_branch < 0) dot_poly_branch = 0;
+ if (dot_candidate_branch < 0) dot_candidate_branch = 0;
+ if (pp[biggest_main_branch_id].width.back()>0)
+ test_dot += 2 * dot_poly_branch ;
+ }
+ //test if it's useful to merge or not
+ //ie, don't merge 'T' but ok for 'Y', merge only lines of not disproportionate different length (ratio max: 4) (or they are both with 0-width end)
+ if (dot_poly_branch < 0.1 || dot_candidate_branch < 0.1 ||
+ (
+ ((polyline.length()>other.length() ? polyline.length() / other.length() : other.length() / polyline.length()) > 4)
+ && !(polyline.width.back() == 0 && other.width.back()==0)
+ ) ){
+ continue;
+ }
+ if (test_dot > best_dot) {
+ best_candidate = &other;
+ best_idx = j;
+ best_dot = test_dot;
+ }
+ }
+ if (best_candidate != nullptr) {
+ //idf++;
+ //std::cout << " == fusion " << id <<" : "<< idf << " ==\n";
+ // delete very near points
+ remove_point_too_near(&polyline);
+ remove_point_too_near(best_candidate);
+
+ // add point at the same pos than the other line to have a nicer fusion
+ add_point_same_percent(&polyline, best_candidate);
+ add_point_same_percent(best_candidate, &polyline);
+
+ //get the angle of the nearest points of the contour to see : _| (good) \_ (average) __(bad)
+ //sqrt because the result are nicer this way: don't over-penalize /_ angles
+ //TODO: try if we can achieve a better result if we use a different algo if the angle is <90°
+ const double coeff_angle_poly = (coeff_angle_cache.find(polyline.points.back()) != coeff_angle_cache.end())
+ ? coeff_angle_cache[polyline.points.back()]
+ : (get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2))));
+ const double coeff_angle_candi = (coeff_angle_cache.find(best_candidate->points.back()) != coeff_angle_cache.end())
+ ? coeff_angle_cache[best_candidate->points.back()]
+ : (get_coeff_from_angle_countour(best_candidate->points.back(), this->expolygon, min(min_width, (coord_t)(best_candidate->length() / 2))));
+
+ //this will encourage to follow the curve, a little, because it's shorter near the center
+ //without that, it tends to go to the outter rim.
+ //std::cout << " max(polyline.length(), best_candidate->length())=" << max(polyline.length(), best_candidate->length())
+ // << ", polyline.length()=" << polyline.length()
+ // << ", best_candidate->length()=" << best_candidate->length()
+ // << ", polyline.length() / max=" << (polyline.length() / max(polyline.length(), best_candidate->length()))
+ // << ", best_candidate->length() / max=" << (best_candidate->length() / max(polyline.length(), best_candidate->length()))
+ // << "\n";
+ double weight_poly = 2 - (polyline.length() / max(polyline.length(), best_candidate->length()));
+ double weight_candi = 2 - (best_candidate->length() / max(polyline.length(), best_candidate->length()));
+ weight_poly *= coeff_angle_poly;
+ weight_candi *= coeff_angle_candi;
+ const double coeff_poly = (dot_poly_branch * weight_poly) / (dot_poly_branch * weight_poly + dot_candidate_branch * weight_candi);
+ const double coeff_candi = 1.0 - coeff_poly;
+ //std::cout << "coeff_angle_poly=" << coeff_angle_poly
+ // << ", coeff_angle_candi=" << coeff_angle_candi
+ // << ", weight_poly=" << (2 - (polyline.length() / max(polyline.length(), best_candidate->length())))
+ // << ", weight_candi=" << (2 - (best_candidate->length() / max(polyline.length(), best_candidate->length())))
+ // << ", sumpoly=" << weight_poly
+ // << ", sumcandi=" << weight_candi
+ // << ", dot_poly_branch=" << dot_poly_branch
+ // << ", dot_candidate_branch=" << dot_candidate_branch
+ // << ", coeff_poly=" << coeff_poly
+ // << ", coeff_candi=" << coeff_candi
+ // << "\n";
+ //iterate the points
+ // as voronoi should create symetric thing, we can iterate synchonously
+ size_t idx_point = 1;
+ while (idx_point < min(polyline.points.size(), best_candidate->points.size())) {
+ //fusion
+ polyline.points[idx_point].x() = polyline.points[idx_point].x() * coeff_poly + best_candidate->points[idx_point].x() * coeff_candi;
+ polyline.points[idx_point].y() = polyline.points[idx_point].y() * coeff_poly + best_candidate->points[idx_point].y() * coeff_candi;
+
+ // The width decrease with distance from the centerline.
+ // This formula is what works the best, even if it's not perfect (created empirically). 0->3% error on a gap fill on some tests.
+ //If someone find an other formula based on the properties of the voronoi algorithm used here, and it works better, please use it.
+ //or maybe just use the distance to nearest edge in bounds...
+ double value_from_current_width = 0.5*polyline.width[idx_point] * dot_poly_branch / max(dot_poly_branch, dot_candidate_branch);
+ value_from_current_width += 0.5*best_candidate->width[idx_point] * dot_candidate_branch / max(dot_poly_branch, dot_candidate_branch);
+ double value_from_dist = 2 * polyline.points[idx_point].distance_to(best_candidate->points[idx_point]);
+ value_from_dist *= sqrt(min(dot_poly_branch, dot_candidate_branch) / max(dot_poly_branch, dot_candidate_branch));
+ polyline.width[idx_point] = value_from_current_width + value_from_dist;
+ //std::cout << "width:" << polyline.width[idx_point] << " = " << value_from_current_width << " + " << value_from_dist
+ // << " (<" << max_width << " && " << (bounds.contour.closest_point(polyline.points[idx_point])->distance_to(polyline.points[idx_point]) * 2.1)<<")\n";
+ //failsafes
+ if (polyline.width[idx_point] > max_width)
+ polyline.width[idx_point] = max_width;
+ const coord_t max_width_contour = bounds.contour.closest_point(polyline.points[idx_point])->distance_to(polyline.points[idx_point]) * 2.1;
+ if (polyline.width[idx_point] > max_width_contour)
+ polyline.width[idx_point] = max_width_contour;
+
+ ++idx_point;
+ }
+ if (idx_point < best_candidate->points.size()) {
+ if (idx_point + 1 < best_candidate->points.size()) {
+ //create a new polyline
+ pp.emplace_back();
+ pp.back().endpoints.first = true;
+ pp.back().endpoints.second = best_candidate->endpoints.second;
+ for (size_t idx_point_new_line = idx_point; idx_point_new_line < best_candidate->points.size(); ++idx_point_new_line) {
+ pp.back().points.push_back(best_candidate->points[idx_point_new_line]);
+ pp.back().width.push_back(best_candidate->width[idx_point_new_line]);
+ }
+ } else {
+ //Add last point
+ polyline.points.push_back(best_candidate->points[idx_point]);
+ polyline.width.push_back(best_candidate->width[idx_point]);
+ //select if an end occur
+ polyline.endpoints.second &= best_candidate->endpoints.second;
+ }
+
+ } else {
+ //select if an end occur
+ polyline.endpoints.second &= best_candidate->endpoints.second;
+ }
+
+ //remove points that are the same or too close each other, ie simplify
+ for (size_t idx_point = 1; idx_point < polyline.points.size(); ++idx_point) {
+ if (polyline.points[idx_point - 1].distance_to(polyline.points[idx_point]) < SCALED_EPSILON) {
+ if (idx_point < polyline.points.size() - 1) {
+ polyline.points.erase(polyline.points.begin() + idx_point);
+ polyline.width.erase(polyline.width.begin() + idx_point);
+ } else {
+ polyline.points.erase(polyline.points.begin() + idx_point - 1);
+ polyline.width.erase(polyline.width.begin() + idx_point - 1);
+ }
+ --idx_point;
+ }
+ }
+ //remove points that are outside of the geometry
+ for (size_t idx_point = 0; idx_point < polyline.points.size(); ++idx_point) {
+ if (!bounds.contains_b(polyline.points[idx_point])) {
+ polyline.points.erase(polyline.points.begin() + idx_point);
+ polyline.width.erase(polyline.width.begin() + idx_point);
+ --idx_point;
+ }
+ }
+
+ //update cache
+ coeff_angle_cache[polyline.points.back()] = coeff_angle_poly * coeff_poly + coeff_angle_candi * coeff_candi;
+
+
+ if (polyline.points.size() < 2) {
+ //remove self
+ pp.erase(pp.begin() + i);
+ --i;
+ --best_idx;
+ }
+
+ pp.erase(pp.begin() + best_idx);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_2.0_aft_fus_" << id << "_" << idf << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+ changes = true;
+ break;
+ }
+ }
+ }
+}
+
+void
+MedialAxis::remove_too_thin_extrusion(ThickPolylines& pp)
+{
+ // remove too thin extrusion at start & end of polylines
+ bool changes = false;
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ // remove bits with too small extrusion
+ while (polyline.points.size() > 1 && polyline.width.front() < this->min_width && polyline.endpoints.first) {
+ //try to split if possible
+ if (polyline.width[1] > min_width) {
+ double percent_can_keep = 1 - (min_width - polyline.width[0]) / (polyline.width[1] - polyline.width[0]);
+ if (polyline.points.front().distance_to(polyline.points[1]) * percent_can_keep > SCALED_RESOLUTION) {
+ //Can split => move the first point and assign a new weight.
+ //the update of endpoints wil be performed in concatThickPolylines
+ polyline.points.front().x() = polyline.points.front().x() +
+ (coord_t)((polyline.points[1].x() - polyline.points.front().x()) * (1 - percent_can_keep));
+ polyline.points.front().y() = polyline.points.front().y() +
+ (coord_t)((polyline.points[1].y() - polyline.points.front().y()) * (1 - percent_can_keep));
+ polyline.width.front() = min_width;
+ } else {
+ /// almost 0-length, Remove
+ polyline.points.erase(polyline.points.begin());
+ polyline.width.erase(polyline.width.begin());
+ }
+ changes = true;
+ break;
+ }
+ polyline.points.erase(polyline.points.begin());
+ polyline.width.erase(polyline.width.begin());
+ changes = true;
+ }
+ while (polyline.points.size() > 1 && polyline.width.back() < this->min_width && polyline.endpoints.second) {
+ //try to split if possible
+ if (polyline.width[polyline.points.size() - 2] > min_width) {
+ double percent_can_keep = 1 - (min_width - polyline.width.back()) / (polyline.width[polyline.points.size() - 2] - polyline.width.back());
+ if (polyline.points.back().distance_to(polyline.points[polyline.points.size() - 2]) * percent_can_keep > SCALED_RESOLUTION) {
+ //Can split => move the first point and assign a new weight.
+ //the update of endpoints wil be performed in concatThickPolylines
+ polyline.points.back().x() = polyline.points.back().x() +
+ (coord_t)((polyline.points[polyline.points.size() - 2].x() - polyline.points.back().x()) * (1 - percent_can_keep));
+ polyline.points.back().y() = polyline.points.back().y() +
+ (coord_t)((polyline.points[polyline.points.size() - 2].y() - polyline.points.back().y()) * (1 - percent_can_keep));
+ polyline.width.back() = min_width;
+ } else {
+ /// almost 0-length, Remove
+ polyline.points.erase(polyline.points.end() - 1);
+ polyline.width.erase(polyline.width.end() - 1);
+ }
+ changes = true;
+ break;
+ }
+ polyline.points.erase(polyline.points.end() - 1);
+ polyline.width.erase(polyline.width.end() - 1);
+ changes = true;
+ }
+ //remove points and bits that comes from a "main line"
+ if (polyline.points.size() < 2 || (changes && polyline.length() < max_width && polyline.points.size() ==2)) {
+ //remove self if too small
+ pp.erase(pp.begin() + i);
+ --i;
+ }
+ }
+ if (changes) concatThickPolylines(pp);
+}
+
+void
+MedialAxis::concatenate_polylines_with_crossing(ThickPolylines& pp)
+{
+
+ // concatenate, but even where multiple thickpolyline join, to create nice long strait polylines
+ /* If we removed any short polylines we now try to connect consecutive polylines
+ in order to allow loop detection. Note that this algorithm is greedier than
+ MedialAxis::process_edge_neighbors() as it will connect random pairs of
+ polylines even when more than two start from the same point. This has no
+ drawbacks since we optimize later using nearest-neighbor which would do the
+ same, but should we use a more sophisticated optimization algorithm we should
+ not connect polylines when more than two meet.
+ Optimisation of the old algorithm : now we select the most "strait line" choice
+ when we merge with an other line at a point with more than two meet.
+ */
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization
+
+ ThickPolyline* best_candidate = nullptr;
+ float best_dot = -1;
+ size_t best_idx = 0;
+
+ // find another polyline starting here
+ for (size_t j = 0; j < pp.size(); ++j) {
+ if (j == i) continue;
+ ThickPolyline& other = pp[j];
+ if (other.endpoints.first && other.endpoints.second) continue;
+
+ if (polyline.last_point().coincides_with(other.last_point())) {
+ other.reverse();
+ } else if (polyline.first_point().coincides_with(other.last_point())) {
+ polyline.reverse();
+ other.reverse();
+ } else if (polyline.first_point().coincides_with(other.first_point())) {
+ polyline.reverse();
+ } else if (!polyline.last_point().coincides_with(other.first_point())) {
+ continue;
+ }
+
+ Vec2d v_poly(polyline.lines().back().vector().x(), polyline.lines().back().vector().y());
+ v_poly *= (1 / std::sqrt(v_poly.x()*v_poly.x() + v_poly.y()*v_poly.y()));
+ Vec2d v_other(other.lines().front().vector().x(), other.lines().front().vector().y());
+ v_other *= (1 / std::sqrt(v_other.x()*v_other.x() + v_other.y()*v_other.y()));
+ float other_dot = v_poly.x()*v_other.x() + v_poly.y()*v_other.y();
+ if (other_dot > best_dot) {
+ best_candidate = &other;
+ best_idx = j;
+ best_dot = other_dot;
+ }
+ }
+ if (best_candidate != nullptr) {
+ polyline.points.insert(polyline.points.end(), best_candidate->points.begin() + 1, best_candidate->points.end());
+ polyline.width.insert(polyline.width.end(), best_candidate->width.begin() + 1, best_candidate->width.end());
+ polyline.endpoints.second = best_candidate->endpoints.second;
+ assert(polyline.width.size() == polyline.points.size());
+ if (best_idx < i) i--;
+ pp.erase(pp.begin() + best_idx);
+ }
+ }
+}
+
+void
+MedialAxis::remove_too_thin_points(ThickPolylines& pp)
+{
+ //remove too thin polylines points (inside a polyline : split it)
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+
+ // remove bits with too small extrusion
+ size_t idx_point = 0;
+ while (idx_point<polyline.points.size()) {
+ if (polyline.width[idx_point] < min_width) {
+ if (idx_point == 0) {
+ //too thin at start
+ polyline.points.erase(polyline.points.begin());
+ polyline.width.erase(polyline.width.begin());
+ idx_point = 0;
+ } else if (idx_point == 1) {
+ //too thin at start
+ polyline.points.erase(polyline.points.begin());
+ polyline.width.erase(polyline.width.begin());
+ polyline.points.erase(polyline.points.begin());
+ polyline.width.erase(polyline.width.begin());
+ idx_point = 0;
+ } else if (idx_point == polyline.points.size() - 2) {
+ //too thin at (near) end
+ polyline.points.erase(polyline.points.end() - 1);
+ polyline.width.erase(polyline.width.end() - 1);
+ polyline.points.erase(polyline.points.end() - 1);
+ polyline.width.erase(polyline.width.end() - 1);
+ } else if (idx_point == polyline.points.size() - 1) {
+ //too thin at end
+ polyline.points.erase(polyline.points.end() - 1);
+ polyline.width.erase(polyline.width.end() - 1);
+ } else {
+ //too thin in middle : split
+ pp.emplace_back();
+ ThickPolyline &newone = pp.back();
+ newone.points.insert(newone.points.begin(), polyline.points.begin() + idx_point + 1, polyline.points.end());
+ newone.width.insert(newone.width.begin(), polyline.width.begin() + idx_point + 1, polyline.width.end());
+ polyline.points.erase(polyline.points.begin() + idx_point, polyline.points.end());
+ polyline.width.erase(polyline.width.begin() + idx_point, polyline.width.end());
+ }
+ } else idx_point++;
+
+ if (polyline.points.size() < 2) {
+ //remove self if too small
+ pp.erase(pp.begin() + i);
+ --i;
+ break;
+ }
+ }
+ }
+}
+
+void
+MedialAxis::remove_too_short_polylines(ThickPolylines& pp, const coord_t min_size)
+{
+ //remove too short polyline
+ bool changes = true;
+ while (changes) {
+ changes = false;
+
+ double shortest_size = min_size;
+ size_t shortest_idx = -1;
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline& polyline = pp[i];
+ // Remove the shortest polylines : polyline that are shorter than wider
+ // (we can't do this check before endpoints extension and clipping because we don't
+ // know how long will the endpoints be extended since it depends on polygon thickness
+ // which is variable - extension will be <= max_width/2 on each side)
+ if ((polyline.endpoints.first || polyline.endpoints.second)
+ && polyline.length() < max_width / 2) {
+ if (shortest_size > polyline.length()) {
+ shortest_size = polyline.length();
+ shortest_idx = i;
+ }
+
+ }
+ }
+ if (shortest_idx < pp.size()) {
+ pp.erase(pp.begin() + shortest_idx);
+ changes = true;
+ }
+ if (changes) concatThickPolylines(pp);
+ }
+}
+
+void
+MedialAxis::ensure_not_overextrude(ThickPolylines& pp)
+{
+ //ensure the volume extruded is correct for what we have been asked
+ // => don't over-extrude
+ double surface = 0;
+ double volume = 0;
+ for (ThickPolyline& polyline : pp) {
+ for (ThickLine &l : polyline.thicklines()) {
+ surface += l.length() * (l.a_width + l.b_width) / 2;
+ double width_mean = (l.a_width + l.b_width) / 2;
+ volume += height * (width_mean - height * (1. - 0.25 * PI)) * l.length();
+ }
+ }
+
+ // compute bounds volume
+ double boundsVolume = 0;
+ boundsVolume += height*bounds.area();
+ // add external "perimeter gap"
+ double perimeterRoundGap = bounds.contour.length() * height * (1 - 0.25*PI) * 0.5;
+ // add holes "perimeter gaps"
+ double holesGaps = 0;
+ for (const Polygon &hole : bounds.holes) {
+ holesGaps += hole.length() * height * (1 - 0.25*PI) * 0.5;
+ }
+ boundsVolume += perimeterRoundGap + holesGaps;
+
+ if (boundsVolume < volume) {
+ //reduce width
+ double reduce_by = boundsVolume / volume;
+ for (ThickPolyline& polyline : pp) {
+ for (coordf_t &width : polyline.width) {
+ width *= reduce_by;
+ }
+ }
+ }
+}
+
+ExPolygon
+MedialAxis::simplify_polygon_frontier()
+{
+
+ //simplify the boundary between us and the bounds.
+ //it will remove every point in the surface contour that aren't on the bounds contour
+ ExPolygon simplified_poly = this->surface;
+ if (&this->surface != &this->bounds) {
+ bool need_intersect = false;
+ for (size_t i = 0; i < simplified_poly.contour.points.size(); i++) {
+ Point &p_check = simplified_poly.contour.points[i];
+ //if (!find) {
+ if (!bounds.has_boundary_point(p_check)) {
+ //check if we put it at a bound point instead of delete it
+ size_t prev_i = i == 0 ? simplified_poly.contour.points.size() - 1 : (i - 1);
+ size_t next_i = i == simplified_poly.contour.points.size() - 1 ? 0 : (i + 1);
+ const Point* closest = bounds.contour.closest_point(p_check);
+ if (closest != nullptr && closest->distance_to(p_check) + SCALED_EPSILON
+ < min(p_check.distance_to(simplified_poly.contour.points[prev_i]), p_check.distance_to(simplified_poly.contour.points[next_i])) / 2) {
+ p_check.x() = closest->x();
+ p_check.y() = closest->y();
+ need_intersect = true;
+ } else {
+ simplified_poly.contour.points.erase(simplified_poly.contour.points.begin() + i);
+ i--;
+ }
+ }
+ }
+ if (need_intersect) {
+ ExPolygons simplified_polys = intersection_ex(simplified_poly, bounds);
+ if (simplified_polys.size() == 1) {
+ simplified_poly = simplified_polys[0];
+ } else {
+ simplified_poly = this->surface;
+ }
+ }
+ }
+
+ if (!simplified_poly.contour.points.empty())
+ simplified_poly.remove_point_too_near(SCALED_RESOLUTION);
+ return simplified_poly;
+}
+
+void
+MedialAxis::build(ThickPolylines* polylines_out) {
+ this->id++;
+ //std::cout << layerid << "\n";
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_0_enter_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(this->surface);
+ // svg.Close();
+ //}
+ this->expolygon = simplify_polygon_frontier();
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_0.5_simplified_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.Close();
+ //}
+ //safety check
+ if (this->expolygon.area() < this->min_width * this->min_width) this->expolygon = this->surface;
+ if (this->expolygon.area() < this->min_width * this->min_width) return;
+
+ //std::cout << "simplify_polygon_frontier\n";
+ // compute the Voronoi diagram and extract medial axis polylines
+ ThickPolylines pp;
+ this->polyline_from_voronoi(this->expolygon.lines(), &pp);
+
+ concatThickPolylines(pp);
+
+ //std::cout << "concatThickPolylines\n";
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_1_voronoi_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ /* Find the maximum width returned; we're going to use this for validating and
+ filtering the output segments. */
+ double max_w = 0;
+ for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it)
+ max_w = fmaxf(max_w, *std::max_element(it->width.begin(), it->width.end()));
+
+
+ fusion_curve(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_2_curve_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+
+ // Aligned fusion: Fusion the bits at the end of lines by "increasing thickness"
+ // For that, we have to find other lines,
+ // and with a next point no more distant than the max width.
+ // Then, we can merge the bit from the first point to the second by following the mean.
+ //
+ main_fusion(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_3_fusion_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ //fusion right-angle corners.
+ fusion_corners(pp);
+
+ if (stop_at_min_width) {
+ extends_line_both_side(pp);
+ }
+
+ //reduce extrusion when it's too thin to be printable
+ remove_too_thin_extrusion(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_4_thinok_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ remove_too_thin_points(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_5.0_thuinner_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ // Loop through all returned polylines in order to extend their endpoints to the
+ // expolygon boundaries
+ if (!stop_at_min_width) {
+ extends_line_both_side(pp);
+ }
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_5_expand_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ concatenate_polylines_with_crossing(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_6_concat_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ remove_too_short_polylines(pp, max_w * 2);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_8_tooshort_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+
+ //TODO: reduce the flow at the intersection ( + ) points ?
+ ensure_not_overextrude(pp);
+ //{
+ // stringstream stri;
+ // stri << "medial_axis_9_endn_" << id << ".svg";
+ // SVG svg(stri.str());
+ // svg.draw(bounds);
+ // svg.draw(this->expolygon);
+ // svg.draw(pp);
+ // svg.Close();
+ //}
+ if (nozzle_diameter != min_width) {
+ grow_to_nozzle_diameter(pp, diff_ex(this->bounds, this->expolygon));
+ taper_ends(pp);
+ }
+
+ polylines_out->insert(polylines_out->end(), pp.begin(), pp.end());
+
+}
+
+
+void
+MedialAxis::grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchors) {
+ //ensure the width is not lower than 0.4.
+ for (ThickPolyline& polyline : pp) {
+ for (int i = 0; i < polyline.points.size(); ++i) {
+ bool is_anchored = false;
+ for (const ExPolygon &poly : anchors) {
+ if (poly.contains(polyline.points[i])) {
+ is_anchored = true;
+ break;
+ }
+ }
+ if (!is_anchored && polyline.width[i]<nozzle_diameter) polyline.width[i] = nozzle_diameter;
+ }
+ }
+}
+
+void
+MedialAxis::taper_ends(ThickPolylines& pp) {
+ //ensure the width is not lower than 0.4.
+ for (ThickPolyline& polyline : pp) {
+ if (polyline.length() < nozzle_diameter * 2) continue;
+ if (polyline.endpoints.first) {
+ polyline.width[0] = min_width;
+ coord_t current_dist = min_width;
+ for (size_t i = 1; i<polyline.width.size(); ++i) {
+ current_dist += polyline.points[i - 1].distance_to(polyline.points[i]);
+ if (current_dist > polyline.width[i]) break;
+ polyline.width[i] = current_dist;
+ }
+ }
+ if (polyline.endpoints.second) {
+ size_t last_idx = polyline.width.size() - 1;
+ polyline.width[last_idx] = min_width;
+ coord_t current_dist = min_width;
+ for (size_t i = 1; i<polyline.width.size(); ++i) {
+ current_dist += polyline.points[last_idx - i + 1].distance_to(polyline.points[last_idx - i]);
+ if (current_dist > polyline.width[last_idx - i]) break;
+ polyline.width[last_idx - i] = current_dist;
+ }
+ }
+ }
+}
+
+ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) {
+ // this value determines granularity of adaptive width, as G-code does not allow
+ // variable extrusion within a single move; this value shall only affect the amount
+ // of segments, and any pruning shall be performed before we apply this tolerance
+ const double tolerance = scale_(0.05);
+
+ int id_line = 0;
+ ExtrusionEntityCollection coll;
+ for (const ThickPolyline &p : polylines) {
+ id_line++;
+ ExtrusionPaths paths;
+ ExtrusionPath path(role);
+ ThickLines lines = p.thicklines();
+
+ for (int i = 0; i < (int)lines.size(); ++i) {
+ const ThickLine& line = lines[i];
+
+ const coordf_t line_len = line.length();
+ if (line_len < SCALED_EPSILON) continue;
+
+ double thickness_delta = fabs(line.a_width - line.b_width);
+ if (thickness_delta > tolerance) {
+ const unsigned short segments = ceil(thickness_delta / tolerance);
+ const coordf_t seg_len = line_len / segments;
+ Points pp;
+ std::vector<coordf_t> width;
+ {
+ pp.push_back(line.a);
+ width.push_back(line.a_width);
+ for (size_t j = 1; j < segments; ++j) {
+ pp.push_back(line.point_at(j*seg_len));
+
+ coordf_t w = line.a_width + (j*seg_len) * (line.b_width - line.a_width) / line_len;
+ width.push_back(w);
+ width.push_back(w);
+ }
+ pp.push_back(line.b);
+ width.push_back(line.b_width);
+
+ assert(pp.size() == segments + 1);
+ assert(width.size() == segments * 2);
+ }
+
+ // delete this line and insert new ones
+ lines.erase(lines.begin() + i);
+ for (size_t j = 0; j < segments; ++j) {
+ ThickLine new_line(pp[j], pp[j + 1]);
+ new_line.a_width = width[2 * j];
+ new_line.b_width = width[2 * j + 1];
+ lines.insert(lines.begin() + i + j, new_line);
+ }
+
+ --i;
+ continue;
+ }
+
+ const double w = fmax(line.a_width, line.b_width);
+ if (path.polyline.points.empty()) {
+ path.polyline.append(line.a);
+ path.polyline.append(line.b);
+ // Convert from spacing to extrusion width based on the extrusion model
+ // of a square extrusion ended with semi circles.
+ flow.width = unscaled(w) + flow.height * (1. - 0.25 * PI);
+#ifdef SLIC3R_DEBUG
+ printf(" filling %f gap\n", flow.width);
+#endif
+ path.mm3_per_mm = flow.mm3_per_mm();
+ path.width = flow.width;
+ path.height = flow.height;
+ } else {
+ thickness_delta = fabs(scale_(flow.width) - w);
+ if (thickness_delta <= tolerance / 2) {
+ // the width difference between this line and the current flow width is
+ // within the accepted tolerance
+ path.polyline.append(line.b);
+ } else {
+ // we need to initialize a new line
+ paths.emplace_back(std::move(path));
+ path = ExtrusionPath(role);
+ --i;
+ }
+ }
+ }
+ if (path.polyline.is_valid())
+ paths.emplace_back(std::move(path));
+ // Append paths to collection.
+ if (!paths.empty()) {
+ if (paths.front().first_point().coincides_with(paths.back().last_point())) {
+ coll.append(ExtrusionLoop(paths));
+ } else {
+ //not a loop : avoid to "sort" it.
+ ExtrusionEntityCollection unsortable_coll(paths);
+ unsortable_coll.no_sort = true;
+ coll.append(unsortable_coll);
+ }
+ }
+ }
+
+ return coll;
+}
+
+} // namespace Slic3r
diff --git a/src/libslic3r/MedialAxis.hpp b/src/libslic3r/MedialAxis.hpp
new file mode 100644
index 000000000..9d71207b1
--- /dev/null
+++ b/src/libslic3r/MedialAxis.hpp
@@ -0,0 +1,74 @@
+#ifndef slic3r_MedialAxis_hpp_
+#define slic3r_MedialAxis_hpp_
+
+#include "libslic3r.h"
+#include "ExPolygon.hpp"
+#include "Polyline.hpp"
+#include "Geometry.hpp"
+#include "ExtrusionEntityCollection.hpp"
+#include "Flow.hpp"
+#include <vector>
+
+#include "boost/polygon/voronoi.hpp"
+using boost::polygon::voronoi_builder;
+using boost::polygon::voronoi_diagram;
+
+namespace Slic3r {
+
+ class MedialAxis {
+ public:
+ Lines lines; //lines is here only to avoid passing it in argument of many methods. Initialized in polyline_from_voronoi.
+ ExPolygon expolygon;
+ const ExPolygon& bounds;
+ const ExPolygon& surface;
+ const coord_t max_width;
+ const coord_t min_width;
+ const coord_t height;
+ coord_t nozzle_diameter;
+ bool stop_at_min_width = true;
+ MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const coord_t _max_width, const coord_t _min_width, const coord_t _height)
+ : surface(_expolygon), bounds(_bounds), max_width(_max_width), min_width(_min_width), height(_height) {
+ nozzle_diameter = _min_width;
+ };
+ void build(ThickPolylines* polylines_out);
+ void build(Polylines* polylines);
+
+ private:
+ static int id;
+ class VD : public voronoi_diagram<double> {
+ public:
+ typedef double coord_type;
+ typedef boost::polygon::point_data<coordinate_type> point_type;
+ typedef boost::polygon::segment_data<coordinate_type> segment_type;
+ typedef boost::polygon::rectangle_data<coordinate_type> rect_type;
+ };
+ VD vd;
+ std::set<const VD::edge_type*> edges, valid_edges;
+ std::map<const VD::edge_type*, std::pair<coordf_t, coordf_t> > thickness;
+ void process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* polyline);
+ bool validate_edge(const VD::edge_type* edge);
+ const Line& retrieve_segment(const VD::cell_type* cell) const;
+ const Point& retrieve_endpoint(const VD::cell_type* cell) const;
+ void polyline_from_voronoi(const Lines& voronoi_edges, ThickPolylines* polylines_out);
+
+ ExPolygon simplify_polygon_frontier();
+ void fusion_curve(ThickPolylines &pp);
+ void main_fusion(ThickPolylines& pp);
+ void fusion_corners(ThickPolylines &pp);
+ void extends_line_both_side(ThickPolylines& pp);
+ void extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width);
+ void remove_too_thin_extrusion(ThickPolylines& pp);
+ void concatenate_polylines_with_crossing(ThickPolylines& pp);
+ void remove_too_thin_points(ThickPolylines& pp);
+ void remove_too_short_polylines(ThickPolylines& pp, const coord_t min_size);
+ void ensure_not_overextrude(ThickPolylines& pp);
+ void grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchors);
+ void taper_ends(ThickPolylines& pp);
+ };
+
+ ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow);
+
+}
+
+
+#endif
diff --git a/src/libslic3r/MultiPoint.cpp b/src/libslic3r/MultiPoint.cpp
index ee3b99747..46cf2f633 100644
--- a/src/libslic3r/MultiPoint.cpp
+++ b/src/libslic3r/MultiPoint.cpp
@@ -162,6 +162,43 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
return found;
}
+// Projection of a point onto the polygon.
+Point MultiPoint::point_projection(const Point &point) const {
+ Point proj = point;
+ double dmin = std::numeric_limits<double>::max();
+ if (!this->points.empty()) {
+ for (size_t i = 0; i < this->points.size()-1; ++i) {
+ const Point &pt0 = this->points[i];
+ const Point &pt1 = this->points[i + 1];
+ double d = pt0.distance_to(point);
+ if (d < dmin) {
+ dmin = d;
+ proj = pt0;
+ }
+ d = pt1.distance_to(point);
+ if (d < dmin) {
+ dmin = d;
+ proj = pt1;
+ }
+ Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1)));
+ coordf_t div = dot(v1);
+ if (div > 0.) {
+ Vec2d v2(coordf_t(point(0) - pt0(0)), coordf_t(point(1) - pt0(1)));
+ coordf_t t = dot(v1, v2) / div;
+ if (t > 0. && t < 1.) {
+ Point foot(coord_t(floor(coordf_t(pt0(0)) + t * v1(0) + 0.5)), coord_t(floor(coordf_t(pt0(1)) + t * v1(1) + 0.5)));
+ d = foot.distance_to(point);
+ if (d < dmin) {
+ dmin = d;
+ proj = foot;
+ }
+ }
+ }
+ }
+ }
+ return proj;
+}
+
std::vector<Point> MultiPoint::_douglas_peucker(const std::vector<Point>& pts, const double tolerance)
{
std::vector<Point> result_pts;
diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp
index 38020d6e8..2440c3a49 100644
--- a/src/libslic3r/MultiPoint.hpp
+++ b/src/libslic3r/MultiPoint.hpp
@@ -79,6 +79,8 @@ public:
bool intersection(const Line& line, Point* intersection) const;
bool first_intersection(const Line& line, Point* intersection) const;
+ // Projection of a point onto the lines defined by the points.
+ virtual Point point_projection(const Point &point) const;
static Points _douglas_peucker(const Points &points, const double tolerance);
static Points visivalingam(const Points& pts, const double& tolerance);
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index de8aeeb2a..5302a3b5a 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -1,11 +1,37 @@
#include "PerimeterGenerator.hpp"
#include "ClipperUtils.hpp"
#include "ExtrusionEntityCollection.hpp"
+#include "BridgeDetector.hpp"
+#include "Geometry.hpp"
#include <cmath>
#include <cassert>
+#include <vector>
+
+#include "BoundingBox.hpp"
+#include "ExPolygon.hpp"
+#include "Geometry.hpp"
+#include "Polygon.hpp"
+#include "Line.hpp"
+#include "ClipperUtils.hpp"
+#include "SVG.hpp"
+#include "polypartition.h"
+#include "poly2tri/poly2tri.h"
+#include <algorithm>
+#include <cassert>
+#include <list>
namespace Slic3r {
+ PerimeterGeneratorLoops get_all_Childs(PerimeterGeneratorLoop loop) {
+ PerimeterGeneratorLoops ret;
+ for (PerimeterGeneratorLoop &child : loop.children) {
+ ret.push_back(child);
+ PerimeterGeneratorLoops vals = get_all_Childs(child);
+ ret.insert(ret.end(), vals.begin(), vals.end());
+ }
+ return ret;
+ }
+
void PerimeterGenerator::process()
{
// other perimeters
@@ -49,117 +75,338 @@ void PerimeterGenerator::process()
// we need to process each island separately because we might have different
// extra perimeters for each one
+ int surface_idx = 0;
for (const Surface &surface : this->slices->surfaces) {
// detect how many perimeters must be generated for this island
int loop_number = this->config->perimeters + surface.extra_perimeters - 1; // 0-indexed loops
- ExPolygons last = union_ex(surface.expolygon.simplify_p(SCALED_RESOLUTION));
+ surface_idx++;
+
+ if (this->config->only_one_perimeter_top && this->upper_slices == NULL){
+ loop_number = 0;
+ }
+
ExPolygons gaps;
+ //this var store infill surface removed from last to not add any more perimeters to it.
+ ExPolygons stored;
+ ExPolygons last = union_ex(surface.expolygon.simplify_p(SCALED_RESOLUTION));
if (loop_number >= 0) {
- // In case no perimeters are to be generated, loop_number will equal to -1.
+ // In case no perimeters are to be generated, loop_number will equal to -1.
std::vector<PerimeterGeneratorLoops> contours(loop_number+1); // depth => loops
std::vector<PerimeterGeneratorLoops> holes(loop_number+1); // depth => loops
ThickPolylines thin_walls;
// we loop one time more than needed in order to find gaps after the last perimeter was applied
for (int i = 0;; ++ i) { // outer loop is 0
+
+ //store surface for bridge infill to avoid unsupported perimeters (but the first one, this one is always good)
+ if (this->config->no_perimeter_unsupported && i == this->config->min_perimeter_unsupported
+ && this->lower_slices != NULL && !this->lower_slices->expolygons.empty()) {
+
+ //compute our unsupported surface
+ ExPolygons unsupported = diff_ex(last, this->lower_slices->expolygons, true);
+ if (!unsupported.empty()) {
+ //remove small overhangs
+ ExPolygons unsupported_filtered = offset2_ex(unsupported, -(float)(perimeter_spacing), (float)(perimeter_spacing));
+ if (!unsupported_filtered.empty()) {
+ //to_draw.insert(to_draw.end(), last.begin(), last.end());
+ //extract only the useful part of the lower layer. The safety offset is really needed here.
+ ExPolygons support = diff_ex(last, unsupported, true);
+ if (this->config->noperi_bridge_only && !unsupported.empty()) {
+ //only consider the part that can be bridged (really, by the bridge algorithm)
+ //first, separate into islands (ie, each ExPlolygon)
+ int numploy = 0;
+ //only consider the bottom layer that intersect unsupported, to be sure it's only on our island.
+ ExPolygonCollection lower_island(support);
+ BridgeDetector detector(unsupported_filtered,
+ lower_island,
+ perimeter_spacing);
+ if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value))) {
+ ExPolygons bridgeable = union_ex(detector.coverage(-1, true));
+ if (!bridgeable.empty()) {
+ //simplify to avoid most of artefacts from printing lines.
+ ExPolygons bridgeable_simplified;
+ for (ExPolygon &poly : bridgeable) {
+ poly.simplify(perimeter_spacing/2, &bridgeable_simplified);
+ }
+ //offset by perimeter spacing because the simplify may have reduced it a bit.
+ //it's not dangerous as it will be intersected by 'unsupported' later
+ //FIXME: add overlap in this->fill_surfaces->append
+ // add overlap (perimeter_spacing/4 was good in test, ie 25%)
+ coord_t overlap = scale_(this->config->get_abs_value("infill_overlap", unscale<double>(perimeter_spacing)));
+ unsupported_filtered = intersection_ex(unsupported_filtered, offset_ex(bridgeable_simplified, overlap));
+ } else {
+ unsupported_filtered.clear();
+ }
+ } else {
+ unsupported_filtered.clear();
+ }
+ } else {
+ //only consider the part that can be 'bridged' (inside the convex hull)
+ // it's not as precise as the bridge detector, but it's better than nothing, and quicker.
+ ExPolygonCollection coll_last(support);
+ ExPolygon hull;
+ hull.contour = coll_last.convex_hull();
+ unsupported_filtered = intersection_ex(unsupported_filtered, ExPolygons() = { hull });
+ }
+ if (!unsupported_filtered.empty()) {
+ //and we want at least 1 perimeter of overlap
+ ExPolygons bridge = unsupported_filtered;
+ unsupported_filtered = intersection_ex(offset_ex(unsupported_filtered, (float)(perimeter_spacing)), last);
+ // remove from the bridge & support the small imperfections of the union
+ ExPolygons bridge_and_support = offset2_ex(union_ex(bridge, support, true), perimeter_spacing/2, -perimeter_spacing/2);
+ // make him flush with perimeter area
+ unsupported_filtered = intersection_ex(offset_ex(unsupported_filtered, (float)(perimeter_spacing / 2)), bridge_and_support);
+
+ //add this directly to the infill list.
+ // this will avoid to throw wrong offsets into a good polygons
+ this->fill_surfaces->append(
+ unsupported_filtered,
+ stInternal);
+
+ // store the results
+ last = diff_ex(last, unsupported_filtered, true);
+ //remove "thin air" polygons
+ for (int i = 0; i < last.size();i++) {
+ if (intersection_ex(support, ExPolygons() = { last[i] }).empty()) {
+ this->fill_surfaces->append(
+ ExPolygons() = { last[i] },
+ stInternal);
+ last.erase(last.begin() + i);
+ i--;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // We can add more perimeters if there are uncovered overhangs
+ // improvement for future: find a way to add perimeters only where it's needed.
+ // It's hard to do, so here is a simple version.
+ bool has_overhang = false;
+ if (this->config->extra_perimeters /*&& i > loop_number*/ && !last.empty()
+ && this->lower_slices != NULL && !this->lower_slices->expolygons.empty()){
+ //split the polygons with bottom/notbottom
+ ExPolygons unsupported = diff_ex(last, this->lower_slices->expolygons, true);
+ if (!unsupported.empty()) {
+ //only consider overhangs and let bridges alone
+ if (true) {
+ //only consider the part that can be bridged (really, by the bridge algorithm)
+ //first, separate into islands (ie, each ExPlolygon)
+ //only consider the bottom layer that intersect unsupported, to be sure it's only on our island.
+ ExPolygonCollection lower_island(diff_ex(last, unsupported, true));
+ BridgeDetector detector(unsupported,
+ lower_island,
+ perimeter_spacing);
+ if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value))) {
+ ExPolygons bridgeable = union_ex(detector.coverage(-1, true));
+ if (!bridgeable.empty()) {
+ //simplify to avoid most of artefacts from printing lines.
+ ExPolygons bridgeable_simplified;
+ for (ExPolygon &poly : bridgeable) {
+ poly.simplify(perimeter_spacing / 2, &bridgeable_simplified);
+ }
+
+ if (!bridgeable_simplified.empty())
+ bridgeable_simplified = offset_ex(bridgeable_simplified, perimeter_spacing/1.9);
+ if (!bridgeable_simplified.empty()) {
+ //offset by perimeter spacing because the simplify may have reduced it a bit.
+ unsupported = diff_ex(unsupported, bridgeable_simplified, true);
+ }
+ }
+ }
+ } else {
+ ExPolygonCollection coll_last(intersection_ex(last, offset_ex(this->lower_slices->expolygons, -perimeter_spacing / 2)));
+ ExPolygon hull;
+ hull.contour = coll_last.convex_hull();
+ unsupported = diff_ex(offset_ex(unsupported, perimeter_spacing), ExPolygons() = { hull });
+ }
+ if (!unsupported.empty()) {
+ //add fake perimeters here
+ has_overhang = true;
+ }
+ }
+ }
+
// Calculate next onion shell of perimeters.
- ExPolygons offsets;
+ //this variable stored the nexyt onion
+ ExPolygons next_onion;
if (i == 0) {
- // the minimum thickness of a single loop is:
- // ext_width/2 + ext_spacing/2 + spacing/2 + width/2
- offsets = this->config->thin_walls ?
- offset2_ex(
- last,
- -(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1),
- +(ext_min_spacing / 2 - 1)) :
- offset_ex(last, - ext_perimeter_width / 2);
+ // compute next onion, without taking care of thin_walls : destroy too thin areas.
+ if (!this->config->thin_walls)
+ next_onion = offset_ex(last, -(float)(ext_perimeter_width / 2));
+
+
// look for thin walls
if (this->config->thin_walls) {
+ // the minimum thickness of a single loop is:
+ // ext_width/2 + ext_spacing/2 + spacing/2 + width/2
+
+ next_onion = offset2_ex(
+ last,
+ -(float)(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1),
+ +(float)(ext_min_spacing / 2 - 1));
+
+ // detect edge case where a curve can be split in multiple small chunks.
+ ExPolygons no_thin_onion = offset_ex(last, -(float)(ext_perimeter_width / 2));
+ float div = 2;
+ while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) {
+ div += 0.5;
+ //use a sightly smaller spacing to try to drastically improve the split
+ ExPolygons next_onion_secondTry = offset2_ex(
+ last,
+ -(float)(ext_perimeter_width / 2 + ext_min_spacing / div - 1),
+ +(float)(ext_min_spacing / div - 1));
+ if (next_onion.size() > next_onion_secondTry.size()) {
+ next_onion = next_onion_secondTry;
+ }
+ if (div > 3) break;
+ }
+
// the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width
// (actually, something larger than that still may exist due to mitering or other causes)
- coord_t min_width = scale_(this->ext_perimeter_flow.nozzle_diameter / 3);
- ExPolygons expp = offset2_ex(
- // medial axis requires non-overlapping geometry
- diff_ex(to_polygons(last),
- offset(offsets, ext_perimeter_width / 2),
- true),
- - min_width / 2, min_width / 2);
- // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
- for (ExPolygon &ex : expp)
- ex.medial_axis(ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls);
+ coord_t min_width = (coord_t)scale_(this->config->thin_walls_min_width.get_abs_value(this->ext_perimeter_flow.nozzle_diameter));
+
+ ExPolygons no_thin_zone = offset_ex(next_onion, (float)(ext_perimeter_width / 2), jtSquare);
+ // medial axis requires non-overlapping geometry
+ ExPolygons thin_zones = diff_ex(last, no_thin_zone, true);
+ //don't use offset2_ex, because we don't want to merge the zones that have been separated.
+ //a very little bit of overlap can be created here with other thin polygons, but it's more useful than worisome.
+ ExPolygons half_thins = offset_ex(thin_zones, (float)(-min_width / 2));
+ //simplify them
+ for (ExPolygon &half_thin : half_thins) {
+ half_thin.remove_point_too_near(SCALED_RESOLUTION);
+ }
+ //we push the bits removed and put them into what we will use as our anchor
+ if (half_thins.size() > 0) {
+ no_thin_zone = diff_ex(last, offset_ex(half_thins, (float)(min_width / 2) - SCALED_EPSILON), true);
+ }
+ // compute a bit of overlap to anchor thin walls inside the print.
+ ExPolygons thin_zones_extruded;
+ for (ExPolygon &half_thin : half_thins) {
+ //growing back the polygon
+ ExPolygons thin = offset_ex(half_thin, (float)(min_width / 2));
+ assert(thin.size() == 1);
+ ExPolygons anchor = intersection_ex(offset_ex(half_thin, (float)(min_width / 2) +
+ (float)(ext_perimeter_width / 2), jtSquare), no_thin_zone, true);
+ ExPolygons bounds = union_ex(thin, anchor, true);
+ for (ExPolygon &bound : bounds) {
+ if (!intersection_ex(thin[0], bound).empty()) {
+ //be sure it's not too small to extrude reliably
+ thin[0].remove_point_too_near(SCALED_RESOLUTION);
+ if (thin[0].area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) {
+ bound.remove_point_too_near(SCALED_RESOLUTION);
+ // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
+ Slic3r::MedialAxis ma(thin[0], bound, ext_perimeter_width + ext_perimeter_spacing2, min_width, this->layer_height);
+ ma.nozzle_diameter = (coord_t)scale_(this->ext_perimeter_flow.nozzle_diameter);
+ ma.build(&thin_walls);
+ thin_zones_extruded.emplace_back(thin[0]);
+ }
+ break;
+ }
+ }
+ }
+ next_onion = diff_ex(offset_ex(last, -(float)(ext_perimeter_width / 2)), thin_zones_extruded, true);
}
} else {
//FIXME Is this offset correct if the line width of the inner perimeters differs
// from the line width of the infill?
coord_t distance = (i == 1) ? ext_perimeter_spacing2 : perimeter_spacing;
- offsets = this->config->thin_walls ?
+ if (this->config->thin_walls){
// This path will ensure, that the perimeters do not overfill, as in
// prusa3d/Slic3r GH #32, but with the cost of rounding the perimeters
// excessively, creating gaps, which then need to be filled in by the not very
// reliable gap fill algorithm.
// Also the offset2(perimeter, -x, x) may sometimes lead to a perimeter, which is larger than
// the original.
- offset2_ex(last,
- - (distance + min_spacing / 2 - 1),
- min_spacing / 2 - 1) :
+ next_onion = offset2_ex(last,
+ -(float)(distance + min_spacing / 2 - 1),
+ +(float)(min_spacing / 2 - 1));
+ } else {
// If "detect thin walls" is not enabled, this paths will be entered, which
// leads to overflows, as in prusa3d/Slic3r GH #32
- offset_ex(last, - distance);
+ next_onion = offset_ex(last, -(float)(distance));
+ }
// look for gaps
- if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0)
+ if (this->config->gap_fill_speed.value > 0 && this->config->gap_fill)
// not using safety offset here would "detect" very narrow gaps
// (but still long enough to escape the area threshold) that gap fill
// won't be able to fill but we'd still remove from infill area
append(gaps, diff_ex(
- offset(last, -0.5 * distance),
- offset(offsets, 0.5 * distance + 10))); // safety offset
+ offset(last, -0.5f*distance),
+ offset(next_onion, 0.5f * distance + 10))); // safety offset
}
- if (offsets.empty()) {
+
+ if (next_onion.empty()) {
// Store the number of loops actually generated.
loop_number = i - 1;
// No region left to be filled in.
last.clear();
break;
} else if (i > loop_number) {
- // If i > loop_number, we were looking just for gaps.
- break;
+ if (has_overhang) {
+ loop_number++;
+ contours.emplace_back();
+ holes.emplace_back();
+ } else {
+ // If i > loop_number, we were looking just for gaps.
+ break;
+ }
}
- for (const ExPolygon &expolygon : offsets) {
- contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true));
+
+ for (const ExPolygon &expolygon : next_onion) {
+ contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true, has_overhang));
if (! expolygon.holes.empty()) {
holes[i].reserve(holes[i].size() + expolygon.holes.size());
for (const Polygon &hole : expolygon.holes)
- holes[i].emplace_back(PerimeterGeneratorLoop(hole, i, false));
+ holes[i].emplace_back(PerimeterGeneratorLoop(hole, i, false, has_overhang));
}
}
- last = std::move(offsets);
+ last = std::move(next_onion);
+
+ //store surface for top infill if only_one_perimeter_top
+ if(i==0 && config->only_one_perimeter_top && this->upper_slices != NULL){
+ //split the polygons with top/not_top
+ ExPolygons upper_polygons(this->upper_slices->expolygons);
+ ExPolygons top_polygons = diff_ex(last, (upper_polygons), true);
+ ExPolygons inner_polygons = diff_ex(last, top_polygons, true);
+ // increase a bit the inner space to fill the frontier between last and stored.
+ stored = union_ex(stored, intersection_ex(offset_ex(top_polygons, (float)(perimeter_spacing / 2)), last));
+ last = intersection_ex(offset_ex(inner_polygons, (float)(perimeter_spacing / 2)), last);
+ }
+
+
+
}
+
+ // re-add stored polygons
+ last = union_ex(last, stored);
// nest loops: holes first
- for (int d = 0; d <= loop_number; ++ d) {
+ for (int d = 0; d <= loop_number; ++d) {
PerimeterGeneratorLoops &holes_d = holes[d];
// loop through all holes having depth == d
- for (int i = 0; i < (int)holes_d.size(); ++ i) {
+ for (int i = 0; i < (int)holes_d.size(); ++i) {
const PerimeterGeneratorLoop &loop = holes_d[i];
// find the hole loop that contains this one, if any
- for (int t = d + 1; t <= loop_number; ++ t) {
- for (int j = 0; j < (int)holes[t].size(); ++ j) {
+ for (int t = d+1; t <= loop_number; ++t) {
+ for (int j = 0; j < (int)holes[t].size(); ++j) {
PerimeterGeneratorLoop &candidate_parent = holes[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
holes_d.erase(holes_d.begin() + i);
- -- i;
+ --i;
goto NEXT_LOOP;
}
}
}
// if no hole contains this hole, find the contour loop that contains it
- for (int t = loop_number; t >= 0; -- t) {
- for (int j = 0; j < (int)contours[t].size(); ++ j) {
+ for (int t = loop_number; t >= 0; --t) {
+ for (int j = 0; j < (int)contours[t].size(); ++j) {
PerimeterGeneratorLoop &candidate_parent = contours[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
holes_d.erase(holes_d.begin() + i);
- -- i;
+ --i;
goto NEXT_LOOP;
}
}
@@ -168,19 +415,19 @@ void PerimeterGenerator::process()
}
}
// nest contour loops
- for (int d = loop_number; d >= 1; -- d) {
+ for (int d = loop_number; d >= 1; --d) {
PerimeterGeneratorLoops &contours_d = contours[d];
// loop through all contours having depth == d
- for (int i = 0; i < (int)contours_d.size(); ++ i) {
+ for (int i = 0; i < (int)contours_d.size(); ++i) {
const PerimeterGeneratorLoop &loop = contours_d[i];
// find the contour loop that contains it
- for (int t = d - 1; t >= 0; -- t) {
- for (int j = 0; j < contours[t].size(); ++ j) {
+ for (int t = d-1; t >= 0; --t) {
+ for (int j = 0; j < contours[t].size(); ++j) {
PerimeterGeneratorLoop &candidate_parent = contours[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
contours_d.erase(contours_d.begin() + i);
- -- i;
+ --i;
goto NEXT_CONTOUR;
}
}
@@ -188,34 +435,60 @@ void PerimeterGenerator::process()
NEXT_CONTOUR: ;
}
}
- // at this point, all loops should be in contours[0]
- ExtrusionEntityCollection entities = this->_traverse_loops(contours.front(), thin_walls);
+ // at this point, all loops should be in contours[0] (= contours.front() )
+ ExtrusionEntityCollection entities;
+ if (config->perimeter_loop.value) {
+ //onlyone_perimter = >fusion all perimeterLoops
+ for (PerimeterGeneratorLoop &loop : contours.front()) {
+ ExtrusionLoop extr_loop = this->_traverse_and_join_loops(loop, get_all_Childs(loop), loop.polygon.points.front());
+ //ExtrusionLoop extr_loop = this->_traverse_and_join_loops_old(loop, loop.polygon.points.front(), true);
+ extr_loop.paths.back().polyline.points.push_back(extr_loop.paths.front().polyline.points.front());
+ entities.append(extr_loop);
+ }
+
+ // append thin walls
+ if (!thin_walls.empty()) {
+ ExtrusionEntityCollection tw = thin_variable_width
+ (thin_walls, erExternalPerimeter, this->ext_perimeter_flow);
+
+ entities.append(tw.entities);
+ thin_walls.clear();
+ }
+ } else {
+ entities = this->_traverse_loops(contours.front(), thin_walls);
+ }
+
+
// if brim will be printed, reverse the order of perimeters so that
// we continue inwards after having finished the brim
// TODO: add test for perimeter order
if (this->config->external_perimeters_first ||
(this->layer_id == 0 && this->print_config->brim_width.value > 0))
- entities.reverse();
+ entities.reverse();
// append perimeters for this slice as a collection
- if (! entities.empty())
+ if (!entities.empty())
this->loops->append(entities);
} // for each loop of an island
// fill gaps
- if (! gaps.empty()) {
+ if (!gaps.empty()) {
// collapse
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
double max = 2. * perimeter_spacing;
ExPolygons gaps_ex = diff_ex(
- //FIXME offset2 would be enough and cheaper.
offset2_ex(gaps, -min/2, +min/2),
offset2_ex(gaps, -max/2, +max/2),
true);
ThickPolylines polylines;
- for (const ExPolygon &ex : gaps_ex)
- ex.medial_axis(max, min, &polylines);
- if (! polylines.empty()) {
- ExtrusionEntityCollection gap_fill = this->_variable_width(polylines,
+ for (const ExPolygon &ex : gaps_ex) {
+ //remove too small gaps that are too hard to fill.
+ //ie one that are smaller than an extrusion with width of min and a length of max.
+ if (ex.area() > min*max) {
+ ex.medial_axis(ex, max, min, &polylines, this->layer_height);
+ }
+ }
+ if (!polylines.empty()) {
+ ExtrusionEntityCollection gap_fill = thin_variable_width(polylines,
erGapFill, this->solid_infill_flow);
this->gap_fill->append(gap_fill.entities);
/* Make sure we don't infill narrow parts that are already gap-filled
@@ -237,13 +510,15 @@ void PerimeterGenerator::process()
coord_t inset =
(loop_number < 0) ? 0 :
(loop_number == 0) ?
- // one loop
+ // one loop
ext_perimeter_spacing / 2 :
// two or more loops?
perimeter_spacing / 2;
// only apply infill overlap if we actually have one perimeter
- if (inset > 0)
- inset -= scale_(this->config->get_abs_value("infill_overlap", unscale<double>(inset + solid_infill_spacing / 2)));
+ coord_t overlap = 0;
+ if (inset > 0) {
+ overlap = scale_(this->config->get_abs_value("infill_overlap", unscale<double>(inset + solid_infill_spacing / 2)));
+ }
// simplify infill contours according to resolution
Polygons pp;
for (ExPolygon &ex : last)
@@ -251,15 +526,24 @@ void PerimeterGenerator::process()
// collapse too narrow infill areas
coord_t min_perimeter_infill_spacing = solid_infill_spacing * (1. - INSET_OVERLAP_TOLERANCE);
// append infill areas to fill_surfaces
+ //auto it_surf = this->fill_surfaces->surfaces.end();
this->fill_surfaces->append(
offset2_ex(
union_ex(pp),
- - inset - min_perimeter_infill_spacing / 2,
+ -inset - min_perimeter_infill_spacing / 2 + overlap,
min_perimeter_infill_spacing / 2),
- stInternal);
+ stInternal);
+ if (overlap != 0) {
+ ExPolygons polyWithoutOverlap = offset2_ex(
+ union_ex(pp),
+ -inset - min_perimeter_infill_spacing / 2,
+ min_perimeter_infill_spacing / 2);
+ this->fill_no_overlap.insert(this->fill_no_overlap.end(), polyWithoutOverlap.begin(), polyWithoutOverlap.end());
+ }
} // for each island
}
+
ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const
{
@@ -285,7 +569,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
// detect overhanging/bridging perimeters
ExtrusionPaths paths;
if (this->config->overhangs && this->layer_id > 0
- && !(this->object_config->support_material && this->object_config->support_material_contact_distance.value == 0)) {
+ && !(this->object_config->support_material && this->object_config->support_material_contact_distance_type.value == zdNone)) {
// get non-overhang paths by intersecting this loop with the grown lower slices
extrusion_paths_append(
paths,
@@ -324,7 +608,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
// append thin walls to the nearest-neighbor search (only for first iteration)
if (!thin_walls.empty()) {
- ExtrusionEntityCollection tw = this->_variable_width
+ ExtrusionEntityCollection tw = thin_variable_width
(thin_walls, erExternalPerimeter, this->ext_perimeter_flow);
coll.append(tw.entities);
@@ -353,7 +637,10 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls);
if (loop.is_contour) {
- eloop.make_counter_clockwise();
+ if (loop.is_overhang && this->layer_id % 2 == 1)
+ eloop.make_clockwise();
+ else
+ eloop.make_counter_clockwise();
entities.append(children.entities);
entities.append(eloop);
} else {
@@ -366,115 +653,584 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
return entities;
}
-static inline ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, Flow &flow, const float tolerance)
-{
- ExtrusionPaths paths;
- ExtrusionPath path(role);
- ThickLines lines = thick_polyline.thicklines();
-
- for (int i = 0; i < (int)lines.size(); ++i) {
- const ThickLine& line = lines[i];
-
- const coordf_t line_len = line.length();
- if (line_len < SCALED_EPSILON) continue;
-
- double thickness_delta = fabs(line.a_width - line.b_width);
- if (thickness_delta > tolerance) {
- const unsigned short segments = ceil(thickness_delta / tolerance);
- const coordf_t seg_len = line_len / segments;
- Points pp;
- std::vector<coordf_t> width;
- {
- pp.push_back(line.a);
- width.push_back(line.a_width);
- for (size_t j = 1; j < segments; ++j) {
- pp.push_back((line.a.cast<double>() + (line.b - line.a).cast<double>().normalized() * (j * seg_len)).cast<coord_t>());
-
- coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
- width.push_back(w);
- width.push_back(w);
+PerimeterIntersectionPoint
+PerimeterGenerator::_get_nearest_point(const PerimeterGeneratorLoops &children, ExtrusionLoop &myPolylines, const coord_t dist_cut, const coord_t max_dist) const {
+ //find best points of intersections
+ PerimeterIntersectionPoint intersect;
+ intersect.distance = 0x7FFFFFFF; // ! assumption on intersect type & max value
+ intersect.idx_polyline_outter = -1;
+ intersect.idx_children = -1;
+ for (size_t idx_child = 0; idx_child < children.size(); idx_child++) {
+ const PerimeterGeneratorLoop &child = children[idx_child];
+ for (size_t idx_poly = 0; idx_poly < myPolylines.paths.size(); idx_poly++) {
+ if (myPolylines.paths[idx_poly].extruder_id == (unsigned int)-1) continue;
+ if (myPolylines.paths[idx_poly].length() < dist_cut + SCALED_RESOLUTION) continue;
+
+ if ((myPolylines.paths[idx_poly].role() == erExternalPerimeter || child.is_external() )
+ && this->object_config->seam_position.value != SeamPosition::spRandom) {
+ //first, try to find 2 point near enough
+ for (size_t idx_point = 0; idx_point < myPolylines.paths[idx_poly].polyline.points.size(); idx_point++) {
+ const Point &p = myPolylines.paths[idx_poly].polyline.points[idx_point];
+ const Point &nearest_p = *child.polygon.closest_point(p);
+ const double dist = nearest_p.distance_to(p);
+ //Try to find a point in the far side, aligning them
+ if (dist + dist_cut / 20 < intersect.distance ||
+ (config->perimeter_loop_seam.value == spRear && (intersect.idx_polyline_outter <0 || p.y() > intersect.outter_best.y())
+ && dist <= max_dist && intersect.distance + dist_cut / 20)) {
+ //ok, copy the idx
+ intersect.distance = (coord_t)nearest_p.distance_to(p);
+ intersect.idx_children = idx_child;
+ intersect.idx_polyline_outter = idx_poly;
+ intersect.outter_best = p;
+ intersect.child_best = nearest_p;
+ }
+ }
+ } else {
+ //first, try to find 2 point near enough
+ for (size_t idx_point = 0; idx_point < myPolylines.paths[idx_poly].polyline.points.size(); idx_point++) {
+ const Point &p = myPolylines.paths[idx_poly].polyline.points[idx_point];
+ const Point &nearest_p = *child.polygon.closest_point(p);
+ const double dist = nearest_p.distance_to(p);
+ if (dist + SCALED_EPSILON < intersect.distance ||
+ (config->perimeter_loop_seam.value == spRear && (intersect.idx_polyline_outter<0 || p.y() < intersect.outter_best.y())
+ && dist <= max_dist && intersect.distance + dist_cut / 20)) {
+ //ok, copy the idx
+ intersect.distance = (coord_t)nearest_p.distance_to(p);
+ intersect.idx_children = idx_child;
+ intersect.idx_polyline_outter = idx_poly;
+ intersect.outter_best = p;
+ intersect.child_best = nearest_p;
+ }
}
- pp.push_back(line.b);
- width.push_back(line.b_width);
-
- assert(pp.size() == segments + 1);
- assert(width.size() == segments*2);
}
-
- // delete this line and insert new ones
- lines.erase(lines.begin() + i);
- for (size_t j = 0; j < segments; ++j) {
- ThickLine new_line(pp[j], pp[j+1]);
- new_line.a_width = width[2*j];
- new_line.b_width = width[2*j+1];
- lines.insert(lines.begin() + i + j, new_line);
+ }
+ }
+ if (intersect.distance <= max_dist) {
+ return intersect;
+ }
+
+ for (size_t idx_child = 0; idx_child < children.size(); idx_child++) {
+ const PerimeterGeneratorLoop &child = children[idx_child];
+ for (size_t idx_poly = 0; idx_poly < myPolylines.paths.size(); idx_poly++) {
+ if (myPolylines.paths[idx_poly].extruder_id == (unsigned int)-1) continue;
+ if (myPolylines.paths[idx_poly].length() < dist_cut + SCALED_RESOLUTION) continue;
+
+ //second, try to check from one of my points
+ //don't check the last point, as it's used to go outter, can't use it to go inner.
+ for (size_t idx_point = 1; idx_point < myPolylines.paths[idx_poly].polyline.points.size()-1; idx_point++) {
+ const Point &p = myPolylines.paths[idx_poly].polyline.points[idx_point];
+ Point nearest_p = child.polygon.point_projection(p);
+ coord_t dist = (coord_t)nearest_p.distance_to(p);
+ //if no projection, go to next
+ if (dist == 0) continue;
+ //std::cout << " child point " << idx_point << "/" << (myPolylines[idx_poly].me.polyline.points.size() - 1 )<< " dist = " << unscale(dist) << " < ? " << unscale(intersect.distance)<<" \n";
+ if (dist + SCALED_EPSILON / 2 < intersect.distance) {
+ //ok, copy the idx
+ intersect.distance = dist;
+ intersect.idx_children = idx_child;
+ intersect.idx_polyline_outter = idx_poly;
+ intersect.outter_best = p;
+ intersect.child_best = nearest_p;
+ }
}
-
- -- i;
- continue;
}
-
- const double w = fmax(line.a_width, line.b_width);
- if (path.polyline.points.empty()) {
- path.polyline.append(line.a);
- path.polyline.append(line.b);
- // Convert from spacing to extrusion width based on the extrusion model
- // of a square extrusion ended with semi circles.
- flow.width = unscale<float>(w) + flow.height * (1. - 0.25 * PI);
- #ifdef SLIC3R_DEBUG
- printf(" filling %f gap\n", flow.width);
- #endif
- path.mm3_per_mm = flow.mm3_per_mm();
- path.width = flow.width;
- path.height = flow.height;
+ }
+ if (intersect.distance <= max_dist) {
+ return intersect;
+ }
+
+ for (size_t idx_child = 0; idx_child < children.size(); idx_child++) {
+ const PerimeterGeneratorLoop &child = children[idx_child];
+ for (size_t idx_poly = 0; idx_poly < myPolylines.paths.size(); idx_poly++) {
+ if (myPolylines.paths[idx_poly].extruder_id == (unsigned int)-1) continue;
+ if (myPolylines.paths[idx_poly].length() < dist_cut + SCALED_RESOLUTION) continue;
+
+ //lastly, try to check from one of his points
+ for (size_t idx_point = 0; idx_point < child.polygon.points.size(); idx_point++) {
+ const Point &p = child.polygon.points[idx_point];
+ Point nearest_p = myPolylines.paths[idx_poly].polyline.point_projection(p);
+ coord_t dist = (coord_t)nearest_p.distance_to(p);
+ //if no projection, go to next
+ if (dist == 0) continue;
+ //if (nearest_p.coincides_with_epsilon(myPolylines.paths[idx_poly].polyline.points.back())) {
+ // Line segment(*(myPolylines.paths[idx_poly].polyline.points.end() - 2), myPolylines.paths[idx_poly].polyline.points.back());
+ // dist = (coord_t)segment.point_at(segment.length() - dist_cut).distance_to(p);
+ //}
+ //std::cout << " my point " << idx_point << " dist=" << unscale(dist) << " <? " << unscale(intersect.distance) << " \n";
+ if (dist + SCALED_EPSILON / 2 < intersect.distance) {
+ //ok, copy the idx
+ intersect.distance = dist;
+ intersect.idx_children = idx_child;
+ intersect.idx_polyline_outter = idx_poly;
+ intersect.outter_best = nearest_p;
+ intersect.child_best = p;
+ }
+ }
+ }
+ }
+ return intersect;
+}
+
+
+ExtrusionLoop
+PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entry_point, const Line &direction) const
+{
+
+ bool need_to_reverse = false;
+ Polyline initial_polyline;
+ const coord_t dist_cut = (coord_t)scale_(this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder - 1));
+
+
+ if (loop.polygon.points.size() < 3) return ExtrusionLoop(elrDefault);
+ if (loop.polygon.length() < dist_cut * 2) {
+ ExtrusionLoop single_point(elrDefault);
+ Polyline poly_point;
+ poly_point.append(loop.polygon.centroid());
+ single_point.paths.emplace_back(
+ loop.is_external() ? erExternalPerimeter : erPerimeter,
+ (double)(loop.is_external() ? this->_ext_mm3_per_mm : this->_mm3_per_mm),
+ (float)(loop.is_external() ? this->ext_perimeter_flow.width : this->perimeter_flow.width),
+ (float)(this->layer_height));
+ single_point.paths.back().polyline = poly_point;
+ return single_point;
+ }
+ //std::cout << "idx_closest_from_entry_point : " << loop.polygon.closest_point_index(entry_point) << "/" << loop.polygon.points.size()<<"\n";
+ const size_t idx_closest_from_entry_point = loop.polygon.closest_point_index(entry_point);
+ //std::cout << "loop.polygon.points[idx_closest_from_entry_point].distance_to(entry_point) : " << unscale(loop.polygon.points[idx_closest_from_entry_point].distance_to(entry_point)) << "\n";
+ if (loop.polygon.points[idx_closest_from_entry_point].distance_to(entry_point) > SCALED_EPSILON) {
+ //create new Point
+ //get first point
+ size_t idx_before = -1;
+ for (size_t idx_p_a = 0; idx_p_a < loop.polygon.points.size(); ++idx_p_a) {
+ Line l(loop.polygon.points[idx_p_a], loop.polygon.points[(idx_p_a + 1 == loop.polygon.points.size()) ? 0 : (idx_p_a + 1)]);
+ if (entry_point.distance_to(l) < SCALED_EPSILON) {
+ idx_before = idx_p_a;
+ break;
+ }
+ }
+ if (idx_before == (size_t)-1) std::cout << "ERROR: _traverse_and_join_loops : idx_before can't be finded to create new point\n";
+ initial_polyline = loop.polygon.split_at_index(idx_before);
+ initial_polyline.points.push_back(entry_point);
+ initial_polyline.points[0] = entry_point;
+ } else {
+ initial_polyline = loop.polygon.split_at_index(idx_closest_from_entry_point);
+ }
+
+
+ //std::vector<PerimeterPolylineNode> myPolylines;
+ ExtrusionLoop my_loop;
+
+ //overhang / notoverhang
+ {
+ bool is_external = loop.is_external();
+
+ ExtrusionRole role;
+ ExtrusionLoopRole loop_role;
+ role = is_external ? erExternalPerimeter : erPerimeter;
+ if (loop.is_internal_contour()) {
+ // Note that we set loop role to ContourInternalPerimeter
+ // also when loop is both internal and external (i.e.
+ // there's only one contour loop).
+ loop_role = elrContourInternalPerimeter;
} else {
- thickness_delta = fabs(scale_(flow.width) - w);
- if (thickness_delta <= tolerance) {
- // the width difference between this line and the current flow width is
- // within the accepted tolerance
- path.polyline.append(line.b);
- } else {
- // we need to initialize a new line
- paths.emplace_back(std::move(path));
- path = ExtrusionPath(role);
- -- i;
+ loop_role = elrDefault;
+ }
+
+ // detect overhanging/bridging perimeters
+ if (this->config->overhangs && this->layer_id > 0
+ && !(this->object_config->support_material && this->object_config->support_material_contact_distance_type.value == zdNone)) {
+ ExtrusionPaths paths;
+ // get non-overhang paths by intersecting this loop with the grown lower slices
+ extrusion_paths_append(
+ paths,
+ intersection_pl(initial_polyline, this->_lower_slices_p),
+ role,
+ is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm,
+ is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width,
+ this->layer_height);
+
+ // get overhang paths by checking what parts of this loop fall
+ // outside the grown lower slices (thus where the distance between
+ // the loop centerline and original lower slices is >= half nozzle diameter
+ extrusion_paths_append(
+ paths,
+ diff_pl(initial_polyline, this->_lower_slices_p),
+ erOverhangPerimeter,
+ this->_mm3_per_mm_overhang,
+ this->overhang_flow.width,
+ this->overhang_flow.height);
+
+ // reapply the nearest point search for starting point
+ // We allow polyline reversal because Clipper may have randomly
+ // reversed polylines during clipping.
+ paths = (ExtrusionPaths)ExtrusionEntityCollection(paths).chained_path();
+
+
+ if (direction.length() > 0) {
+ Polyline direction_polyline;
+ for (ExtrusionPath &path : paths) {
+ direction_polyline.points.insert(direction_polyline.points.end(), path.polyline.points.begin(), path.polyline.points.end());
+ }
+ direction_polyline.clip_start(SCALED_RESOLUTION);
+ direction_polyline.clip_end(SCALED_RESOLUTION);
+ coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
+ need_to_reverse = dot>0;
+ }
+ if (need_to_reverse) {
+ std::reverse(paths.begin(), paths.end());
+ }
+ //search for the first path
+ size_t good_idx = 0;
+ for (size_t idx_path = 0; idx_path < paths.size(); idx_path++) {
+ const ExtrusionPath &path = paths[idx_path];
+ if (need_to_reverse) {
+ if (path.polyline.points.back().coincides_with_epsilon(initial_polyline.points.front())) {
+ good_idx = idx_path;
+ break;
+ }
+ } else {
+ if (path.polyline.points.front().coincides_with_epsilon(initial_polyline.points.front())) {
+ good_idx = idx_path;
+ break;
+ }
+ }
+ }
+ for (size_t idx_path = good_idx; idx_path < paths.size(); idx_path++) {
+ ExtrusionPath &path = paths[idx_path];
+ if (need_to_reverse) path.reverse();
+ my_loop.paths.emplace_back(path);
}
+ for (size_t idx_path = 0; idx_path < good_idx; idx_path++) {
+ ExtrusionPath &path = paths[idx_path];
+ if (need_to_reverse) path.reverse();
+ my_loop.paths.emplace_back(path);
+ }
+ } else {
+
+ if (direction.length() > 0) {
+ Polyline direction_polyline = initial_polyline;
+ direction_polyline.clip_start(SCALED_RESOLUTION);
+ direction_polyline.clip_end(SCALED_RESOLUTION);
+ coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
+ need_to_reverse = dot>0;
+ }
+
+ ExtrusionPath path(role);
+ path.polyline = initial_polyline;
+ if (need_to_reverse) path.polyline.reverse();
+ path.mm3_per_mm = is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm;
+ path.width = is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width;
+ path.height = (float)(this->layer_height);
+ my_loop.paths.emplace_back(path);
}
+
}
- if (path.polyline.is_valid())
- paths.emplace_back(std::move(path));
- return paths;
+
+ return my_loop;
}
-ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
+ExtrusionLoop
+PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop, const PerimeterGeneratorLoops &children, const Point entry_point) const
{
- // This value determines granularity of adaptive width, as G-code does not allow
- // variable extrusion within a single move; this value shall only affect the amount
- // of segments, and any pruning shall be performed before we apply this tolerance.
- ExtrusionEntityCollection coll;
- const double tolerance = scale_(0.05);
- for (const ThickPolyline &p : polylines) {
- ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance);
- // Append paths to collection.
- if (! paths.empty()) {
- if (paths.front().first_point() == paths.back().last_point())
- coll.append(ExtrusionLoop(std::move(paths)));
- else
- coll.append(std::move(paths));
+ //std::cout << " === ==== _traverse_and_join_loops ==== ===\n";
+ // other perimeters
+ //this->_mm3_per_mm = this->perimeter_flow.mm3_per_mm();
+ //coord_t perimeter_width = this->perimeter_flow.scaled_width();
+ const coord_t perimeter_spacing = this->perimeter_flow.scaled_spacing();
+
+ //// external perimeters
+ //this->_ext_mm3_per_mm = this->ext_perimeter_flow.mm3_per_mm();
+ //coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
+ const coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
+ //coord_t ext_perimeter_spacing2 = this->ext_perimeter_flow.scaled_spacing(this->perimeter_flow);
+
+ //const coord_t dist_cut = (coord_t)scale_(this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder - 1));
+ //TODO change this->external_perimeter_flow.scaled_width() if it's the first one!
+ const coord_t max_width_extrusion = this->perimeter_flow.scaled_width();
+ ExtrusionLoop my_loop = _extrude_and_cut_loop(loop, entry_point);
+
+ int child_idx = 0;
+ //Polylines myPolylines = { myPolyline };
+ //iterate on each point ot find the best place to go into the child
+ vector<PerimeterGeneratorLoop> childs = children;
+ while (!childs.empty()) {
+ child_idx++;
+ PerimeterIntersectionPoint nearest = this->_get_nearest_point(childs, my_loop, this->perimeter_flow.scaled_width(), this->perimeter_flow.scaled_width()* 1.42);
+ if (nearest.idx_children == (size_t)-1) {
+ //return ExtrusionEntityCollection();
+ break;
+ } else {
+ const PerimeterGeneratorLoop &child = childs[nearest.idx_children];
+ //std::cout << "c." << child_idx << " === i have " << my_loop.paths.size() << " paths" << " == cut_path_is_ccw size " << path_is_ccw.size() << "\n";
+ //std::cout << "change to child " << nearest.idx_children << " @ " << unscale(nearest.outter_best.x) << ":" << unscale(nearest.outter_best.y)
+ // << ", idxpolyline = " << nearest.idx_polyline_outter << "\n";
+ //PerimeterGeneratorLoops less_childs = childs;
+ //less_childs.erase(less_childs.begin() + nearest.idx_children);
+ //create new node with recursive ask for the inner perimeter & COPY of the points, ready to be cut
+ my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, my_loop.paths[nearest.idx_polyline_outter]);
+
+ ExtrusionPath *outer_start = &my_loop.paths[nearest.idx_polyline_outter];
+ ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
+ Line deletedSection;
+
+ //cut our polyline
+ //separate them
+ size_t nearest_idx_outter = outer_start->polyline.closest_point_index(nearest.outter_best);
+ if (outer_start->polyline.points[nearest_idx_outter].coincides_with_epsilon(nearest.outter_best)) {
+ if (nearest_idx_outter < outer_start->polyline.points.size() - 1) {
+ outer_start->polyline.points.erase(outer_start->polyline.points.begin() + nearest_idx_outter + 1, outer_start->polyline.points.end());
+ }
+ if (nearest_idx_outter > 0) {
+ outer_end->polyline.points.erase(outer_end->polyline.points.begin(), outer_end->polyline.points.begin() + nearest_idx_outter);
+ }
+ } else {
+ //get first point
+ size_t idx_before = -1;
+ for (size_t idx_p_a = 0; idx_p_a < outer_start->polyline.points.size() - 1; ++idx_p_a) {
+ Line l(outer_start->polyline.points[idx_p_a], outer_start->polyline.points[idx_p_a + 1]);
+ if (nearest.outter_best.distance_to(l) < SCALED_EPSILON) {
+ idx_before = idx_p_a;
+ break;
+ }
+ }
+ if (idx_before == (size_t)-1) {
+ std::cout << "ERROR: idx_before can't be finded\n";
+ continue;
+ }
+
+ Points &my_polyline_points = outer_start->polyline.points;
+ my_polyline_points.erase(my_polyline_points.begin() + idx_before + 1, my_polyline_points.end());
+ my_polyline_points.push_back(nearest.outter_best);
+
+ if (idx_before < outer_end->polyline.points.size()-1)
+ outer_end->polyline.points.erase(outer_end->polyline.points.begin(), outer_end->polyline.points.begin() + idx_before + 1);
+ else
+ outer_end->polyline.points.erase(outer_end->polyline.points.begin()+1, outer_end->polyline.points.end());
+ outer_end->polyline.points.insert(outer_end->polyline.points.begin(), nearest.outter_best);
+ }
+ Polyline to_reduce = outer_start->polyline;
+ if (to_reduce.points.size()>1) to_reduce.clip_end(SCALED_RESOLUTION);
+ deletedSection.a = to_reduce.points.back();
+ to_reduce = outer_end->polyline;
+ if (to_reduce.points.size()>1) to_reduce.clip_start(SCALED_RESOLUTION);
+ deletedSection.b = to_reduce.points.front();
+
+ //get the inner loop to connect to us.
+ ExtrusionLoop child_loop = _extrude_and_cut_loop(child, nearest.child_best, deletedSection);
+
+ const coord_t inner_child_spacing = child.is_external() ? ext_perimeter_spacing : perimeter_spacing;
+ const coord_t outer_start_spacing = scale_(outer_start->width - outer_start->height * (1. - 0.25 * PI));
+ const coord_t outer_end_spacing = scale_(outer_end->width - outer_end->height * (1. - 0.25 * PI));
+
+ //FIXME: if child_loop has no point or 1 point or not enough space !!!!!!!
+ const size_t child_paths_size = child_loop.paths.size();
+ if (child_paths_size == 0) continue;
+ my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, child_loop.paths.begin(), child_loop.paths.end());
+
+ //add paths into my_loop => need to re-get the refs
+ outer_start = &my_loop.paths[nearest.idx_polyline_outter];
+ outer_end = &my_loop.paths[nearest.idx_polyline_outter + child_paths_size + 1];
+ ExtrusionPath *inner_start = &my_loop.paths[nearest.idx_polyline_outter+1];
+ ExtrusionPath *inner_end = &my_loop.paths[nearest.idx_polyline_outter + child_paths_size];
+ //TRIM
+ //choose trim direction
+ if (outer_start->polyline.points.size() == 1 && outer_end->polyline.points.size() == 1) {
+ //do nothing
+ } else if (outer_start->polyline.points.size() == 1) {
+ outer_end->polyline.clip_start(outer_end_spacing);
+ if (inner_end->polyline.length() > inner_child_spacing)
+ inner_end->polyline.clip_end(inner_child_spacing);
+ else
+ inner_end->polyline.clip_end(inner_end->polyline.length() / 2);
+ } else if (outer_end->polyline.points.size() == 1) {
+ outer_start->polyline.clip_end(outer_start_spacing);
+ if (inner_start->polyline.length() > inner_child_spacing)
+ inner_start->polyline.clip_start(inner_child_spacing);
+ else
+ inner_start->polyline.clip_start(inner_start->polyline.length()/2);
+ } else {
+ double length_poly_1 = outer_start->polyline.length();
+ double length_poly_2 = outer_end->polyline.length();
+ coord_t length_trim_1 = outer_start_spacing / 2;
+ coord_t length_trim_2 = outer_end_spacing / 2;
+ if (length_poly_1 < length_trim_1) {
+ length_trim_2 = length_trim_1 + length_trim_2 - length_poly_1;
+ }
+ if (length_poly_2 < length_trim_1) {
+ length_trim_1 = length_trim_1 + length_trim_2 - length_poly_2;
+ }
+ if (length_poly_1 > length_trim_1) {
+ outer_start->polyline.clip_end(length_trim_1);
+ } else {
+ outer_start->polyline.points.erase(outer_start->polyline.points.begin() + 1, outer_start->polyline.points.end());
+ }
+ if (length_poly_2 > length_trim_2) {
+ outer_end->polyline.clip_start(length_trim_2);
+ } else {
+ outer_end->polyline.points.erase(outer_end->polyline.points.begin(), outer_end->polyline.points.end() - 1);
+ }
+
+ length_poly_1 = inner_start->polyline.length();
+ length_poly_2 = inner_end->polyline.length();
+ length_trim_1 = inner_child_spacing / 2;
+ length_trim_2 = inner_child_spacing / 2;
+ if (length_poly_1 < length_trim_1) {
+ length_trim_2 = length_trim_1 + length_trim_2 - length_poly_1;
+ }
+ if (length_poly_2 < length_trim_1) {
+ length_trim_1 = length_trim_1 + length_trim_2 - length_poly_2;
+ }
+ if (length_poly_1 > length_trim_1) {
+ inner_start->polyline.clip_start(length_trim_1);
+ } else {
+ inner_start->polyline.points.erase(
+ inner_start->polyline.points.begin(),
+ inner_start->polyline.points.end() - 1);
+ }
+ if (length_poly_2 > length_trim_2) {
+ inner_end->polyline.clip_end(length_trim_2);
+ } else {
+ inner_end->polyline.points.erase(
+ inner_end->polyline.points.begin() + 1,
+ inner_end->polyline.points.end());
+ }
+ }
+
+ //last check to see if we need a reverse
+ {
+ Line l1(outer_start->polyline.points.back(), inner_start->polyline.points.front());
+ Line l2(inner_end->polyline.points.back(), outer_end->polyline.points.front());
+ Point p_inter(0, 0);
+ bool is_interect = l1.intersection(l2, &p_inter);
+ if (is_interect && p_inter.distance_to(l1) < SCALED_EPSILON && p_inter.distance_to(l2) < SCALED_EPSILON) {
+ //intersection! need to reverse!
+ std::reverse(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, my_loop.paths.begin() + nearest.idx_polyline_outter + child_paths_size + 1);
+ for (size_t idx = nearest.idx_polyline_outter + 1; idx < nearest.idx_polyline_outter + child_paths_size + 1; idx++) {
+ my_loop.paths[idx].reverse();
+ }
+ outer_start = &my_loop.paths[nearest.idx_polyline_outter];
+ inner_start = &my_loop.paths[nearest.idx_polyline_outter + 1];
+ inner_end = &my_loop.paths[nearest.idx_polyline_outter + child_paths_size];
+ outer_end = &my_loop.paths[nearest.idx_polyline_outter + child_paths_size + 1];
+ }
+
+ }
+
+ //now add extrusionPAths to connect the two loops
+ ExtrusionPaths travel_path_begin;// (ExtrusionRole::erNone, 0, outer_start->width, outer_start->height);
+ //travel_path_begin.extruder_id = -1;
+ ExtrusionPaths travel_path_end;// (ExtrusionRole::erNone, 0, outer_end->width, outer_end->height);
+ //travel_path_end.extruder_id = -1;
+ double dist_travel = outer_start->polyline.points.back().distance_to(inner_start->polyline.points.front());
+ if (dist_travel > max_width_extrusion*1.5 && this->config->fill_density.value > 0) {
+ travel_path_begin.emplace_back(ExtrusionRole::erPerimeter, outer_start->mm3_per_mm, outer_start->width, outer_start->height);
+ travel_path_begin.emplace_back(ExtrusionRole::erNone, 0, outer_start->width, outer_start->height);
+ travel_path_begin.emplace_back(ExtrusionRole::erPerimeter, outer_start->mm3_per_mm, outer_start->width, outer_start->height);
+ travel_path_begin[0].extruder_id = -1;
+ travel_path_begin[1].extruder_id = -1;
+ travel_path_begin[2].extruder_id = -1;
+ Line line(outer_start->polyline.points.back(), inner_start->polyline.points.front());
+ Point p_dist_cut_extrude = (line.b - line.a);
+ p_dist_cut_extrude.x() = (coord_t)(p_dist_cut_extrude.x() * ((double)max_width_extrusion) / (line.length() * 2));
+ p_dist_cut_extrude.y() = (coord_t)(p_dist_cut_extrude.y() * ((double)max_width_extrusion) / (line.length() * 2));
+ //extrude a bit after the turn, to close the loop
+ Point p_start_travel = line.a;
+ p_start_travel += p_dist_cut_extrude;
+ travel_path_begin[0].polyline.append(outer_start->polyline.points.back());
+ travel_path_begin[0].polyline.append(p_start_travel);
+ //extrude a bit before the final turn, to close the loop
+ Point p_end_travel = line.b;
+ p_end_travel -= p_dist_cut_extrude;
+ travel_path_begin[2].polyline.append(p_end_travel);
+ travel_path_begin[2].polyline.append(inner_start->polyline.points.front());
+ //fake travel in the middle
+ travel_path_begin[1].polyline.append(p_start_travel);
+ travel_path_begin[1].polyline.append(p_end_travel);
+ } else {
+ // the path is small enough to extrude all along.
+ double flow_mult = 1;
+ if (dist_travel > max_width_extrusion && this->config->fill_density.value > 0) {
+ // the path is a bit too long, reduce the extrusion flow.
+ flow_mult = max_width_extrusion / dist_travel;
+ }
+ travel_path_begin.emplace_back(ExtrusionRole::erPerimeter, outer_start->mm3_per_mm * flow_mult, (float)(outer_start->width * flow_mult), outer_start->height);
+ travel_path_begin[0].extruder_id = -1;
+ travel_path_begin[0].polyline.append(outer_start->polyline.points.back());
+ travel_path_begin[0].polyline.append(inner_start->polyline.points.front());
+ }
+ dist_travel = inner_end->polyline.points.back().distance_to(outer_end->polyline.points.front());
+ if (dist_travel > max_width_extrusion*1.5 && this->config->fill_density.value > 0) {
+ travel_path_end.emplace_back(ExtrusionRole::erPerimeter, outer_end->mm3_per_mm, outer_end->width, outer_end->height);
+ travel_path_end.emplace_back(ExtrusionRole::erNone, 0, outer_end->width, outer_end->height);
+ travel_path_end.emplace_back(ExtrusionRole::erPerimeter, outer_end->mm3_per_mm, outer_end->width, outer_end->height);
+ travel_path_end[0].extruder_id = -1;
+ travel_path_end[1].extruder_id = -1;
+ travel_path_end[2].extruder_id = -1;
+ Line line(inner_end->polyline.points.back(), outer_end->polyline.points.front());
+ Point p_dist_cut_extrude = (line.b - line.a);
+ p_dist_cut_extrude.x() = (coord_t)(p_dist_cut_extrude.x() * ((double)max_width_extrusion) / (line.length() * 2));
+ p_dist_cut_extrude.y() = (coord_t)(p_dist_cut_extrude.y() * ((double)max_width_extrusion) / (line.length() * 2));
+ //extrude a bit after the turn, to close the loop
+ Point p_start_travel_2 = line.a;
+ p_start_travel_2 += p_dist_cut_extrude;
+ travel_path_end[0].polyline.append(inner_end->polyline.points.back());
+ travel_path_end[0].polyline.append(p_start_travel_2);
+ //extrude a bit before the final turn, to close the loop
+ Point p_end_travel_2 = line.b;
+ p_end_travel_2 -= p_dist_cut_extrude;
+ travel_path_end[2].polyline.append(p_end_travel_2);
+ travel_path_end[2].polyline.append(outer_end->polyline.points.front());
+ //fake travel in the middle
+ travel_path_end[1].polyline.append(p_start_travel_2);
+ travel_path_end[1].polyline.append(p_end_travel_2);
+ } else {
+ // the path is small enough to extrude all along.
+ double flow_mult = 1;
+ if (dist_travel > max_width_extrusion && this->config->fill_density.value > 0) {
+ // the path is a bit too long, reduce the extrusion flow.
+ flow_mult = max_width_extrusion / dist_travel;
+ }
+ travel_path_end.emplace_back(ExtrusionRole::erPerimeter, outer_end->mm3_per_mm * flow_mult, (float)(outer_end->width * flow_mult), outer_end->height);
+ travel_path_end[0].extruder_id = -1;
+ travel_path_end[0].polyline.append(inner_end->polyline.points.back());
+ travel_path_end[0].polyline.append(outer_end->polyline.points.front());
+ }
+ //check if we add path or reuse bits
+ //FIXME
+ /*if (outer_start->polyline.points.size() == 1) {
+ outer_start->polyline = travel_path_begin.front().polyline;
+ travel_path_begin.erase(travel_path_begin.begin());
+ outer_start->extruder_id = -1;
+ } else if (outer_end->polyline.points.size() == 1) {
+ outer_end->polyline = travel_path_end.back().polyline;
+ travel_path_end.erase(travel_path_end.end() - 1);
+ outer_end->extruder_id = -1;
+ }*/
+ //add paths into my_loop => after that all ref are wrong!
+ for (int i = travel_path_end.size() - 1; i >= 0; i--) {
+ my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + child_paths_size + 1, travel_path_end[i]);
+ }
+ for (int i = travel_path_begin.size() - 1; i >= 0; i--) {
+ my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, travel_path_begin[i]);
+ }
}
+
+ //update for next loop
+ childs.erase(childs.begin() + nearest.idx_children);
}
- return coll;
+
+ return my_loop;
}
bool PerimeterGeneratorLoop::is_internal_contour() const
{
// An internal contour is a contour containing no other contours
if (! this->is_contour)
- return false;
+ return false;
for (const PerimeterGeneratorLoop &loop : this->children)
if (loop.is_contour)
return false;
- return true;
-}
+ return true;
+ }
}
diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp
index 44af8c8be..7b7457e8c 100644
--- a/src/libslic3r/PerimeterGenerator.hpp
+++ b/src/libslic3r/PerimeterGenerator.hpp
@@ -8,9 +8,18 @@
#include "Polygon.hpp"
#include "PrintConfig.hpp"
#include "SurfaceCollection.hpp"
+#include "ExtrusionEntityCollection.hpp"
namespace Slic3r {
+struct PerimeterIntersectionPoint {
+ size_t idx_children;
+ Point child_best;
+ Point outter_best;
+ size_t idx_polyline_outter;
+ coord_t distance;
+};
+
// Hierarchy of perimeters.
class PerimeterGeneratorLoop {
public:
@@ -19,13 +28,18 @@ public:
// Is it a contour or a hole?
// Contours are CCW oriented, holes are CW oriented.
bool is_contour;
+ //overhang may need to be reversed
+ bool is_overhang;
// Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole.
unsigned short depth;
// Children contour, may be both CCW and CW oriented (outer contours or holes).
std::vector<PerimeterGeneratorLoop> children;
-
- PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) :
- polygon(polygon), is_contour(is_contour), depth(depth) {}
+
+
+ PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) :
+ polygon(polygon), is_contour(is_contour), depth(depth), is_overhang(false) {}
+ PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour, bool is_overhang) :
+ polygon(polygon), is_contour(is_contour), depth(depth), is_overhang(is_overhang) {}
// External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
bool is_external() const { return this->depth == 0; }
// An island, which may have holes, but it does not have another internal island.
@@ -38,6 +52,7 @@ class PerimeterGenerator {
public:
// Inputs:
const SurfaceCollection *slices;
+ const ExPolygonCollection *upper_slices;
const ExPolygonCollection *lower_slices;
double layer_height;
int layer_id;
@@ -52,6 +67,7 @@ public:
ExtrusionEntityCollection *loops;
ExtrusionEntityCollection *gap_fill;
SurfaceCollection *fill_surfaces;
+ ExPolygons fill_no_overlap;
PerimeterGenerator(
// Input:
@@ -68,7 +84,7 @@ public:
ExtrusionEntityCollection* gap_fill,
// Infills without the gap fills
SurfaceCollection* fill_surfaces)
- : slices(slices), lower_slices(NULL), layer_height(layer_height),
+ : slices(slices), lower_slices(NULL), upper_slices(NULL), layer_height(layer_height),
layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow),
overhang_flow(flow), solid_infill_flow(flow),
config(config), object_config(object_config), print_config(print_config),
@@ -82,9 +98,11 @@ private:
double _mm3_per_mm;
double _mm3_per_mm_overhang;
Polygons _lower_slices_p;
-
+
ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const;
- ExtrusionEntityCollection _variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const;
+ ExtrusionLoop _traverse_and_join_loops(const PerimeterGeneratorLoop &loop, const PerimeterGeneratorLoops &childs, const Point entryPoint) const;
+ ExtrusionLoop _extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entryPoint, const Line &direction = Line(Point(0,0),Point(0,0))) const;
+ PerimeterIntersectionPoint _get_nearest_point(const PerimeterGeneratorLoops &children, ExtrusionLoop &myPolylines, const coord_t dist_cut, const coord_t max_dist) const;
};
}
diff --git a/src/libslic3r/Point.cpp b/src/libslic3r/Point.cpp
index c2417d0dc..0e0b6e0ad 100644
--- a/src/libslic3r/Point.cpp
+++ b/src/libslic3r/Point.cpp
@@ -100,6 +100,29 @@ int Point::nearest_point_index(const PointConstPtrs &points) const
return idx;
}
+/* distance to the closest point of line */
+double
+Point::distance_to(const Line &line) const {
+ const double dx = line.b.x() - line.a.x();
+ const double dy = line.b.y() - line.a.y();
+
+ const double l2 = dx*dx + dy*dy; // avoid a sqrt
+ if (l2 == 0.0) return this->distance_to(line.a); // line.a == line.b case
+
+ // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
+ // We find projection of this point onto the line.
+ // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
+ const double t = ((this->x() - line.a.x()) * dx + (this->y() - line.a.y()) * dy) / l2;
+ if (t < 0.0) return this->distance_to(line.a); // beyond the 'a' end of the segment
+ else if (t > 1.0) return this->distance_to(line.b); // beyond the 'b' end of the segment
+ Point projection(
+ line.a.x() + t * dx,
+ line.a.y() + t * dy
+ );
+ return this->distance_to(projection);
+}
+
+
int Point::nearest_point_index(const PointPtrs &points) const
{
PointConstPtrs p;
diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp
index d456fb9c6..1be14fc59 100644
--- a/src/libslic3r/Point.hpp
+++ b/src/libslic3r/Point.hpp
@@ -51,6 +51,9 @@ inline coord_t cross2(const Vec2crd &v1, const Vec2crd &v2) { return v1(0) * v2(
inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline coordf_t dot(const Vec2d &v1, const Vec2d &v2) { return v1.x() * v2.x() + v1.y() * v2.y(); }
+inline coordf_t dot(const Vec2d &v) { return v.x() * v.x() + v.y() * v.y(); }
+
inline Vec2crd to_2d(const Vec3crd &pt3) { return Vec2crd(pt3(0), pt3(1)); }
inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); }
inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); }
@@ -118,6 +121,18 @@ public:
double ccw_angle(const Point &p1, const Point &p2) const;
Point projection_onto(const MultiPoint &poly) const;
Point projection_onto(const Line &line) const;
+
+ double distance_to(const Point &point) const { return (point - *this).cast<double>().norm(); }
+ double distance_to_square(const Point &point) const {
+ double dx = (point.x() - this->x());
+ double dy = (point.y() - this->y());
+ return dx*dx + dy*dy;
+ }
+ double distance_to(const Line &line) const;
+ bool coincides_with(const Point &point) const { return this->x() == point.x() && this->y() == point.y(); }
+ bool coincides_with_epsilon(const Point &point) const {
+ return std::abs(this->x() - point.x()) < SCALED_EPSILON && std::abs(this->y() - point.y()) < SCALED_EPSILON;
+ }
};
namespace int128 {
diff --git a/src/libslic3r/Polyline.cpp b/src/libslic3r/Polyline.cpp
index af155468a..424f0c0d4 100644
--- a/src/libslic3r/Polyline.cpp
+++ b/src/libslic3r/Polyline.cpp
@@ -6,6 +6,7 @@
#include "Polygon.hpp"
#include <iostream>
#include <utility>
+#include <algorithm>
namespace Slic3r {
@@ -233,8 +234,12 @@ ThickLines ThickPolyline::thicklines() const
ThickLines lines;
if (this->points.size() >= 2) {
lines.reserve(this->points.size() - 1);
- for (size_t i = 0; i + 1 < this->points.size(); ++ i)
- lines.emplace_back(this->points[i], this->points[i + 1], this->width[2 * i], this->width[2 * i + 1]);
+ for (size_t i = 0; i < this->points.size() - 1; ++i) {
+ ThickLine line(this->points[i], this->points[i + 1]);
+ line.a_width = this->width[i];
+ line.b_width = this->width[i + 1];
+ lines.push_back(line);
+ }
}
return lines;
}
@@ -253,4 +258,102 @@ Lines3 Polyline3::lines() const
return lines;
}
+void concatThickPolylines(ThickPolylines& pp) {
+ bool changes = true;
+ while (changes){
+ changes = false;
+ //concat polyline if only 2 polyline at a point
+ for (size_t i = 0; i < pp.size(); ++i) {
+ ThickPolyline *polyline = &pp[i];
+ if (polyline->first_point().coincides_with(polyline->last_point())) {
+ polyline->endpoints.first = false;
+ polyline->endpoints.second = false;
+ continue;
+ }
+
+ size_t id_candidate_first_point = -1;
+ size_t id_candidate_last_point = -1;
+ size_t nbCandidate_first_point = 0;
+ size_t nbCandidate_last_point = 0;
+ // find another polyline starting here
+ for (size_t j = 0; j < pp.size(); ++j) {
+ if (j == i) continue;
+ ThickPolyline *other = &pp[j];
+ if (other->first_point().coincides_with(other->last_point())) continue;
+ if (polyline->last_point().coincides_with(other->last_point())) {
+ id_candidate_last_point = j;
+ nbCandidate_last_point++;
+ }
+ if (polyline->last_point().coincides_with(other->first_point())) {
+ id_candidate_last_point = j;
+ nbCandidate_last_point++;
+ }
+ if (polyline->first_point().coincides_with(other->last_point())) {
+ id_candidate_first_point = j;
+ nbCandidate_first_point++;
+ }
+ if (polyline->first_point().coincides_with(other->first_point())) {
+ id_candidate_first_point = j;
+ nbCandidate_first_point++;
+ }
+ }
+ if (id_candidate_last_point == id_candidate_first_point && nbCandidate_first_point == 1 && nbCandidate_last_point == 1) {
+ if (polyline->first_point().coincides_with(pp[id_candidate_first_point].first_point())) pp[id_candidate_first_point].reverse();
+ // it's a trap! it's a loop!
+ polyline->points.insert(polyline->points.end(), pp[id_candidate_first_point].points.begin() + 1, pp[id_candidate_first_point].points.end());
+ polyline->width.insert(polyline->width.end(), pp[id_candidate_first_point].width.begin() + 1, pp[id_candidate_first_point].width.end());
+ pp.erase(pp.begin() + id_candidate_first_point);
+ changes = true;
+ polyline->endpoints.first = false;
+ polyline->endpoints.second = false;
+ } else {
+
+ if (nbCandidate_first_point == 1) {
+ if (polyline->first_point().coincides_with(pp[id_candidate_first_point].first_point())) pp[id_candidate_first_point].reverse();
+ //concat at front
+ polyline->width[0] = std::max(polyline->width.front(), pp[id_candidate_first_point].width.back());
+ polyline->points.insert(polyline->points.begin(), pp[id_candidate_first_point].points.begin(), pp[id_candidate_first_point].points.end() - 1);
+ polyline->width.insert(polyline->width.begin(), pp[id_candidate_first_point].width.begin(), pp[id_candidate_first_point].width.end() - 1);
+ polyline->endpoints.first = pp[id_candidate_first_point].endpoints.first;
+ pp.erase(pp.begin() + id_candidate_first_point);
+ changes = true;
+ if (id_candidate_first_point < i) {
+ i--;
+ polyline = &pp[i];
+ }
+ if (id_candidate_last_point > id_candidate_first_point) {
+ id_candidate_last_point--;
+ }
+ } else if (nbCandidate_first_point == 0) {
+ //update endpoint
+ polyline->endpoints.first = true;
+ }
+ if (nbCandidate_last_point == 1) {
+ if (polyline->last_point().coincides_with(pp[id_candidate_last_point].last_point())) pp[id_candidate_last_point].reverse();
+ //concat at back
+ polyline->width[polyline->width.size() - 1] = std::max(polyline->width.back(), pp[id_candidate_last_point].width.front());
+ polyline->points.insert(polyline->points.end(), pp[id_candidate_last_point].points.begin() + 1, pp[id_candidate_last_point].points.end());
+ polyline->width.insert(polyline->width.end(), pp[id_candidate_last_point].width.begin() + 1, pp[id_candidate_last_point].width.end());
+ polyline->endpoints.second = pp[id_candidate_last_point].endpoints.second;
+ pp.erase(pp.begin() + id_candidate_last_point);
+ changes = true;
+ if (id_candidate_last_point < i) {
+ i--;
+ polyline = &pp[i];
+ }
+ } else if (nbCandidate_last_point == 0) {
+ //update endpoint
+ polyline->endpoints.second = true;
+ }
+
+ if (polyline->last_point().coincides_with(polyline->first_point())) {
+ //the concat has created a loop : update endpoints
+ polyline->endpoints.first = false;
+ polyline->endpoints.second = false;
+ }
+ }
+ }
+ }
+}
+
}
diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp
index e17fafd62..1886d565c 100644
--- a/src/libslic3r/Polyline.hpp
+++ b/src/libslic3r/Polyline.hpp
@@ -25,12 +25,12 @@ public:
explicit Polyline(Points &&points) : MultiPoint(std::move(points)) {}
Polyline& operator=(const Polyline &other) { points = other.points; return *this; }
Polyline& operator=(Polyline &&other) { points = std::move(other.points); return *this; }
- static Polyline new_scale(const std::vector<Vec2d> &points) {
- Polyline pl;
- pl.points.reserve(points.size());
- for (const Vec2d &pt : points)
- pl.points.emplace_back(Point::new_scale(pt(0), pt(1)));
- return pl;
+ static Polyline new_scale(const std::vector<Vec2d> &points) {
+ Polyline pl;
+ pl.points.reserve(points.size());
+ for (const Vec2d &pt : points)
+ pl.points.emplace_back(Point::new_scale(pt(0), pt(1)));
+ return pl;
}
void append(const Point &point) { this->points.push_back(point); }
@@ -130,8 +130,19 @@ inline void polylines_append(Polylines &dst, Polylines &&src)
bool remove_degenerate(Polylines &polylines);
+
+/// ThickPolyline : a polyline with a width for each point
+/// This class has a vector of coordf_t, it must be the same size as points.
+/// it's used to store the size of the line at this point.
+/// Also, the endpoint let us know if the front() and back() of the polyline
+/// join something or is a dead-end.
class ThickPolyline : public Polyline {
public:
+ /// width size must be == point size
+ std::vector<coordf_t> width;
+ /// if true => it's an endpoint, if false it join an other ThickPolyline. first is at front(), second is at back()
+ std::pair<bool, bool> endpoints;
+
ThickPolyline() : endpoints(std::make_pair(false, false)) {}
ThickLines thicklines() const;
void reverse() {
@@ -139,11 +150,11 @@ public:
std::reverse(this->width.begin(), this->width.end());
std::swap(this->endpoints.first, this->endpoints.second);
}
-
- std::vector<coordf_t> width;
- std::pair<bool,bool> endpoints;
};
+/// concatenate poylines if possible and refresh the endpoints
+void concatThickPolylines(ThickPolylines &polylines);
+
class Polyline3 : public MultiPoint3
{
public:
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 1ef6c7b84..9a210abaa 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -101,6 +101,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"bridge_acceleration",
"bridge_fan_speed",
"colorprint_heights",
+ "top_fan_speed",
"cooling",
"default_acceleration",
"deretract_speed",
@@ -125,7 +126,9 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"first_layer_acceleration",
"first_layer_bed_temperature",
"first_layer_speed",
+ "first_layer_infill_speed",
"gcode_comments",
+ "label_printed_objects",
"gcode_flavor",
"infill_acceleration",
"layer_gcode",
@@ -151,6 +154,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"retract_lift",
"retract_lift_above",
"retract_lift_below",
+ "retract_lift_not_last_layer",
"retract_restart_extra",
"retract_restart_extra_toolchange",
"retract_speed",
@@ -192,7 +196,9 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|| opt_key == "min_skirt_length"
|| opt_key == "ooze_prevention") {
steps.emplace_back(psSkirt);
- } else if (opt_key == "brim_width") {
+ } else if (opt_key == "brim_width"
+ || opt_key == "brim_ears"
+ || opt_key == "brim_ears_max_angle") {
steps.emplace_back(psBrim);
steps.emplace_back(psSkirt);
} else if (
@@ -1197,22 +1203,24 @@ std::string Print::validate() const
break;
}
}
- SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters();
+ SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters();
size_t tallest_object_idx = 0;
if (has_custom_layering)
PrintObject::update_layer_height_profile(*m_objects.front()->model_object(), slicing_params0, layer_height_profiles.front());
for (size_t i = 1; i < m_objects.size(); ++ i) {
const PrintObject *object = m_objects[i];
const SlicingParameters slicing_params = object->slicing_parameters();
- if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
- std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
- return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths");
- if (slicing_params.raft_layers() != slicing_params0.raft_layers())
- return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers");
- if (object->config().support_material_contact_distance != m_objects.front()->config().support_material_contact_distance)
- return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
- if (! equal_layering(slicing_params, slicing_params0))
- return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
+ if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
+ std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
+ return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths");
+ if (slicing_params.raft_layers() != slicing_params0.raft_layers())
+ return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers");
+ if (object->config().support_material_contact_distance_type != m_objects.front()->config().support_material_contact_distance_type
+ || object->config().support_material_contact_distance_top != m_objects.front()->config().support_material_contact_distance_top
+ || object->config().support_material_contact_distance_bottom != m_objects.front()->config().support_material_contact_distance_bottom)
+ return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
+ if (! equal_layering(slicing_params, slicing_params0))
+ return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
if (has_custom_layering) {
PrintObject::update_layer_height_profile(*object->model_object(), slicing_params, layer_height_profiles[i]);
if (*(layer_height_profiles[i].end()-2) > *(layer_height_profiles[tallest_object_idx].end()-2))
@@ -1225,33 +1233,33 @@ std::string Print::validate() const
for (size_t idx_object = 0; idx_object < m_objects.size(); ++ idx_object) {
const PrintObject *object = m_objects[idx_object];
const std::vector<coordf_t> &layer_height_profile = layer_height_profiles[idx_object];
- bool failed = false;
+ bool failed = false;
if (layer_height_profile_tallest.size() >= layer_height_profile.size()) {
- int i = 0;
+ int i = 0;
while (i < layer_height_profile.size() && i < layer_height_profile_tallest.size()) {
if (std::abs(layer_height_profile_tallest[i] - layer_height_profile[i])) {
- failed = true;
- break;
- }
+ failed = true;
+ break;
+ }
++ i;
if (i == layer_height_profile.size() - 2) // this element contains this objects max z
if (layer_height_profile_tallest[i] > layer_height_profile[i]) // the difference does not matter in this case
++ i;
- }
+ }
} else
- failed = true;
- if (failed)
- return L("The Wipe tower is only supported if all objects have the same layer height profile");
- }
+ failed = true;
+ if (failed)
+ return L("The Wipe tower is only supported if all objects have the same layer height profile");
}
}
}
+ }
- {
- // find the smallest nozzle diameter
- std::vector<unsigned int> extruders = this->extruders();
- if (extruders.empty())
- return L("The supplied settings will cause an empty print.");
+ {
+ // find the smallest nozzle diameter
+ std::vector<unsigned int> extruders = this->extruders();
+ if (extruders.empty())
+ return L("The supplied settings will cause an empty print.");
// Find the smallest used nozzle diameter and the number of unique nozzle diameters.
double min_nozzle_diameter = std::numeric_limits<double>::max();
@@ -1274,13 +1282,13 @@ std::string Print::validate() const
for (PrintObject *object : m_objects) {
if (object->config().raft_layers > 0 || object->config().support_material.value) {
if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && max_nozzle_diameter - min_nozzle_diameter > EPSILON) {
- // The object has some form of support and either support_material_extruder or support_material_interface_extruder
- // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
- // are of the same diameter.
+ // The object has some form of support and either support_material_extruder or support_material_interface_extruder
+ // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
+ // are of the same diameter.
return L("Printing with multiple extruders of differing nozzle diameters. "
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
"all nozzles have to be of the same diameter.");
- }
+ }
if (this->has_wipe_tower()) {
if (object->config().support_material_contact_distance == 0) {
// Soluble interface
@@ -1476,7 +1484,10 @@ void Print::process()
m_brim.clear();
if (m_config.brim_width > 0) {
this->set_status(88, "Generating brim");
- this->_make_brim();
+ if (config().brim_ears)
+ this->_make_brim_ears();
+ else
+ this->_make_brim();
}
this->set_done(psBrim);
}
@@ -1548,8 +1559,12 @@ void Print::_make_skirt()
for (const SupportLayer *layer : object->support_layers()) {
if (layer->print_z > skirt_height_z)
break;
- for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities)
- append(object_points, extrusion_entity->as_polyline().points);
+ for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities) {
+ Polylines poly;
+ extrusion_entity->collect_polylines(poly);
+ for (const Polyline &polyline : poly)
+ append(object_points, polyline.points);
+ }
}
// Repeat points for each object copy.
for (const Point &shift : object->m_copies) {
@@ -1646,8 +1661,7 @@ void Print::_make_skirt()
m_skirt.reverse();
}
-void Print::_make_brim()
-{
+void Print::_make_brim() {
// Brim is only printed on first layer and uses perimeter extruder.
Flow flow = this->brim_flow();
Polygons islands;
@@ -1655,7 +1669,7 @@ void Print::_make_brim()
Polygons object_islands;
for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
object_islands.push_back(expoly.contour);
- if (! object->support_layers().empty())
+ if (!object->support_layers().empty())
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
islands.reserve(islands.size() + object_islands.size() * object->m_copies.size());
for (const Point &pt : object->m_copies)
@@ -1666,7 +1680,7 @@ void Print::_make_brim()
}
Polygons loops;
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
- for (size_t i = 0; i < num_loops; ++ i) {
+ for (size_t i = 0; i < num_loops; ++i) {
this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
for (Polygon &poly : islands) {
@@ -1678,12 +1692,172 @@ void Print::_make_brim()
}
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
}
-
+
loops = union_pt_chained(loops, false);
std::reverse(loops.begin(), loops.end());
extrusion_entities_append_loops(m_brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()));
}
+void Print::_make_brim_ears() {
+ Flow flow = this->brim_flow();
+ Points pt_ears;
+ Polygons islands;
+ for (PrintObject *object : m_objects) {
+ Polygons object_islands;
+ for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
+ object_islands.push_back(expoly.contour);
+ if (!object->support_layers().empty())
+ object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
+ islands.reserve(islands.size() + object_islands.size() * object->m_copies.size());
+ for (const Point &copy_pt : object->m_copies)
+ for (const Polygon &poly : object_islands) {
+ islands.push_back(poly);
+ islands.back().translate(copy_pt);
+ for (const Point &p : poly.convex_points(config().brim_ears_max_angle.value * PI / 180.0)) {
+ pt_ears.push_back(p);
+ pt_ears.back() += (copy_pt);
+ }
+ }
+ }
+
+ //create loops (same as standard brim)
+ Polygons loops;
+ size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
+ for (size_t i = 0; i < num_loops; ++i) {
+ this->throw_if_canceled();
+ islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
+ for (Polygon &poly : islands) {
+ // poly.simplify(SCALED_RESOLUTION);
+ poly.points.push_back(poly.points.front());
+ Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
+ p.pop_back();
+ poly.points = std::move(p);
+ }
+ polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
+ }
+ loops = union_pt_chained(loops, false);
+
+
+ //create ear pattern
+ coord_t size_ear = (scale_(m_config.brim_width.value) - flow.scaled_spacing());
+ Polygon point_round;
+ point_round.points.push_back(Point(size_ear * 1, 0 * size_ear));
+ point_round.points.push_back(Point(size_ear*0.966, 0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*0.87, 0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*0.7, 0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*0.5, 0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*0.26, 0.966*size_ear));
+ point_round.points.push_back(Point(size_ear * 0, 1 * size_ear));
+ point_round.points.push_back(Point(size_ear*-0.26, 0.966*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.5, 0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.7, 0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.87, 0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.966, 0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*-1, 0 * size_ear));
+ point_round.points.push_back(Point(size_ear*-0.966, -0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.87, -0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.7, -0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.5, -0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.26, -0.966*size_ear));
+ point_round.points.push_back(Point(size_ear * 0, -1 * size_ear));
+ point_round.points.push_back(Point(size_ear*0.26, -0.966*size_ear));
+ point_round.points.push_back(Point(size_ear*0.5, -0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*0.7, -0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*0.87, -0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*0.966, -0.26*size_ear));
+
+ //create ears
+ Polygons mouse_ears;
+ for (Point pt : pt_ears) {
+ mouse_ears.push_back(point_round);
+ mouse_ears.back().translate(pt);
+ }
+
+ //intersection
+ Polylines lines = intersection_pl(loops, mouse_ears);
+
+ //reorder them
+ std::sort(lines.begin(), lines.end(), [](const Polyline &a, const Polyline &b)->bool { return a.closest_point(Point(0, 0))->y() < b.closest_point(Point(0, 0))->y(); });
+ Polylines lines_sorted;
+ Polyline* previous = NULL;
+ Polyline* best = NULL;
+ double best_dist = -1;
+ size_t best_idx = 0;
+ while (lines.size() > 0) {
+ if (previous == NULL) {
+ lines_sorted.push_back(lines.back());
+ previous = &lines_sorted.back();
+ lines.erase(lines.end() - 1);
+ } else {
+ best = NULL;
+ best_dist = -1;
+ best_idx = 0;
+ for (size_t i = 0; i < lines.size(); ++i) {
+ Polyline &viewed_line = lines[i];
+ double dist = viewed_line.points.front().distance_to(previous->points.front());
+ dist = std::min(dist, viewed_line.points.front().distance_to(previous->points.back()));
+ dist = std::min(dist, viewed_line.points.back().distance_to(previous->points.front()));
+ dist = std::min(dist, viewed_line.points.back().distance_to(previous->points.back()));
+ if (dist < best_dist || best == NULL) {
+ best = &viewed_line;
+ best_dist = dist;
+ best_idx = i;
+ }
+ }
+ if (best != NULL) {
+ //copy new line inside the sorted array.
+ lines_sorted.push_back(lines[best_idx]);
+ lines.erase(lines.begin() + best_idx);
+
+ //connect if near enough
+ if (lines_sorted.size() > 1) {
+ size_t idx = lines_sorted.size() - 2;
+ bool connect = false;
+ if (lines_sorted[idx].points.back().distance_to(lines_sorted[idx + 1].points.front()) < flow.scaled_spacing() * 2) {
+ connect = true;
+ } else if (lines_sorted[idx].points.back().distance_to(lines_sorted[idx + 1].points.back()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx + 1].reverse();
+ connect = true;
+ } else if (lines_sorted[idx].points.front().distance_to(lines_sorted[idx + 1].points.front()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx].reverse();
+ connect = true;
+ } else if (lines_sorted[idx].points.front().distance_to(lines_sorted[idx + 1].points.back()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx].reverse();
+ lines_sorted[idx + 1].reverse();
+ connect = true;
+ }
+
+ if (connect) {
+ //connect them
+ lines_sorted[idx].points.insert(
+ lines_sorted[idx].points.end(),
+ lines_sorted[idx + 1].points.begin(),
+ lines_sorted[idx + 1].points.end());
+ lines_sorted.erase(lines_sorted.begin() + idx + 1);
+ idx--;
+ }
+ }
+
+ //update last position
+ previous = &lines_sorted.back();
+ } else {
+ previous == NULL;
+ }
+
+ }
+ }
+
+ //push into extrusions
+ extrusion_entities_append_paths(
+ m_brim.entities,
+ lines_sorted,
+ erSkirt,
+ float(flow.mm3_per_mm()),
+ float(flow.width),
+ float(this->skirt_first_layer_height())
+ );
+}
+
// Wipe tower support.
bool Print::has_wipe_tower() const
{
@@ -1759,7 +1933,7 @@ void Print::_make_wipe_tower()
float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging),
m_config.high_current_on_filament_swap.value, wipe_volumes,
- m_wipe_tower_data.tool_ordering.first_extruder());
+ m_wipe_tower_data.tool_ordering.first_extruder(), float(m_config.first_layer_extrusion_width));
//wipe_tower.set_retract();
//wipe_tower.set_zhop();
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 3de91818a..b7a0efcd9 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -131,7 +131,7 @@ public:
// by the interactive layer height editor and by the printing process itself.
// The slicing parameters are dependent on various configuration values
// (layer height, first layer height, raft settings, print nozzle diameter etc).
- SlicingParameters slicing_parameters() const;
+ SlicingParameters slicing_parameters() const;
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object);
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
@@ -172,6 +172,7 @@ private:
void generate_support_material();
void _slice(const std::vector<coordf_t> &layer_height_profile);
+ void _offsetHoles(float hole_delta, LayerRegion *layerm);
std::string _fix_slicing_errors();
void _simplify_slices(double distance);
void _make_perimeters();
@@ -180,7 +181,9 @@ private:
void process_external_surfaces();
void discover_vertical_shells();
void bridge_over_infill();
+ void replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_replacement, SurfaceType st_under_it);
void clip_fill_surfaces();
+ void count_distance_solid();
void discover_horizontal_shells();
void combine_infill();
void _generate_support_material();
@@ -364,6 +367,7 @@ private:
void _make_skirt();
void _make_brim();
+ void _make_brim_ears();
void _make_wipe_tower();
void _simplify_slices(double distance);
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 85dcb5d40..140dedcec 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -69,15 +69,24 @@ void PrintConfigDef::init_fff_params()
// Maximum extruder temperature, bumped to 1500 to support printing of glass.
const int max_temp = 1500;
- def = this->add("avoid_crossing_perimeters", coBool);
+ def = this->add("avoid_crossing_perimeters", coBool);
def->label = L("Avoid crossing perimeters");
- def->tooltip = L("Optimize travel moves in order to minimize the crossing of perimeters. "
+ def->tooltip = L("Optimize travel moves in order to minimize the crossing of perimeters. "
"This is mostly useful with Bowden extruders which suffer from oozing. "
"This feature slows down both the print and the G-code generation.");
def->cli = "avoid-crossing-perimeters!";
def->mode = comExpert;
def->default_value = new ConfigOptionBool(false);
+ def = this->add("remove_small_gaps", coBool);
+ def->label = L("Remove small gaps");
+ def->tooltip = L("Remove the small gaps in the 3D model when slicing. Disable it if you "
+ "are very confident on your model, or you want to print an item with a geometry "
+ "designed for vase mode.");
+ def->cli = "remove-small-gaps!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(true);
+
def = this->add("bed_temperature", coInts);
def->label = L("Other layers");
def->tooltip = L("Bed temperature for layers after the first one. "
@@ -130,12 +139,12 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(0);
def = this->add("bridge_angle", coFloat);
- def->label = L("Bridging angle");
+ def->label = L("Bridging");
def->category = L("Infill");
def->tooltip = L("Bridging angle override. If left to zero, the bridging angle will be calculated "
"automatically. Otherwise the provided angle will be used for all bridges. "
"Use 180° for zero angle.");
- def->sidetext = L("°");
+ def->sidetext = L("°");
def->cli = "bridge-angle=f";
def->min = 0;
def->mode = comAdvanced;
@@ -151,8 +160,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->default_value = new ConfigOptionInts { 100 };
+ def = this->add("top_fan_speed", coInts);
+ def->label = L("Top fan speed");
+ def->tooltip = L("This fan speed is enforced during all top fills.");
+ def->sidetext = L("%");
+ def->cli = "top-fan-speed=i@";
+ def->min = 0;
+ def->max = 100;
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionInts{ 100 };
+
def = this->add("bridge_flow_ratio", coFloat);
- def->label = L("Bridge flow ratio");
+ def->label = L("Bridge");
def->category = L("Advanced");
def->tooltip = L("This factor affects the amount of plastic for bridging. "
"You can decrease it slightly to pull the extrudates and prevent sagging, "
@@ -160,9 +179,20 @@ void PrintConfigDef::init_fff_params()
"with cooling (use a fan) before tweaking this.");
def->cli = "bridge-flow-ratio=f";
def->min = 0;
- def->max = 2;
+ def->max = 2;
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionFloat(1);
+
+ def = this->add("over_bridge_flow_ratio", coFloat);
+ def->label = L("Above the bridges");
+ def->category = L("Advanced");
+ def->tooltip = L("Flow ratio to compensate for the gaps in a bridged top surface. Used for ironing infill"
+ "pattern to prevent regions where the low-flow pass does not provide a smooth surface due to a lack of plastic."
+ " You can increase it slightly to pull the top layer at the correct height. Recommended maximum: 1.2.");
+ def->cli = "over-bridge-flow-ratio=f";
+ def->min = 0;
def->mode = comAdvanced;
- def->default_value = new ConfigOptionFloat(1);
+ def->default_value = new ConfigOptionFloat(1);
def = this->add("bridge_speed", coFloat);
def->label = L("Bridges");
@@ -181,9 +211,23 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("mm");
def->cli = "brim-width=f";
def->min = 0;
- def->mode = comAdvanced;
def->default_value = new ConfigOptionFloat(0);
+ def = this->add("brim_ears", coBool);
+ def->label = L(" ");
+ def->tooltip = L("Only draw brim over the sharp edges of the model.");
+ def->cli = "brim-ears!";
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("brim_ears_max_angle", coFloat);
+ def->label = L("max angle");
+ def->tooltip = L("Maximum angle to let a brim ear appear.");
+ def->sidetext = L("°");
+ def->cli = "brim-ears-max-angle=f";
+ def->min = 0;
+ def->max = 180;
+ def->default_value = new ConfigOptionFloat(125);
+
def = this->add("clip_multipart_objects", coBool);
def->label = L("Clip multi-part objects");
def->tooltip = L("When printing multi-material objects, this settings will make slic3r "
@@ -320,13 +364,12 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(6);
def = this->add("elefant_foot_compensation", coFloat);
- def->label = L("Elephant foot compensation");
+ def->label = L("First layer");
def->category = L("Advanced");
- def->tooltip = L("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.");
+ def->tooltip = L("The first layer will be grown / shrunk in the XY plane by the configured value "
+ "to compensate for the 1st layer squish aka an Elephant Foot effect. (should be negative = inwards)");
def->sidetext = L("mm");
def->cli = "elefant-foot-compensation=f";
- def->min = 0;
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloat(0);
@@ -362,27 +405,84 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(false);
- def = this->add("external_fill_pattern", coEnum);
- def->label = L("Top/bottom fill pattern");
+ def = this->add("top_fill_pattern", coEnum);
+ def->label = L("Top Pattern");
def->category = L("Infill");
- def->tooltip = L("Fill pattern for top/bottom infill. This only affects the external visible layer, "
- "and not its adjacent solid shells.");
- def->cli = "external-fill-pattern|solid-fill-pattern=s";
+ def->tooltip = L("Fill pattern for top infill. This only affects the top external visible layer, and not its adjacent solid shells.");
+ def->cli = "top-fill-pattern|solid-fill-pattern=s";
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("concentric");
+ def->enum_values.push_back("concentricgapfill");
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
+ def->enum_values.push_back("smooth");
+ def->enum_values.push_back("smoothtriple");
+ def->enum_values.push_back("smoothhilbert");
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Concentric"));
+ def->enum_labels.push_back(L("Concentric (filled)"));
def->enum_labels.push_back(L("Hilbert Curve"));
def->enum_labels.push_back(L("Archimedean Chords"));
def->enum_labels.push_back(L("Octagram Spiral"));
- // solid_fill_pattern is an obsolete equivalent to external_fill_pattern.
+ def->enum_labels.push_back(L("Ironing"));
+ // solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
def->aliases = { "solid_fill_pattern" };
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
+ def = this->add("bottom_fill_pattern", coEnum);
+ def->label = L("Bottom Pattern");
+ def->category = L("Infill");
+ def->tooltip = L("Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells.");
+ def->cli = "bottom-fill-pattern|solid-fill-pattern=s";
+ def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
+ def->enum_values.push_back("rectilinear");
+ def->enum_values.push_back("concentric");
+ def->enum_values.push_back("concentricgapfill");
+ def->enum_values.push_back("hilbertcurve");
+ def->enum_values.push_back("archimedeanchords");
+ def->enum_values.push_back("octagramspiral");
+ def->enum_labels.push_back(L("Rectilinear"));
+ def->enum_labels.push_back(L("Concentric"));
+ def->enum_labels.push_back(L("Concentric (filled)"));
+ def->enum_labels.push_back(L("Hilbert Curve"));
+ def->enum_labels.push_back(L("Archimedean Chords"));
+ def->enum_labels.push_back(L("Octagram Spiral"));
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
+
+ def = this->add("enforce_full_fill_volume", coBool);
+ def->label = L("Enforce 100% fill volume");
+ def->category = L("Infill");
+ def->tooltip = L("Experimental option which modifies (in solid infill) fill flow to have the exact amount of plastic inside the volume to fill "
+ "(it generally changes the flow from -7% to +4%, depending on the size of the surface to fill and the overlap parameters, "
+ "but it can go as high as +50% for infill in very small areas where rectilinear doesn't have good coverage). It has the advantage "
+ "to remove the over-extrusion seen in thin infill areas, from the overlap ratio");
+ def->cli = "enforce-full-fill-volume!";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(true);
+
+ def = this->add("external_infill_margin", coFloat);
+ def->label = L("Default");
+ def->category = L("Infill");
+ def->tooltip = L("This parameter grows the top/bottom/solid layers by the specified MM to anchor them into the part. Put 0 to deactivate it.");
+ def->sidetext = L("mm");
+ def->cli = "top-layer-anchor=f";
+ def->min = 0;
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionFloat(1.5);
+
+ def = this->add("bridged_infill_margin", coFloat);
+ def->label = L("Bridged");
+ def->category = L("Infill");
+ def->tooltip = L("This parameter grows the bridged solid infill layers by the specified MM to anchor them into the part. Put 0 to deactivate it.");
+ def->sidetext = L("mm");
+ def->cli = "top-layer-anchor=f";
+ def->min = 0;
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionFloat(2);
+
def = this->add("external_perimeter_extrusion_width", coFloatOrPercent);
def->label = L("External perimeters");
def->category = L("Extrusion Width");
@@ -395,7 +495,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(0, false);
def = this->add("external_perimeter_speed", coFloatOrPercent);
- def->label = L("External perimeters");
+ def->label = L("External");
def->category = L("Speed");
def->tooltip = L("This separate setting will affect the speed of external perimeters (the visible ones). "
"If expressed as percentage (for example: 80%) it will be calculated "
@@ -411,11 +511,33 @@ void PrintConfigDef::init_fff_params()
def->label = L("External perimeters first");
def->category = L("Layers and Perimeters");
def->tooltip = L("Print contour perimeters from the outermost one to the innermost one "
- "instead of the default inverse order.");
+ "instead of the default inverse order.");
def->cli = "external-perimeters-first!";
def->mode = comExpert;
def->default_value = new ConfigOptionBool(false);
+ def = this->add("perimeter_loop", coBool);
+ def->label = L(" ");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Join the perimeters to create only one continuous extrusion without any z-hop."
+ " Long inside travel (from external to holes) are not extruded to give some space to the infill.");
+ def->cli = "loop-perimeter!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("perimeter_loop_seam", coEnum);
+ def->label = L("Seam position");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Position of perimeters starting points.");
+ def->cli = "perimeter-seam-position=s";
+ def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values();
+ def->enum_values.push_back("nearest");
+ def->enum_values.push_back("rear");
+ def->enum_labels.push_back(L("Nearest"));
+ def->enum_labels.push_back(L("Rear"));
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionEnum<SeamPosition>(spRear);
+
def = this->add("extra_perimeters", coBool);
def->label = L("Extra perimeters if needed");
def->category = L("Layers and Perimeters");
@@ -423,9 +545,17 @@ void PrintConfigDef::init_fff_params()
"Slic3r keeps adding perimeters, until more than 70% of the loop immediately above "
"is supported.");
def->cli = "extra-perimeters!";
- def->mode = comExpert;
+ def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(true);
+ def = this->add("only_one_perimeter_top", coBool);
+ def->label = "Only one perimeter on Top surfaces";
+ def->category = "Layers and Perimeters";
+ def->tooltip = "Use only one perimeter on flat top surface, to let more space to the top infill pattern.";
+ def->cli = "one-top-perimeter!";
+ def->default_value = new ConfigOptionBool(true);
+
+
def = this->add("extruder", coInt);
def->gui_type = "i_enum_open";
def->label = L("Extruder");
@@ -663,7 +793,7 @@ void PrintConfigDef::init_fff_params()
def->cli = "filament-ramming-parameters=s@";
def->mode = comExpert;
def->default_value = new ConfigOptionStrings { "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" };
+ " 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" };
def = this->add("filament_unload_time", coFloats);
def->label = L("Filament unload time");
@@ -730,7 +860,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionStrings { "" };
def = this->add("fill_angle", coFloat);
- def->label = L("Fill angle");
+ def->label = L("Fill");
def->category = L("Infill");
def->tooltip = L("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 "
@@ -752,6 +882,7 @@ void PrintConfigDef::init_fff_params()
def->cli = "fill-density=s";
def->min = 0;
def->max = 100;
+ /*
def->enum_values.push_back("0");
def->enum_values.push_back("5");
def->enum_values.push_back("10");
@@ -780,10 +911,37 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("80%");
def->enum_labels.push_back("90%");
def->enum_labels.push_back("100%");
- def->default_value = new ConfigOptionPercent(20);
+ */
+ def->enum_values.push_back("0");
+ def->enum_values.push_back("4");
+ def->enum_values.push_back("5.5");
+ def->enum_values.push_back("7.5");
+ def->enum_values.push_back("10");
+ def->enum_values.push_back("13");
+ def->enum_values.push_back("18");
+ def->enum_values.push_back("23");
+ def->enum_values.push_back("31");
+ def->enum_values.push_back("42");
+ def->enum_values.push_back("55");
+ def->enum_values.push_back("75");
+ def->enum_values.push_back("100");
+ def->enum_labels.push_back("0");
+ def->enum_labels.push_back("4");
+ def->enum_labels.push_back("5.5");
+ def->enum_labels.push_back("7.5");
+ def->enum_labels.push_back("10");
+ def->enum_labels.push_back("13");
+ def->enum_labels.push_back("18");
+ def->enum_labels.push_back("23");
+ def->enum_labels.push_back("31");
+ def->enum_labels.push_back("42");
+ def->enum_labels.push_back("55");
+ def->enum_labels.push_back("75");
+ def->enum_labels.push_back("100");
+ def->default_value = new ConfigOptionPercent(18);
def = this->add("fill_pattern", coEnum);
- def->label = L("Fill pattern");
+ def->label = L("Pattern");
def->category = L("Infill");
def->tooltip = L("Fill pattern for general low-density infill.");
def->cli = "fill-pattern=s";
@@ -801,6 +959,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
+ def->enum_values.push_back("scatteredrectilinear");
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Grid"));
def->enum_labels.push_back(L("Triangles"));
@@ -814,6 +973,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Hilbert Curve"));
def->enum_labels.push_back(L("Archimedean Chords"));
def->enum_labels.push_back(L("Octagram Spiral"));
+ def->enum_labels.push_back(L("Scattered Rectilinear"));
def->default_value = new ConfigOptionEnum<InfillPattern>(ipStars);
def = this->add("first_layer_acceleration", coFloat);
@@ -861,16 +1021,29 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(0.35, false);
def = this->add("first_layer_speed", coFloatOrPercent);
- def->label = L("First layer speed");
+ def->label = L("Default");
def->tooltip = L("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.");
+ "but infill of the first layer, it can be overwrite by the 'default' (default depends of the type of the path) "
+ "speed if it's lower than that. If expressed as a percentage "
+ "(for example: 40%) it will scale the 'default' speeds.");
def->sidetext = L("mm/s or %");
def->cli = "first-layer-speed=s";
def->min = 0;
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloatOrPercent(30, false);
-
+
+ def = this->add("first_layer_infill_speed", coFloatOrPercent);
+ def->label = L("infill");
+ def->tooltip = L("If expressed as absolute value in mm/s, this speed will be applied to infill moves "
+ "of the first layer, it can be overwrite by the 'default' (solid infill or infill if not bottom) "
+ "speed if it's lower than that. If expressed as a percentage "
+ "(for example: 40%) it will scale the 'default' speed.");
+ def->sidetext = L("mm/s or %");
+ def->cli = "first-layer-infill-speed=s";
+ def->min = 0;
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionFloatOrPercent(30, false);
+
def = this->add("first_layer_temperature", coInts);
def->label = L("First layer");
def->tooltip = L("Extruder temperature for first layer. If you want to control temperature manually "
@@ -878,13 +1051,22 @@ void PrintConfigDef::init_fff_params()
def->cli = "first-layer-temperature=i@";
def->min = 0;
def->max = max_temp;
- def->default_value = new ConfigOptionInts { 200 };
-
+ def->default_value = new ConfigOptionInts{ 200 };
+
+ def = this->add("gap_fill", coBool);
+ def->label = L("Gap fill");
+ def->category = L("Advanced");
+ def->tooltip = L("Enable gap fill algorithm. It will extrude small lines between perimeters "
+ "when there is not enough space for another perimeter or an infill.");
+ def->cli = "gap-fill!";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(true);
+
def = this->add("gap_fill_speed", coFloat);
def->label = L("Gap fill");
def->category = L("Speed");
def->tooltip = L("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.");
+ "to avoid too much shaking and resonance issues. Set zero to disable gaps filling.");
def->sidetext = L("mm/s");
def->cli = "gap-fill-speed=f";
def->min = 0;
@@ -894,12 +1076,19 @@ void PrintConfigDef::init_fff_params()
def = this->add("gcode_comments", coBool);
def->label = L("Verbose G-code");
def->tooltip = L("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.");
+ "If you print from SD card, the additional weight of the file could make your firmware "
+ "slow down.");
def->cli = "gcode-comments!";
def->mode = comExpert;
def->default_value = new ConfigOptionBool(0);
+ def = this->add("label_printed_objects", coBool);
+ def->label = "Label Prints with Object ID";
+ def->tooltip = "Enable this to add comments in the G-Code that label print moves with what object they belong. Can be used with Octoprint CancelObject plugin.";
+ def->cli = "label-printed-objects!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(0);
+
def = this->add("gcode_flavor", coEnum);
def->label = L("G-code flavor");
def->tooltip = L("Some G/M-code commands, including temperature control and others, are not universal. "
@@ -961,6 +1150,39 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionInt(1);
+ def = this->add("infill_dense", coBool);
+ def->label = ("");
+ def->category = L("Infill");
+ def->tooltip = L("Enables the creation of a support layer under the first solid layer. This allows you to use a lower infill ratio without compromising the top quality."
+ " The dense infill is laid out with a 50% infill density.");
+ def->cli = "infill-dense!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("infill_not_connected", coBool);
+ def->label = ("Do not connect infill lines to each other");
+ def->category = L("Infill");
+ def->tooltip = L("If checked, the infill algorithm will try to not connect the lines near the infill. Can be useful for art or with high infill/perimeter overlap.");
+ def->cli = "infill-not-connected!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("infill_dense_algo", coEnum);
+ def->label = L("Algorithm");
+ def->tooltip = L("Choose the way the dense layer is lay out."
+ " The automatic option let it try to draw the smallest surface with only strait lines inside the sparse infill."
+ " The anchored just enlarge a bit (by bridged anchor) the surfaces that need a better support.");
+ def->cli = "infill-dense-algo=s";
+ def->enum_keys_map = &ConfigOptionEnum<DenseInfillAlgo>::get_enum_values();
+ def->enum_values.push_back("automatic");
+ def->enum_values.push_back("autosmall");
+ def->enum_values.push_back("enlarged");
+ def->enum_labels.push_back(L("Automatic"));
+ def->enum_labels.push_back(L("Automatic, only for small areas"));
+ def->enum_labels.push_back(L("Anchored"));
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionEnum<DenseInfillAlgo>(dfaAutomatic);
+
def = this->add("infill_extruder", coInt);
def->label = L("Infill extruder");
def->category = L("Extruders");
@@ -984,6 +1206,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("infill_first", coBool);
def->label = L("Infill before perimeters");
+ def->category = L("Infill");
def->tooltip = L("This option will switch the print order of perimeters and infill, making the latter first.");
def->cli = "infill-first!";
def->mode = comExpert;
@@ -1012,7 +1235,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(25, true);
def = this->add("infill_speed", coFloat);
- def->label = L("Infill");
+ def->label = L("Sparse");
def->category = L("Speed");
def->tooltip = L("Speed for printing the internal fill. Set to zero for auto.");
def->sidetext = L("mm/s");
@@ -1056,6 +1279,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->default_value = new ConfigOptionString("");
+ def = this->add("exact_last_layer_height", coBool);
+ def->label = L("Exact last layer height");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("This setting controls the height of last object layers to put the last layer at the exact highest height possible. Experimental.");
+ def->cli = "exact_last-layer-height=f";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(false);
+
def = this->add("remaining_times", coBool);
def->label = L("Supports remaining times");
def->tooltip = L("Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute"
@@ -1128,9 +1359,9 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)";
def->sidetext = L("mm/s");
def->min = 0;
- def->width = machine_limits_opt_width;
+ def->width = machine_limits_opt_width;
def->mode = comAdvanced;
- def->default_value = new ConfigOptionFloats{ 0., 0. };
+ def->default_value = new ConfigOptionFloats{ 0., 0. };
// M205 T... [mm/sec]
def = this->add("machine_min_travel_rate", coFloats);
@@ -1139,9 +1370,9 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Minimum travel feedrate") + " (M205 T)";
def->sidetext = L("mm/s");
def->min = 0;
- def->width = machine_limits_opt_width;
+ def->width = machine_limits_opt_width;
def->mode = comAdvanced;
- def->default_value = new ConfigOptionFloats{ 0., 0. };
+ def->default_value = new ConfigOptionFloats{ 0., 0. };
// M204 S... [mm/sec^2]
def = this->add("machine_max_acceleration_extruding", coFloats);
@@ -1150,7 +1381,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Maximum acceleration when extruding") + " (M204 S)";
def->sidetext = L("mm/s²");
def->min = 0;
- def->width = machine_limits_opt_width;
+ def->width = machine_limits_opt_width;
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloats{ 1500., 1250. };
@@ -1161,7 +1392,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Maximum acceleration when retracting") + " (M204 T)";
def->sidetext = L("mm/s²");
def->min = 0;
- def->width = machine_limits_opt_width;
+ def->width = machine_limits_opt_width;
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloats{ 1500., 1250. };
@@ -1172,7 +1403,7 @@ void PrintConfigDef::init_fff_params()
def->cli = "max-fan-speed=i@";
def->min = 0;
def->max = 100;
- def->mode = comExpert;
+ def->mode = comAdvanced;
def->default_value = new ConfigOptionInts { 100 };
def = this->add("max_layer_height", coFloats);
@@ -1239,7 +1470,7 @@ void PrintConfigDef::init_fff_params()
def->cli = "min-fan-speed=i@";
def->min = 0;
def->max = 100;
- def->mode = comExpert;
+ def->mode = comAdvanced;
def->default_value = new ConfigOptionInts { 35 };
def = this->add("min_layer_height", coFloats);
@@ -1359,11 +1590,36 @@ void PrintConfigDef::init_fff_params()
def->label = L("Detect bridging perimeters");
def->category = L("Layers and Perimeters");
def->tooltip = L("Experimental option to adjust flow for overhangs (bridge flow will be used), "
- "to apply bridge speed to them and enable fan.");
+ "to apply bridge speed to them and enable fan.");
def->cli = "overhangs!";
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(true);
+ def = this->add("no_perimeter_unsupported", coBool);
+ def->label = L("");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Experimental option to remove perimeters where there is nothing under it and where a bridged infill should be better. Computationally intensive!");
+ def->cli = "no-perimeter-unsupported!";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("min_perimeter_unsupported", coInt);
+ def->label = L("Minimum perimeters");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Number of perimeters exluded from this option.");
+ def->cli = "min-perimeter-unsupported=i";
+ def->min = 0;
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionInt(0);
+
+ def = this->add("noperi_bridge_only", coBool);
+ def->label = L("Only on bridged areas");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Only remove perimeters over areas marked as 'bridge'. Can be useful to let perimeter run over overhangs, but it's not very reliable.");
+ def->cli = "noperi-bridge-only!";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(true);
+
def = this->add("parking_pos_retraction", coFloat);
def->label = L("Filament parking position");
def->tooltip = L("Distance of the extruder tip from the position where the filament is parked "
@@ -1418,7 +1674,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(0, false);
def = this->add("perimeter_speed", coFloat);
- def->label = L("Perimeters");
+ def->label = L("Default");
def->category = L("Speed");
def->tooltip = L("Speed for perimeters (contours, aka vertical shells). Set to zero for auto.");
def->sidetext = L("mm/s");
@@ -1451,9 +1707,9 @@ void PrintConfigDef::init_fff_params()
def->gui_flags = "serialized";
def->multiline = true;
def->full_width = true;
- def->height = 60;
+ def->height = 60;
def->mode = comExpert;
- def->default_value = new ConfigOptionStrings();
+ def->default_value = new ConfigOptionStrings();
def = this->add("printer_model", coString);
def->label = L("Printer type");
@@ -1486,11 +1742,19 @@ void PrintConfigDef::init_fff_params()
def = this->add("printer_settings_id", coString);
def->default_value = new ConfigOptionString("");
+ def = this->add("support_material_solid_first_layer", coBool);
+ def->label = L("Solid first layer");
+ def->category = L("Support material");
+ def->tooltip = L("Use a solid layer instead of a raft for the layer that touch the build plate.");
+ def->cli = "support-material-solid-first-layer!";
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBool(false);
+
def = this->add("raft_layers", coInt);
def->label = L("Raft layers");
def->category = L("Support material");
def->tooltip = L("The object will be raised by this number of layers, and support material "
- "will be generated under it.");
+ "will be generated under it.");
def->sidetext = L("layers");
def->cli = "raft-layers=i";
def->min = 0;
@@ -1583,6 +1847,13 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloats { 0. };
+ def = this->add("retract_lift_not_last_layer", coBools);
+ def->label = L("Not on top");
+ def->category = L("Support material");
+ def->tooltip = L("Select this option to not use the z-lift on a top surface.");
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionBools { false };
+
def = this->add("retract_restart_extra", coFloats);
def->label = L("Extra length on restart");
def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push "
@@ -1630,12 +1901,22 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("nearest");
def->enum_values.push_back("aligned");
def->enum_values.push_back("rear");
+ def->enum_values.push_back("hidden");
def->enum_labels.push_back(L("Random"));
def->enum_labels.push_back(L("Nearest"));
def->enum_labels.push_back(L("Aligned"));
- def->enum_labels.push_back(L("Rear"));
+ def->enum_labels.push_back(L("Rear"));
+ def->enum_labels.push_back(L("Hidden"));
def->mode = comSimple;
- def->default_value = new ConfigOptionEnum<SeamPosition>(spAligned);
+ def->default_value = new ConfigOptionEnum<SeamPosition>(spHidden);
+
+ def = this->add("seam_travel", coBool);
+ def->label = L("Travel move reduced");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Add a big cost to travel paths when possible (when going into a loop), so it will prefer a less optimal seam posistion if it's nearer.");
+ def->cli = "seam-travel!";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionBool(false);
#if 0
def = this->add("seam_preferred_direction", coFloat);
@@ -1725,7 +2006,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionInts { 5 };
def = this->add("small_perimeter_speed", coFloatOrPercent);
- def->label = L("Small perimeters");
+ def->label = L("Small");
def->category = L("Speed");
def->tooltip = L("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 "
@@ -1781,7 +2062,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(0, false);
def = this->add("solid_infill_speed", coFloatOrPercent);
- def->label = L("Solid infill");
+ def->label = L("Solid");
def->category = L("Speed");
def->tooltip = L("Speed for printing solid regions (top/bottom/internal horizontal shells). "
"This can be expressed as a percentage (for example: 80%) over the default "
@@ -1816,7 +2097,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Temperature variation");
def->tooltip = L("Temperature difference to be applied when an extruder is not active. "
"Enables a full-height \"sacrificial\" skirt on which the nozzles are periodically wiped.");
- def->sidetext = "∆°C";
+ def->sidetext = "∆°C";
def->cli = "standby-temperature-delta=i";
def->min = -max_temp;
def->max = max_temp;
@@ -1861,7 +2142,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("The printer multiplexes filaments into a single hot end.");
def->cli = "single-extruder-multi-material!";
def->mode = comExpert;
- def->default_value = new ConfigOptionBool(false);
+ def->default_value = new ConfigOptionBool(false);
def = this->add("single_extruder_multi_material_priming", coBool);
def->label = L("Prime all printing extruders");
@@ -1918,20 +2199,55 @@ void PrintConfigDef::init_fff_params()
def->mode = comSimple;
def->default_value = new ConfigOptionBool(false);
- def = this->add("support_material_contact_distance", coFloat);
+ def = this->add("support_material_contact_distance_type", coEnum);
+ def->label = L("Type");
+ def->category = L("Support material");
+ def->tooltip = L("How to compute the vertical z-distance.\n"
+ "From filament: it use the nearest bit of the filament. When a bridge is extruded, it goes below the current plane.\n"
+ "From plane: it use the plane-z. Same than 'from filament' if no 'bridge' is extruded.\n"
+ "None: No z-offset. Useful for Soluble supports.\n");
+ def->cli = "support-material-contact-type=s";
+ def->enum_keys_map = &ConfigOptionEnum<SupportZDistanceType>::get_enum_values();
+ def->enum_values.push_back("filament");
+ def->enum_values.push_back("plane");
+ def->enum_values.push_back("none");
+ def->enum_labels.push_back("From filament");
+ def->enum_labels.push_back("From plane");
+ def->enum_labels.push_back("None");
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionEnum<SupportZDistanceType>(zdFilament);
+
+ def = this->add("support_material_contact_distance_top", coFloat);
+ def->gui_type = "f_enum_open";
+ def->label = L("Top");
+ def->category = L("Support material");
+ def->tooltip = L("The vertical distance between support material interface and the object"
+ "(when the object is printed on top of the support). "
+ "Setting this to 0 will also prevent Slic3r from using bridge flow and speed "
+ "for the first object layer.");
+ def->sidetext = L("mm");
+ def->cli = "support-material-contact-distance-top=f";
+ // def->min = 0;
+ def->enum_values.push_back("0");
+ def->enum_values.push_back("0.2");
+ def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str());
+ def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str());
+ def->mode = comAdvanced;
+ def->default_value = new ConfigOptionFloat(0.2);
+
+ def = this->add("support_material_contact_distance_bottom", coFloat);
def->gui_type = "f_enum_open";
- def->label = L("Contact Z distance");
+ def->label = L("Bottom");
def->category = L("Support material");
- def->tooltip = L("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.");
+ def->tooltip = L("The vertical distance between object and support material interface"
+ "(when the support is printed on top of the object).");
def->sidetext = L("mm");
- def->cli = "support-material-contact-distance=f";
-// def->min = 0;
+ def->cli = "support-material-contact-distance-bottom=f";
+ // def->min = 0;
def->enum_values.push_back("0");
def->enum_values.push_back("0.2");
- def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str());
- def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str());
+ def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str());
+ def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str());
def->mode = comAdvanced;
def->default_value = new ConfigOptionFloat(0.2);
@@ -2009,7 +2325,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(0);
def = this->add("support_material_interface_speed", coFloatOrPercent);
- def->label = L("Support material interface");
+ def->label = L("Interface");
def->category = L("Support material");
def->tooltip = L("Speed for printing support material interface layers. If expressed as percentage "
"(for example 50%) it will be calculated over support material speed.");
@@ -2029,7 +2345,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("rectilinear-grid");
def->enum_values.push_back("honeycomb");
- def->enum_labels.push_back(L("Rectilinear"));
+ def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Rectilinear grid"));
def->enum_labels.push_back(L("Honeycomb"));
def->mode = comAdvanced;
@@ -2046,7 +2362,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(2.5);
def = this->add("support_material_speed", coFloat);
- def->label = L("Support material");
+ def->label = L("Default");
def->category = L("Support material");
def->tooltip = L("Speed for printing support material.");
def->sidetext = L("mm/s");
@@ -2099,7 +2415,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionInts { 200 };
def = this->add("thin_walls", coBool);
- def->label = L("Detect thin walls");
+ def->label = L("");
def->category = L("Layers and Perimeters");
def->tooltip = L("Detect single-width walls (parts where two extrusions don't fit and we need "
"to collapse them into a single trace).");
@@ -2107,6 +2423,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(true);
+ def = this->add("thin_walls_min_width", coFloatOrPercent);
+ def->label = L("min width");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Minimum width for the extrusion to be extruded (widths lower than the nozzle diameter will be over-extruded at the nozzle diameter). Can be percent of the nozzle size.");
+ def->cli = "thin-walls-min-width=s";
+ def->mode = comExpert;
+ def->min = 0;
+ def->default_value = new ConfigOptionFloatOrPercent(33,true);
+
def = this->add("threads", coInt);
def->label = L("Threads");
def->tooltip = L("Threads are used to parallelize long-running tasks. Optimal threads number "
@@ -2144,7 +2469,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloatOrPercent(0, false);
def = this->add("top_solid_infill_speed", coFloatOrPercent);
- def->label = L("Top solid infill");
+ def->label = L("Top solid");
def->category = L("Speed");
def->tooltip = L("Speed for printing top solid layers (it only applies to the uppermost "
"external layers and not to their internal solid layers). You may want "
@@ -2249,7 +2574,7 @@ void PrintConfigDef::init_fff_params()
140.f, 140.f, 140.f, 140.f, 0.f };
def = this->add("wipe_tower_x", coFloat);
- def->label = L("Position X");
+ def->label = L("X");
def->tooltip = L("X coordinate of the left front corner of a wipe tower");
def->sidetext = L("mm");
def->cli = "wipe-tower-x=f";
@@ -2257,7 +2582,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(180.);
def = this->add("wipe_tower_y", coFloat);
- def->label = L("Position Y");
+ def->label = L("Y");
def->tooltip = L("Y coordinate of the left front corner of a wipe tower");
def->sidetext = L("mm");
def->cli = "wipe-tower-y=f";
@@ -2307,16 +2632,27 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionFloat(10.);
def = this->add("xy_size_compensation", coFloat);
- def->label = L("XY Size Compensation");
+ def->label = L("All layers");
def->category = L("Advanced");
def->tooltip = L("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.");
+ "for fine-tuning sizes.");
def->sidetext = L("mm");
def->cli = "xy-size-compensation=f";
def->mode = comExpert;
def->default_value = new ConfigOptionFloat(0);
+ def = this->add("hole_size_compensation", coFloat);
+ def->label = L("Holes");
+ def->category = L("Advanced");
+ def->tooltip = L("The convex holes will be grown / shrunk in the XY plane by the configured value"
+ " (negative = inwards, positive = outwards, should be negative as the holes are always a bit smaller irl)."
+ " This might be useful for fine-tuning hole sizes.");
+ def->sidetext = L("mm");
+ def->cli = "hole-size-compensation=f";
+ def->mode = comExpert;
+ def->default_value = new ConfigOptionFloat(0);
+
def = this->add("z_offset", coFloat);
def->label = L("Z offset");
def->tooltip = L("This value will be added (or subtracted) from all the Z coordinates "
@@ -2797,9 +3133,13 @@ void DynamicPrintConfig::normalize()
opt->values.assign(opt->values.size(), false); // set all values to false
}
{
- this->opt<ConfigOptionInt>("perimeters", true)->value = 1;
+ this->opt<ConfigOptionInt>("perimeters", true)->value = 1;
this->opt<ConfigOptionInt>("top_solid_layers", true)->value = 0;
- this->opt<ConfigOptionPercent>("fill_density", true)->value = 0;
+ this->opt<ConfigOptionPercent>("fill_density", true)->value = 0;
+ this->opt<ConfigOptionBool>("support_material", true)->value = false;
+ this->opt<ConfigOptionInt>("support_material_enforce_layers")->value = 0;
+ this->opt<ConfigOptionBool>("exact_last_layer_height", true)->value = false;
+ this->opt<ConfigOptionBool>("ensure_vertical_shell_thickness", true)->value = false;
}
}
}
@@ -2807,8 +3147,8 @@ void DynamicPrintConfig::normalize()
std::string DynamicPrintConfig::validate()
{
// Full print config is initialized from the defaults.
- const ConfigOption *opt = this->option("printer_technology", false);
- auto printer_technology = (opt == nullptr) ? ptFFF : static_cast<PrinterTechnology>(dynamic_cast<const ConfigOptionEnumGeneric*>(opt)->value);
+ const ConfigOption *opt = this->option("printer_technology", false);
+ auto printer_technology = (opt == nullptr) ? ptFFF : static_cast<PrinterTechnology>(dynamic_cast<const ConfigOptionEnumGeneric*>(opt)->value);
switch (printer_technology) {
case ptFFF:
{
@@ -2892,13 +3232,19 @@ std::string FullPrintConfig::validate()
if (! print_config_def.get("fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
return "Invalid value for --fill-pattern";
- // --external-fill-pattern
- if (! print_config_def.get("external_fill_pattern")->has_enum_value(this->external_fill_pattern.serialize()))
- return "Invalid value for --external-fill-pattern";
+ // --top-fill-pattern
+ if (! print_config_def.get("top_fill_pattern")->has_enum_value(this->top_fill_pattern.serialize()))
+ return "Invalid value for --top-fill-pattern";
+
+ // --bottom-fill-pattern
+ if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize()))
+ return "Invalid value for --bottom-fill-pattern";
// --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON &&
- ! print_config_def.get("external_fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
+ (! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
+ || ! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
+ ))
return "The selected fill pattern is not supposed to work at 100% density";
// --infill-every-layers
@@ -2913,6 +3259,10 @@ std::string FullPrintConfig::validate()
if (this->bridge_flow_ratio <= 0)
return "Invalid value for --bridge-flow-ratio";
+ // --over-bridge-flow-ratio
+ if (this->over_bridge_flow_ratio <= 0)
+ return "Invalid value for --over-bridge-flow-ratio";
+
// extruder clearance
if (this->extruder_clearance_radius <= 0)
return "Invalid value for --extruder-clearance-radius";
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 4842156d6..02fb1e7c0 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -41,7 +41,8 @@ enum PrintHostType {
enum InfillPattern {
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
- ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral,
+ ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth, ipSmoothHilbert, ipSmoothTriple,
+ ipRectiWithPerimeter, ipConcentricGapFill, ipScatteredRectilinear
};
enum SupportMaterialPattern {
@@ -49,13 +50,21 @@ enum SupportMaterialPattern {
};
enum SeamPosition {
- spRandom, spNearest, spAligned, spRear
+ spRandom, spNearest, spAligned, spRear, spHidden
};
enum FilamentType {
ftPLA, ftABS, ftPET, ftHIPS, ftFLEX, ftSCAFF, ftEDGE, ftNGEN, ftPVA
};
+enum DenseInfillAlgo {
+ dfaAutomatic, dfaAutoNotFull, dfaEnlarged,
+};
+
+enum SupportZDistanceType {
+ zdFilament, zdPlane, zdNone,
+};
+
enum SLADisplayOrientation {
sladoLandscape,
sladoPortrait
@@ -112,12 +121,18 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::g
keys_map["cubic"] = ipCubic;
keys_map["line"] = ipLine;
keys_map["concentric"] = ipConcentric;
+ keys_map["concentricgapfill"] = ipConcentricGapFill;
keys_map["honeycomb"] = ipHoneycomb;
keys_map["3dhoneycomb"] = ip3DHoneycomb;
keys_map["gyroid"] = ipGyroid;
keys_map["hilbertcurve"] = ipHilbertCurve;
keys_map["archimedeanchords"] = ipArchimedeanChords;
keys_map["octagramspiral"] = ipOctagramSpiral;
+ keys_map["smooth"] = ipSmooth;
+ keys_map["smoothtriple"] = ipSmoothTriple;
+ keys_map["smoothhilbert"] = ipSmoothHilbert;
+ keys_map["rectiwithperimeter"] = ipRectiWithPerimeter;
+ keys_map["scatteredrectilinear"]= ipScatteredRectilinear;
}
return keys_map;
}
@@ -139,6 +154,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::ge
keys_map["nearest"] = spNearest;
keys_map["aligned"] = spAligned;
keys_map["rear"] = spRear;
+ keys_map["hidden"] = spHidden;
}
return keys_map;
}
@@ -159,6 +175,24 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<FilamentType>::ge
return keys_map;
}
+template<> inline const t_config_enum_values& ConfigOptionEnum<DenseInfillAlgo>::get_enum_values() {
+ static const t_config_enum_values keys_map = {
+ { "automatic", dfaAutomatic },
+ { "autosmall", dfaAutoNotFull },
+ { "enlarged", dfaEnlarged }
+ };
+ return keys_map;
+}
+
+template<> inline const t_config_enum_values& ConfigOptionEnum<SupportZDistanceType>::get_enum_values() {
+ static const t_config_enum_values keys_map = {
+ { "filament", zdFilament },
+ { "plane", zdPlane },
+ { "none", zdNone }
+ };
+ return keys_map;
+}
+
template<> inline const t_config_enum_values& ConfigOptionEnum<SLADisplayOrientation>::get_enum_values() {
static const t_config_enum_values keys_map = {
{ "landscape", sladoLandscape},
@@ -370,6 +404,7 @@ class PrintObjectConfig : public StaticPrintConfig
STATIC_PRINT_CONFIG_CACHE(PrintObjectConfig)
public:
ConfigOptionBool clip_multipart_objects;
+ ConfigOptionBool remove_small_gaps;
ConfigOptionBool dont_support_bridges;
ConfigOptionFloat elefant_foot_compensation;
ConfigOptionFloatOrPercent extrusion_width;
@@ -378,8 +413,10 @@ public:
// Force the generation of solid shells between adjacent materials/volumes.
ConfigOptionBool interface_shells;
ConfigOptionFloat layer_height;
+ ConfigOptionBool exact_last_layer_height;
ConfigOptionInt raft_layers;
ConfigOptionEnum<SeamPosition> seam_position;
+ ConfigOptionBool seam_travel;
// ConfigOptionFloat seam_preferred_direction;
// ConfigOptionFloat seam_preferred_direction_jitter;
ConfigOptionBool support_material;
@@ -388,7 +425,9 @@ public:
// Direction of the support pattern (in XY plane).
ConfigOptionFloat support_material_angle;
ConfigOptionBool support_material_buildplate_only;
- ConfigOptionFloat support_material_contact_distance;
+ ConfigOptionEnum<SupportZDistanceType> support_material_contact_distance_type;
+ ConfigOptionFloat support_material_contact_distance_top;
+ ConfigOptionFloat support_material_contact_distance_bottom;
ConfigOptionInt support_material_enforce_layers;
ConfigOptionInt support_material_extruder;
ConfigOptionFloatOrPercent support_material_extrusion_width;
@@ -402,18 +441,21 @@ public:
// Spacing between support material lines (the hatching distance).
ConfigOptionFloat support_material_spacing;
ConfigOptionFloat support_material_speed;
+ ConfigOptionBool support_material_solid_first_layer;
ConfigOptionBool support_material_synchronize_layers;
// Overhang angle threshold.
ConfigOptionInt support_material_threshold;
ConfigOptionBool support_material_with_sheath;
ConfigOptionFloatOrPercent support_material_xy_spacing;
ConfigOptionFloat xy_size_compensation;
+ ConfigOptionFloat hole_size_compensation;
ConfigOptionBool wipe_into_objects;
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
OPT_PTR(clip_multipart_objects);
+ OPT_PTR(remove_small_gaps);
OPT_PTR(dont_support_bridges);
OPT_PTR(elefant_foot_compensation);
OPT_PTR(extrusion_width);
@@ -421,15 +463,19 @@ protected:
OPT_PTR(infill_only_where_needed);
OPT_PTR(interface_shells);
OPT_PTR(layer_height);
+ OPT_PTR(exact_last_layer_height);
OPT_PTR(raft_layers);
OPT_PTR(seam_position);
+ OPT_PTR(seam_travel);
// OPT_PTR(seam_preferred_direction);
// OPT_PTR(seam_preferred_direction_jitter);
OPT_PTR(support_material);
OPT_PTR(support_material_auto);
OPT_PTR(support_material_angle);
OPT_PTR(support_material_buildplate_only);
- OPT_PTR(support_material_contact_distance);
+ OPT_PTR(support_material_contact_distance_type);
+ OPT_PTR(support_material_contact_distance_top);
+ OPT_PTR(support_material_contact_distance_bottom);
OPT_PTR(support_material_enforce_layers);
OPT_PTR(support_material_interface_contact_loops);
OPT_PTR(support_material_extruder);
@@ -441,11 +487,13 @@ protected:
OPT_PTR(support_material_pattern);
OPT_PTR(support_material_spacing);
OPT_PTR(support_material_speed);
+ OPT_PTR(support_material_solid_first_layer);
OPT_PTR(support_material_synchronize_layers);
OPT_PTR(support_material_xy_spacing);
OPT_PTR(support_material_threshold);
OPT_PTR(support_material_with_sheath);
OPT_PTR(xy_size_compensation);
+ OPT_PTR(hole_size_compensation);
OPT_PTR(wipe_into_objects);
}
};
@@ -458,24 +506,40 @@ public:
ConfigOptionFloat bridge_angle;
ConfigOptionInt bottom_solid_layers;
ConfigOptionFloat bridge_flow_ratio;
+ ConfigOptionFloat over_bridge_flow_ratio;
ConfigOptionFloat bridge_speed;
ConfigOptionBool ensure_vertical_shell_thickness;
- ConfigOptionEnum<InfillPattern> external_fill_pattern;
+ ConfigOptionEnum<InfillPattern> top_fill_pattern;
+ ConfigOptionEnum<InfillPattern> bottom_fill_pattern;
+ ConfigOptionBool enforce_full_fill_volume;
+ ConfigOptionFloat external_infill_margin;
+ ConfigOptionFloat bridged_infill_margin;
ConfigOptionFloatOrPercent external_perimeter_extrusion_width;
ConfigOptionFloatOrPercent external_perimeter_speed;
ConfigOptionBool external_perimeters_first;
+ ConfigOptionBool perimeter_loop;
+ ConfigOptionEnum<SeamPosition> perimeter_loop_seam;
ConfigOptionBool extra_perimeters;
+ ConfigOptionBool only_one_perimeter_top;
ConfigOptionFloat fill_angle;
ConfigOptionPercent fill_density;
ConfigOptionEnum<InfillPattern> fill_pattern;
+ ConfigOptionBool gap_fill;
ConfigOptionFloat gap_fill_speed;
ConfigOptionInt infill_extruder;
ConfigOptionFloatOrPercent infill_extrusion_width;
ConfigOptionInt infill_every_layers;
ConfigOptionFloatOrPercent infill_overlap;
ConfigOptionFloat infill_speed;
+ ConfigOptionBool infill_not_connected;
+ ConfigOptionBool infill_dense;
+ ConfigOptionEnum<DenseInfillAlgo> infill_dense_algo;
+ ConfigOptionBool infill_first;
// Detect bridging perimeters
ConfigOptionBool overhangs;
+ ConfigOptionBool no_perimeter_unsupported;
+ ConfigOptionInt min_perimeter_unsupported;
+ ConfigOptionBool noperi_bridge_only;
ConfigOptionInt perimeter_extruder;
ConfigOptionFloatOrPercent perimeter_extrusion_width;
ConfigOptionFloat perimeter_speed;
@@ -489,6 +553,7 @@ public:
ConfigOptionFloatOrPercent solid_infill_speed;
// Detect thin walls.
ConfigOptionBool thin_walls;
+ ConfigOptionFloatOrPercent thin_walls_min_width;
ConfigOptionFloatOrPercent top_infill_extrusion_width;
ConfigOptionInt top_solid_layers;
ConfigOptionFloatOrPercent top_solid_infill_speed;
@@ -500,23 +565,39 @@ protected:
OPT_PTR(bridge_angle);
OPT_PTR(bottom_solid_layers);
OPT_PTR(bridge_flow_ratio);
+ OPT_PTR(over_bridge_flow_ratio);
OPT_PTR(bridge_speed);
OPT_PTR(ensure_vertical_shell_thickness);
- OPT_PTR(external_fill_pattern);
+ OPT_PTR(top_fill_pattern);
+ OPT_PTR(bottom_fill_pattern);
+ OPT_PTR(enforce_full_fill_volume);
+ OPT_PTR(external_infill_margin);
+ OPT_PTR(bridged_infill_margin);
OPT_PTR(external_perimeter_extrusion_width);
OPT_PTR(external_perimeter_speed);
OPT_PTR(external_perimeters_first);
+ OPT_PTR(perimeter_loop);
+ OPT_PTR(perimeter_loop_seam);
OPT_PTR(extra_perimeters);
+ OPT_PTR(only_one_perimeter_top);
OPT_PTR(fill_angle);
OPT_PTR(fill_density);
OPT_PTR(fill_pattern);
+ OPT_PTR(gap_fill);
OPT_PTR(gap_fill_speed);
OPT_PTR(infill_extruder);
OPT_PTR(infill_extrusion_width);
OPT_PTR(infill_every_layers);
OPT_PTR(infill_overlap);
OPT_PTR(infill_speed);
+ OPT_PTR(infill_dense);
+ OPT_PTR(infill_not_connected);
+ OPT_PTR(infill_dense_algo);
+ OPT_PTR(infill_first);
OPT_PTR(overhangs);
+ OPT_PTR(no_perimeter_unsupported);
+ OPT_PTR(min_perimeter_unsupported);
+ OPT_PTR(noperi_bridge_only);
OPT_PTR(perimeter_extruder);
OPT_PTR(perimeter_extrusion_width);
OPT_PTR(perimeter_speed);
@@ -528,6 +609,7 @@ protected:
OPT_PTR(solid_infill_every_layers);
OPT_PTR(solid_infill_speed);
OPT_PTR(thin_walls);
+ OPT_PTR(thin_walls_min_width);
OPT_PTR(top_infill_extrusion_width);
OPT_PTR(top_solid_infill_speed);
OPT_PTR(top_solid_layers);
@@ -616,6 +698,7 @@ public:
ConfigOptionFloats filament_cooling_final_speed;
ConfigOptionStrings filament_ramming_parameters;
ConfigOptionBool gcode_comments;
+ ConfigOptionBool label_printed_objects;
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
ConfigOptionString layer_gcode;
ConfigOptionFloat max_print_speed;
@@ -628,6 +711,7 @@ public:
ConfigOptionFloats retract_lift;
ConfigOptionFloats retract_lift_above;
ConfigOptionFloats retract_lift_below;
+ ConfigOptionBools retract_lift_not_last_layer;
ConfigOptionFloats retract_restart_extra;
ConfigOptionFloats retract_restart_extra_toolchange;
ConfigOptionFloats retract_speed;
@@ -685,6 +769,7 @@ protected:
OPT_PTR(filament_cooling_final_speed);
OPT_PTR(filament_ramming_parameters);
OPT_PTR(gcode_comments);
+ OPT_PTR(label_printed_objects);
OPT_PTR(gcode_flavor);
OPT_PTR(layer_gcode);
OPT_PTR(max_print_speed);
@@ -697,6 +782,7 @@ protected:
OPT_PTR(retract_lift);
OPT_PTR(retract_lift_above);
OPT_PTR(retract_lift_below);
+ OPT_PTR(retract_lift_not_last_layer);
OPT_PTR(retract_restart_extra);
OPT_PTR(retract_restart_extra_toolchange);
OPT_PTR(retract_speed);
@@ -734,7 +820,10 @@ public:
ConfigOptionInts bed_temperature;
ConfigOptionFloat bridge_acceleration;
ConfigOptionInts bridge_fan_speed;
+ ConfigOptionInts top_fan_speed;
ConfigOptionFloat brim_width;
+ ConfigOptionBool brim_ears;
+ ConfigOptionFloat brim_ears_max_angle;
ConfigOptionBool complete_objects;
ConfigOptionFloats colorprint_heights;
ConfigOptionBools cooling;
@@ -753,9 +842,9 @@ public:
ConfigOptionInts first_layer_bed_temperature;
ConfigOptionFloatOrPercent first_layer_extrusion_width;
ConfigOptionFloatOrPercent first_layer_speed;
+ ConfigOptionFloatOrPercent first_layer_infill_speed;
ConfigOptionInts first_layer_temperature;
ConfigOptionFloat infill_acceleration;
- ConfigOptionBool infill_first;
ConfigOptionInts max_fan_speed;
ConfigOptionFloats max_layer_height;
ConfigOptionInts min_fan_speed;
@@ -812,7 +901,10 @@ protected:
OPT_PTR(bed_temperature);
OPT_PTR(bridge_acceleration);
OPT_PTR(bridge_fan_speed);
+ OPT_PTR(top_fan_speed);
OPT_PTR(brim_width);
+ OPT_PTR(brim_ears);
+ OPT_PTR(brim_ears_max_angle);
OPT_PTR(complete_objects);
OPT_PTR(colorprint_heights);
OPT_PTR(cooling);
@@ -831,9 +923,9 @@ protected:
OPT_PTR(first_layer_bed_temperature);
OPT_PTR(first_layer_extrusion_width);
OPT_PTR(first_layer_speed);
+ OPT_PTR(first_layer_infill_speed);
OPT_PTR(first_layer_temperature);
OPT_PTR(infill_acceleration);
- OPT_PTR(infill_first);
OPT_PTR(max_fan_speed);
OPT_PTR(max_layer_height);
OPT_PTR(min_fan_speed);
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index d516153a9..bacdd5bb9 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -331,11 +331,24 @@ void PrintObject::prepare_infill()
// to remove only half of the combined infill
this->bridge_over_infill();
m_print->throw_if_canceled();
+ this->replaceSurfaceType(stInternalSolid, stInternalOverBridge, stInternalBridge);
+ m_print->throw_if_canceled();
+ this->replaceSurfaceType(stInternalSolid, stInternalOverBridge, stBottomBridge);
+ m_print->throw_if_canceled();
+ this->replaceSurfaceType(stTop, stTopOverBridge, stInternalBridge);
+ m_print->throw_if_canceled();
+ this->replaceSurfaceType(stTop, stTopOverBridge, stBottomBridge);
+ m_print->throw_if_canceled();
// combine fill surfaces to honor the "infill every N layers" option
this->combine_infill();
m_print->throw_if_canceled();
+ // count the distance from the nearest top surface, to allow to use denser infill
+ // if needed and if infill_dense_layers is positive.
+ this->count_distance_solid();
+ m_print->throw_if_canceled();
+
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
for (const Layer *layer : m_layers) {
@@ -442,25 +455,38 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
for (const t_config_option_key &opt_key : opt_keys) {
if ( opt_key == "perimeters"
|| opt_key == "extra_perimeters"
+ || opt_key == "gap_fill"
|| opt_key == "gap_fill_speed"
|| opt_key == "overhangs"
|| opt_key == "first_layer_extrusion_width"
|| opt_key == "perimeter_extrusion_width"
|| opt_key == "infill_overlap"
|| opt_key == "thin_walls"
- || opt_key == "external_perimeters_first") {
+ || opt_key == "thin_walls_min_width"
+ || opt_key == "external_perimeters_first"
+ || opt_key == "perimeter_loop"
+ || opt_key == "perimeter_loop_seam"
+ || opt_key == "no_perimeter_unsupported"
+ || opt_key == "min_perimeter_unsupported"
+ || opt_key == "noperi_bridge_only") {
steps.emplace_back(posPerimeters);
} else if (
opt_key == "layer_height"
|| opt_key == "first_layer_height"
+ || opt_key == "exact_last_layer_height"
|| opt_key == "raft_layers") {
steps.emplace_back(posSlice);
- }
- else if (
+ }
+ else if (
opt_key == "clip_multipart_objects"
|| opt_key == "elefant_foot_compensation"
- || opt_key == "support_material_contact_distance"
- || opt_key == "xy_size_compensation") {
+ || opt_key == "support_material_contact_distance_type"
+ || opt_key == "support_material_contact_distance_top"
+ || opt_key == "support_material_contact_distance_bottom"
+ || opt_key == "xy_size_compensation"
+ || opt_key == "external_infill_margin"
+ || opt_key == "bridged_infill_margin"
+ || opt_key == "hole_size_compensation") {
steps.emplace_back(posSlice);
} else if (
opt_key == "support_material"
@@ -481,13 +507,17 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "support_material_threshold"
|| opt_key == "support_material_with_sheath"
|| opt_key == "dont_support_bridges"
- || opt_key == "first_layer_extrusion_width") {
+ || opt_key == "first_layer_extrusion_width"
+ || opt_key == "support_material_solid_first_layer") {
steps.emplace_back(posSupportMaterial);
} else if (
opt_key == "interface_shells"
|| opt_key == "infill_only_where_needed"
|| opt_key == "infill_every_layers"
|| opt_key == "solid_infill_every_layers"
+ || opt_key == "infill_dense"
+ || opt_key == "infill_not_connected"
+ || opt_key == "infill_dense_algo"
|| opt_key == "bottom_solid_layers"
|| opt_key == "top_solid_layers"
|| opt_key == "solid_infill_below_area"
@@ -498,7 +528,9 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "bridge_angle") {
steps.emplace_back(posPrepareInfill);
} else if (
- opt_key == "external_fill_pattern"
+ opt_key == "top_fill_pattern"
+ || opt_key == "bottom_fill_pattern"
+ || opt_key == "enforce_full_fill_volume"
|| opt_key == "external_fill_link_max_length"
|| opt_key == "fill_angle"
|| opt_key == "fill_pattern"
@@ -521,6 +553,7 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
steps.emplace_back(posInfill);
} else if (
opt_key == "seam_position"
+ || opt_key == "seam_travel"
|| opt_key == "seam_preferred_direction"
|| opt_key == "seam_preferred_direction_jitter"
|| opt_key == "support_material_speed"
@@ -590,6 +623,257 @@ bool PrintObject::has_support_material() const
|| m_config.support_material_enforce_layers > 0;
}
+// Function used by fit_to_size.
+// It check if polygon_to_check can be decimated, using only point into allowedPoints and also cover polygon_to_cover
+ExPolygon try_fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, const ExPolygons &allowedPoints) {
+
+ ExPolygon polygon_reduced = polygon_to_check;
+ size_t pos_check = 0;
+ bool has_del = false;
+ while ( (polygon_reduced.contour.points.begin() + pos_check) != polygon_reduced.contour.points.end()) {
+ bool ok = false;
+ for (ExPolygon poly : allowedPoints) {
+ if (poly.contains_b(*(polygon_reduced.contour.points.begin() + pos_check))) {
+ ok = true;
+ has_del = true;
+ break;
+ }
+ }
+ if (ok) ++pos_check;
+ else polygon_reduced.contour.points.erase(polygon_reduced.contour.points.begin() + pos_check);
+ }
+ if (has_del) polygon_reduced.holes.clear();
+ return polygon_reduced;
+}
+
+// find one of the smallest polygon, growing polygon_to_check, only using point into allowedPoints and covering polygon_to_cover.
+ExPolygons fit_to_size(ExPolygon polygon_to_cover, ExPolygon polygon_to_check, const ExPolygons &allowedPoints,
+ const ExPolygon &growing_area, const coord_t offset, float coverage) {
+
+ //grow the polygon_to_check enough to cover polygon_to_cover
+ float current_coverage = coverage;
+ coord_t previous_offset = 0;
+ coord_t current_offset = offset;
+ ExPolygon polygon_reduced = try_fit_to_size(polygon_to_cover, polygon_to_check, allowedPoints);
+ while (!diff_ex(polygon_to_cover, polygon_reduced).empty()){
+ //not enough, use a bigger offset
+ float percent_coverage = polygon_reduced.area() / growing_area.area();
+ float next_coverage = percent_coverage + (percent_coverage - current_coverage) * 4;
+ previous_offset = current_offset;
+ current_offset *= 2;
+ if (next_coverage < 0.1) current_offset *= 2;
+ //create the bigger polygon and test it
+ ExPolygons bigger_polygon = offset_ex(polygon_to_check, current_offset);
+ if (bigger_polygon.size() != 1) {
+ // Error, growing a single polygon result in many/no other => fallback to full coverage
+ return ExPolygons({ growing_area });
+ }
+ bigger_polygon = intersection_ex(bigger_polygon[0], growing_area);
+ if (bigger_polygon.size() != 1 || bigger_polygon[0].area() > growing_area.area()) {
+ // Growing too much => we can as well use the full coverage, in this case
+ return ExPolygons() = { growing_area };
+ }
+ polygon_reduced = try_fit_to_size(polygon_to_cover, bigger_polygon[0], allowedPoints);
+ }
+ //ok, we have a good one, now try to optimise (unless there are almost no growth)
+ if (current_offset > offset * 3){
+ //try to shrink
+ uint32_t nb_opti_max = 6;
+ for (uint32_t i = 0; i < nb_opti_max; ++i){
+ coord_t new_offset = (previous_offset + current_offset) / 2;
+ ExPolygons bigger_polygon = offset_ex(polygon_to_check, new_offset);
+ if (bigger_polygon.size() != 1) {
+ //Warn, growing a single polygon result in many/no other, use previous good result
+ break;
+ }
+ bigger_polygon = intersection_ex(bigger_polygon[0], growing_area);
+ if (bigger_polygon.size() != 1 || bigger_polygon[0].area() > growing_area.area()) {
+ //growing too much, use previous good result (imo, should not be possible to enter this branch)
+ break;
+ }
+ ExPolygon polygon_test = try_fit_to_size(polygon_to_cover, bigger_polygon[0], allowedPoints);
+ if (!diff_ex(polygon_to_cover, polygon_test).empty()){
+ //bad, not enough, use a bigger offset
+ previous_offset = new_offset;
+ }
+ else {
+ //good, we may now try a smaller offset
+ current_offset = new_offset;
+ polygon_reduced = polygon_test;
+ }
+ }
+ }
+
+ //return the area which cover the growing_area. Intersect it to retreive the holes.
+ return intersection_ex(polygon_reduced, growing_area);
+}
+
+void PrintObject::count_distance_solid() {
+ //if dense area * COEFF_SPLIT > sparse area then fill all with dense
+ // sparse area = layer's fill area - solid area
+ const float COEFF_SPLIT = 2;
+ const int NB_DENSE_LAYERS = 1;
+ for (size_t idx_region = 0; idx_region < this->m_print->regions().size(); ++idx_region) {
+ //count how many surface there are on each one
+ LayerRegion *previousOne = NULL;
+ if (this->layers().size() > 1) previousOne = this->layers()[this->layers().size() - 1]->get_region(idx_region);
+ if (previousOne != NULL && previousOne->region()->config().infill_dense.getBool() && previousOne->region()->config().fill_density<40) {
+ for (Surface &surf : previousOne->fill_surfaces.surfaces) {
+ if (surf.is_solid()) {
+ surf.maxNbSolidLayersOnTop = 0;
+ }
+ }
+ for (size_t idx_layer = this->layers().size() - 2; idx_layer < this->layers().size() - 1; --idx_layer) {
+ LayerRegion *layerm = this->layers()[idx_layer]->get_region(idx_region);
+ Surfaces surf_to_add;
+ for (Surface &surf : layerm->fill_surfaces.surfaces) {
+ if (!surf.is_solid()){
+ surf.maxNbSolidLayersOnTop = 30000;
+ uint16_t dense_dist = 30000;
+ ExPolygons dense_polys;
+ ExPolygons sparse_polys = { surf.expolygon };
+ //find the surface which intersect with the smalle maxNb possible
+ for (Surface &upp : previousOne->fill_surfaces.surfaces) {
+ // i'm using intersection_ex because the result different than
+ // upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon)
+ ExPolygons intersect = intersection_ex(sparse_polys, offset_ex(upp.expolygon, -layerm->flow(frInfill).scaled_width()), true);
+ if (!intersect.empty()) {
+ if (layerm->region()->config().infill_dense_algo == dfaEnlarged) {
+ uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1);
+ const int nb_dense_layers = 1;
+ if (dist <= nb_dense_layers) {
+ // it will be a dense infill, split the surface if needed
+ uint64_t area_intersect = 0;
+ for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area();
+ //if it's in a dense area and the current surface isn't a dense one yet and the not-dense is too small.
+ if ((surf.area() > area_intersect * COEFF_SPLIT) &&
+ surf.maxNbSolidLayersOnTop > nb_dense_layers) {
+ //split in two
+ if (dist == 1) {
+ //if just under the solid area, we can expand a bit
+ //remove too small sections and grew a bit to anchor it into the part
+ intersect = offset_ex(intersect, layerm->flow(frInfill).scaled_width() + scale_(layerm->region()->config().bridged_infill_margin));
+ } else {
+ //just remove too small sections
+ intersect = offset_ex(intersect,
+ layerm->flow(frInfill).scaled_width());
+ }
+ if (!intersect.empty()) {
+ ExPolygons sparse_surfaces = offset2_ex(
+ diff_ex(sparse_polys, intersect, true),
+ -layerm->flow(frInfill).scaled_width(),
+ layerm->flow(frInfill).scaled_width());
+ ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
+ //assign (copy)
+ sparse_polys.clear();
+ sparse_polys.insert(sparse_polys.begin(), sparse_surfaces.begin(), sparse_surfaces.end());
+ dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end());
+ dense_dist = std::min(dense_dist, dist);
+ }
+ } else {
+ surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
+ }
+ } else {
+ surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
+ }
+ } else if (layerm->region()->config().infill_dense_algo == dfaAutoNotFull || layerm->region()->config().infill_dense_algo == dfaAutomatic) {
+ double area_intersect = 0;
+ for (ExPolygon poly_inter : intersect) area_intersect += poly_inter.area();
+ //like intersect.empty() but more resilient
+ if (area_intersect > layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2) {
+ uint16_t dist = (uint16_t)(upp.maxNbSolidLayersOnTop + 1);
+ if (dist <= NB_DENSE_LAYERS) {
+ // it will be a dense infill, split the surface if needed
+ //if the not-dense is too big to do a full dense and the current surface isn't a dense one yet.
+ if ((layerm->region()->config().infill_dense_algo == dfaAutomatic || surf.area() > area_intersect * COEFF_SPLIT) &&
+ surf.maxNbSolidLayersOnTop > NB_DENSE_LAYERS) {
+ //split in two
+ if (dist == 1) {
+ //if just under the solid area, we can expand a bit
+ ExPolygons cover_intersect;
+ for (ExPolygon &expoly_tocover : intersect) {
+ ExPolygons temp = (fit_to_size(expoly_tocover, expoly_tocover,
+ diff_ex(offset_ex(layerm->fill_no_overlap_expolygons, layerm->flow(frInfill).scaled_width()),
+ offset_ex(layerm->fill_no_overlap_expolygons, -layerm->flow(frInfill).scaled_width())),
+ surf.expolygon,
+ 4 * layerm->flow(frInfill).scaled_width(), 0.01));
+ cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end());
+ }
+ intersect = offset_ex(cover_intersect,
+ layerm->flow(frInfill).scaled_width());// +scale_(expandby));
+ //layerm->region()->config().external_infill_margin));
+ } else {
+ //just remove too small sections
+ intersect = offset_ex(intersect,
+ layerm->flow(frInfill).scaled_width());
+ }
+ if (!intersect.empty()) {
+ ExPolygons sparse_surfaces = offset2_ex(
+ diff_ex(sparse_polys, intersect, true),
+ -layerm->flow(frInfill).scaled_width(),
+ layerm->flow(frInfill).scaled_width());
+ ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
+ //assign (copy)
+ sparse_polys.clear();
+ sparse_polys.insert(sparse_polys.begin(), sparse_surfaces.begin(), sparse_surfaces.end());
+ dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end());
+ dense_dist = std::min(dense_dist, dist);
+ }
+ } else {
+ if (area_intersect < layerm->flow(frInfill).scaled_width() * layerm->flow(frInfill).scaled_width() * 2)
+ surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
+ }
+ } else {
+ surf.maxNbSolidLayersOnTop = std::min(surf.maxNbSolidLayersOnTop, dist);
+ }
+ }
+ }
+ }
+ }
+ //check if we need to split the surface
+ if (dense_dist != 30000) {
+ double area_dense = 0;
+ for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area();
+ double area_sparse = 0;
+ for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area();
+ if (area_sparse > area_dense * COEFF_SPLIT) {
+ //split
+ dense_polys = union_ex(dense_polys);
+ for (ExPolygon dense_poly : dense_polys) {
+ Surface dense_surf(surf, dense_poly);
+ dense_surf.maxNbSolidLayersOnTop = dense_dist;
+ surf_to_add.push_back(dense_surf);
+ }
+ sparse_polys = union_ex(sparse_polys);
+ for (ExPolygon sparse_poly : sparse_polys) {
+ Surface sparse_surf(surf, sparse_poly);
+ surf_to_add.push_back(sparse_surf);
+ }
+ //layerm->fill_surfaces.surfaces.erase(it_surf);
+ } else {
+ surf.maxNbSolidLayersOnTop = dense_dist;
+ surf_to_add.push_back(surf);
+ }
+ } else {
+ surf_to_add.push_back(surf);
+ }
+ } else {
+ surf.maxNbSolidLayersOnTop = 0;
+ surf_to_add.push_back(surf);
+ }
+ }
+ //if (!surf_to_add.empty()) {
+ // layerm->fill_surfaces.surfaces.insert(layerm->fill_surfaces.surfaces.begin(), surf_to_add.begin(), surf_to_add.end());
+ //}
+ layerm->fill_surfaces.surfaces.clear();
+ layerm->fill_surfaces.surfaces.insert(layerm->fill_surfaces.surfaces.begin(), surf_to_add.begin(), surf_to_add.end());
+ previousOne = layerm;
+ }
+ }
+ }
+}
+
+
// This function analyzes slices of a region (SurfaceCollection slices).
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
// Initially all slices are of type stInternal.
@@ -628,12 +912,12 @@ void PrintObject::detect_surfaces_type()
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
// If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void.
SurfaceType surface_type_bottom_1st =
- (m_config.raft_layers.value > 0 && m_config.support_material_contact_distance.value > 0) ?
+ (m_config.raft_layers.value > 0 && m_config.support_material_contact_distance_type.value != zdNone) ?
stBottomBridge : stBottom;
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print.
SurfaceType surface_type_bottom_other =
- (m_config.support_material.value && m_config.support_material_contact_distance.value == 0) ?
+ (m_config.support_material.value && m_config.support_material_contact_distance_type.value == zdNone) ?
stBottom : stBottomBridge;
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
m_print->throw_if_canceled();
@@ -644,6 +928,7 @@ void PrintObject::detect_surfaces_type()
// unless internal shells are requested
Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
Layer *lower_layer = (idx_layer > 0) ? m_layers[idx_layer - 1] : nullptr;
+ Layer *under_lower_layer = (idx_layer > 1) ? this->layers()[idx_layer - 2] : nullptr;
// collapse very narrow parts (using the safety offset in the diff is not enough)
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
@@ -731,6 +1016,7 @@ void PrintObject::detect_surfaces_type()
std::vector<std::pair<Slic3r::ExPolygons, SVG::ExPolygonAttributes>> expolygons_with_attributes;
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(top), SVG::ExPolygonAttributes("green")));
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottom), SVG::ExPolygonAttributes("brown")));
+ expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottomOverBridge), SVG::ExPolygonAttributes("grey")));
expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black")));
SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes);
}
@@ -969,8 +1255,8 @@ void PrintObject::discover_vertical_shells()
PROFILE_BLOCK(discover_vertical_shells_region_layer);
m_print->throw_if_canceled();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- static size_t debug_idx = 0;
- ++ debug_idx;
+ static size_t debug_idx = 0;
+ ++ debug_idx;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
Layer *layer = m_layers[idx_layer];
@@ -995,13 +1281,13 @@ void PrintObject::discover_vertical_shells()
#if 0
// #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
- Slic3r::SVG svg_cummulative(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d.svg", debug_idx), this->bounding_box());
+ Slic3r::SVG svg_cummulative(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d.svg", debug_idx), this->bounding_box());
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n) {
if (n < 0 || n >= (int)m_layers.size())
continue;
ExPolygons &expolys = m_layers[n]->perimeter_expolygons;
for (size_t i = 0; i < expolys.size(); ++ i) {
- Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", debug_idx, n, i), get_extents(expolys[i]));
+ Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", debug_idx, n, i), get_extents(expolys[i]));
svg.draw(expolys[i]);
svg.draw_outline(expolys[i].contour, "black", scale_(0.05));
svg.draw_outline(expolys[i].holes, "blue", scale_(0.05));
@@ -1041,7 +1327,7 @@ void PrintObject::discover_vertical_shells()
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
- Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-%d.svg", debug_idx), get_extents(shell));
+ Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-%d.svg", debug_idx), get_extents(shell));
svg.draw(shell);
svg.draw_outline(shell, "black", scale_(0.05));
svg.Close();
@@ -1168,8 +1454,8 @@ void PrintObject::discover_vertical_shells()
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal-%d.svg", debug_idx), get_extents(shell), new_internal, "black", "blue", scale_(0.05));
- SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_void-%d.svg", debug_idx), get_extents(shell), new_internal_void, "black", "blue", scale_(0.05));
- SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_solid-%d.svg", debug_idx), get_extents(shell), new_internal_solid, "black", "blue", scale_(0.05));
+ SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_void-%d.svg", debug_idx), get_extents(shell), new_internal_void, "black", "blue", scale_(0.05));
+ SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_solid-%d.svg", debug_idx), get_extents(shell), new_internal_solid, "black", "blue", scale_(0.05));
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
@@ -1327,6 +1613,167 @@ void PrintObject::bridge_over_infill()
}
}
+/* This method applies overextrude flow to the first internal solid layer above
+ bridge (which is over sparse infill) note: it's almost complete copy/paste from the method behind,
+ i think it should be merged before gitpull that.
+ */
+void PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_replacement, SurfaceType st_under_it)
+{
+ BOOST_LOG_TRIVIAL(info) << "overextrude over Bridge...";
+
+ for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
+ const PrintRegion &region = *m_print->regions()[region_id];
+
+ for (LayerPtrs::iterator layer_it = m_layers.begin(); layer_it != m_layers.end(); ++layer_it) {
+
+ // skip first layer
+ if (layer_it == this->layers().begin()) continue;
+
+ Layer* layer = *layer_it;
+ LayerRegion* layerm = layer->regions()[region_id];
+
+ // extract the stInternalSolid surfaces that might be transformed into bridges
+ Polygons internal_solid;
+ layerm->fill_surfaces.filter_by_type(st_to_replace, &internal_solid);
+
+ double internsolidareainit=0;
+ for (ExPolygon &ex : union_ex(internal_solid)) internsolidareainit+=ex.area();
+
+ Polygons internal_over_tot_init;
+ layerm->fill_surfaces.filter_by_type(st_replacement, &internal_over_tot_init);
+ double totoverareaInit=0;
+ for (ExPolygon &ex : union_ex(internal_over_tot_init)) totoverareaInit+=ex.area();
+
+ Polygons stBottom_init;
+ layerm->fill_surfaces.filter_by_type(stBottom, &stBottom_init);
+ double bottomeareainit=0;
+ for (ExPolygon &ex : union_ex(stBottom_init)) bottomeareainit+=ex.area();
+
+ Polygons stBottomBridge_init;
+ layerm->fill_surfaces.filter_by_type(stBottomBridge, &stBottomBridge_init);
+ double bottombridgearea=0;
+ for (ExPolygon &ex : union_ex(stBottomBridge_init)) bottombridgearea+=ex.area();
+
+ Polygons stIntBridge_init;
+ layerm->fill_surfaces.filter_by_type(st_under_it, &stIntBridge_init);
+ double intbridgeareainit=0;
+ for (ExPolygon &ex : union_ex(stIntBridge_init)) intbridgeareainit+=ex.area();
+
+ // check whether the lower area is deep enough for absorbing the extra flow
+ // (for obvious physical reasons but also for preventing the bridge extrudates
+ // from overflowing in 3D preview)
+ ExPolygons to_overextrude;
+ {
+ Polygons to_overextrude_pp = internal_solid;
+
+ // get previous layer
+ if (int(layer_it - this->layers().begin()) - 1 >= 0) {
+ const Layer* lower_layer = this->layers()[int(layer_it - this->layers().begin()) - 1];
+
+ // iterate through regions and collect internal surfaces
+ Polygons lower_internal;
+ for (LayerRegion *lower_layerm : lower_layer->m_regions) {
+ lower_layerm->fill_surfaces.filter_by_type(stInternal, &lower_internal);
+ Polygons lower_internal_OK;
+ Polygons lower_internal_Bridge;
+ Polygons lower_internal_Over;
+ lower_layerm->fill_surfaces.filter_by_type(st_replacement, &lower_internal_OK);
+ lower_layerm->fill_surfaces.filter_by_type(st_under_it, &lower_internal_Bridge);
+ lower_layerm->fill_surfaces.filter_by_type(st_to_replace, &lower_internal_Over);
+ double okarea =0, bridgearea=0, overarea=0;
+ for (ExPolygon &ex : union_ex(lower_internal_OK)) okarea+=ex.area();
+ for (ExPolygon &ex : union_ex(lower_internal_Bridge)) bridgearea+=ex.area();
+ for (ExPolygon &ex : union_ex(lower_internal_Over)) overarea+=ex.area();
+
+ lower_layerm->fill_surfaces.filter_by_type(st_under_it, &lower_internal);
+ }
+ double sumarea=0;
+ for (ExPolygon &ex : union_ex(lower_internal)) sumarea+=ex.area();
+
+ // intersect such lower internal surfaces with the candidate solid surfaces
+ to_overextrude_pp = intersection(to_overextrude_pp, lower_internal);
+ }
+
+ // there's no point in overextruding too thin/short regions
+ //FIXME Vojtech: The offset2 function is not a geometric offset,
+ // therefore it may create 1) gaps, and 2) sharp corners, which are outside the original contour.
+ // The gaps will be filled by a separate region, which makes the infill less stable and it takes longer.
+ // {
+ // float min_width = float(bridge_flow.scaled_width()) * 3.f;
+ // to_overextrude_pp = offset2(to_overextrude_pp, -min_width, +min_width);
+ // }
+
+ if (to_overextrude_pp.empty()) continue;
+
+ // convert into ExPolygons
+ to_overextrude = union_ex(to_overextrude_pp);
+ }
+
+ #ifdef SLIC3R_DEBUG
+ printf("Bridging " PRINTF_ZU " internal areas at layer " PRINTF_ZU "\n", to_overextrude.size(), layer->id());
+ #endif
+
+ // compute the remaning internal solid surfaces as difference
+ ExPolygons not_to_overextrude = diff_ex(internal_solid, to_polygons(to_overextrude), true);
+ to_overextrude = intersection_ex(to_polygons(to_overextrude), internal_solid, true);
+ // build the new collection of fill_surfaces
+ layerm->fill_surfaces.remove_type(st_to_replace);
+ double overareafinal = 0, solidareafinal=0;
+ for (ExPolygon &ex : to_overextrude){
+ overareafinal += ex.area();
+ layerm->fill_surfaces.surfaces.push_back(Surface(st_replacement, ex));
+ }
+ for (ExPolygon &ex : not_to_overextrude){
+ solidareafinal += ex.area();
+ layerm->fill_surfaces.surfaces.push_back(Surface(st_to_replace, ex));
+ }
+ Polygons internal_over_tot;
+ layerm->fill_surfaces.filter_by_type(stInternalOverBridge, &internal_over_tot);
+ double totoverarea=0;
+ for (ExPolygon &ex : union_ex(internal_over_tot)) totoverarea+=ex.area();
+
+ /*
+ # exclude infill from the layers below if needed
+ # see discussion at https://github.com/alexrj/Slic3r/issues/240
+ # Update: do not exclude any infill. Sparse infill is able to absorb the excess material.
+ if (0) {
+ my $excess = $layerm->extruders->{infill}->bridge_flow->width - $layerm->height;
+ for (my $i = $layer_id-1; $excess >= $self->get_layer($i)->height; $i--) {
+ Slic3r::debugf " skipping infill below those areas at layer %d\n", $i;
+ foreach my $lower_layerm (@{$self->get_layer($i)->regions}) {
+ my @new_surfaces = ();
+ # subtract the area from all types of surfaces
+ foreach my $group (@{$lower_layerm->fill_surfaces->group}) {
+ push @new_surfaces, map $group->[0]->clone(expolygon => $_),
+ @{diff_ex(
+ [ map $_->p, @$group ],
+ [ map @$_, @$to_overextrude ],
+ )};
+ push @new_surfaces, map Slic3r::Surface->new(
+ expolygon => $_,
+ surface_type => S_TYPE_INTERNALVOID,
+ ), @{intersection_ex(
+ [ map $_->p, @$group ],
+ [ map @$_, @$to_overextrude ],
+ )};
+ }
+ $lower_layerm->fill_surfaces->clear;
+ $lower_layerm->fill_surfaces->append($_) for @new_surfaces;
+ }
+
+ $excess -= $self->get_layer($i)->height;
+ }
+ }
+ */
+
+#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
+ layerm->export_region_slices_to_svg_debug("7_overextrude_over_bridge");
+ layerm->export_region_fill_surfaces_to_svg_debug("7_overextrude_over_bridge");
+#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
+ }
+ }
+}
+
static void clamp_exturder_to_default(ConfigOptionInt &opt, size_t num_extruders)
{
if (opt.value > (int)num_extruders)
@@ -1529,8 +1976,8 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
goto end;
delete layer;
m_layers.pop_back();
- if (! m_layers.empty())
- m_layers.back()->upper_layer = nullptr;
+ if (! m_layers.empty())
+ m_layers.back()->upper_layer = nullptr;
}
m_print->throw_if_canceled();
end:
@@ -1545,8 +1992,9 @@ end:
Layer *layer = m_layers[layer_id];
// Apply size compensation and perform clipping of multi-part objects.
float delta = float(scale_(m_config.xy_size_compensation.value));
+ float hole_delta = float(scale_(this->config().hole_size_compensation.value));
if (layer_id == 0)
- delta -= float(scale_(m_config.elefant_foot_compensation.value));
+ delta += float(scale_(m_config.elefant_foot_compensation.value));
bool scale = delta != 0.f;
bool clip = m_config.clip_multipart_objects.value || delta > 0.f;
if (layer->m_regions.size() == 1) {
@@ -1555,15 +2003,16 @@ end:
LayerRegion *layerm = layer->m_regions.front();
layerm->slices.set(offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta), stInternal);
}
- } else if (scale || clip) {
+ _offsetHoles(hole_delta, layer->regions().front());
+ } else if (scale || clip || hole_delta != 0.f) {
// Multiple regions, growing, shrinking or just clipping one region by the other.
// When clipping the regions, priority is given to the first regions.
Polygons processed;
- for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) {
+ for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) {
LayerRegion *layerm = layer->m_regions[region_id];
- ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces));
- if (scale)
- slices = offset_ex(slices, delta);
+ ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces));
+ if (scale)
+ slices = offset_ex(slices, delta);
if (region_id > 0 && clip)
// Trim by the slices of already processed regions.
slices = diff_ex(to_polygons(std::move(slices)), processed);
@@ -1571,6 +2020,7 @@ end:
// Collect the already processed regions to trim the to be processed regions.
polygons_append(processed, slices);
layerm->slices.set(std::move(slices), stInternal);
+ _offsetHoles(hole_delta, layerm);
}
}
// Merge all regions' slices to get islands, chain them by a shortest path.
@@ -1581,6 +2031,45 @@ end:
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end";
}
+void PrintObject::_offsetHoles(float hole_delta, LayerRegion *layerm) {
+ if (hole_delta != 0.f) {
+ ExPolygons& polys = to_expolygons(std::move(layerm->slices.surfaces));
+ ExPolygons new_polys;
+ for (ExPolygon ex_poly : polys) {
+ ExPolygon new_ex_poly(ex_poly);
+ new_ex_poly.holes.clear();
+ for (Polygon hole : ex_poly.holes) {
+ //check if convex to reduce it
+ // check whether first point forms a convex angle
+ bool ok = true;
+ ok = (hole.points.front().ccw_angle(hole.points.back(), *(hole.points.begin() + 1)) <= PI + 0.001);
+
+
+ // check whether points 1..(n-1) form convex angles
+ if (ok)
+ for (Points::const_iterator p = hole.points.begin() + 1; p != hole.points.end() - 1; ++p) {
+ ok = (p->ccw_angle(*(p - 1), *(p + 1)) <= PI + 0.001);
+ if (!ok) break;
+ }
+
+ // check whether last point forms a convex angle
+ ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.001);
+
+ if (ok) {
+ for (Polygon newHole : offset(hole, -hole_delta)) {
+ //reverse because it's a hole, not an object
+ newHole.make_clockwise();
+ new_ex_poly.holes.push_back(newHole);
+ }
+ } else
+ new_ex_poly.holes.push_back(hole);
+ }
+ new_polys.push_back(new_ex_poly);
+ }
+ layerm->slices.set(std::move(new_polys), stInternal);
+ }
+}
+
std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::vector<float> &z, bool modifier)
{
std::vector<const ModelVolume*> volumes;
@@ -1974,7 +2463,7 @@ void PrintObject::discover_horizontal_shells()
// not work in some situations, as there won't be any grown region in the perimeter
// area (this was seen in a model where the top layer had one extra perimeter, thus
// its fill_surfaces were thinner than the lower layer's infill), however it's the best
- // solution so far. Growing the external slices by EXTERNAL_INFILL_MARGIN will put
+ // solution so far. Growing the external slices by external_infill_margin will put
// too much solid infill inside nearly-vertical slopes.
// Surfaces including the area of perimeters. Everything, that is visible from the top / bottom
@@ -1992,8 +2481,8 @@ void PrintObject::discover_horizontal_shells()
continue;
// Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom';
- size_t solid_layers = (type == stTop) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value;
- for (int n = (type == stTop) ? i-1 : i+1; std::abs(n - i) < solid_layers; (type == stTop) ? -- n : ++ n) {
+ size_t solid_layers = (type == stTop || type == stTopOverBridge) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value;
+ for (int n = (type == stTop || type == stTopOverBridge) ? i-1 : i+1; std::abs(n - i) < solid_layers; (type == stTop || type == stTopOverBridge) ? -- n : ++ n) {
if (n < 0 || n >= int(m_layers.size()))
continue;
// Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
@@ -2114,7 +2603,7 @@ void PrintObject::discover_horizontal_shells()
// Use an existing surface as a template, it carries the bridge angle etc.
*group.front());
}
- EXTERNAL:;
+ EXTERNAL:;
} // foreach type (stTop, stBottom, stBottomBridge)
} // for each layer
} // for each region
@@ -2177,12 +2666,12 @@ void PrintObject::combine_infill()
for (size_t layer_idx = 0; layer_idx < m_layers.size(); ++ layer_idx) {
m_print->throw_if_canceled();
size_t num_layers = combine[layer_idx];
- if (num_layers <= 1)
+ if (num_layers <= 1)
continue;
// Get all the LayerRegion objects to be combined.
std::vector<LayerRegion*> layerms;
layerms.reserve(num_layers);
- for (size_t i = layer_idx + 1 - num_layers; i <= layer_idx; ++ i)
+ for (size_t i = layer_idx + 1 - num_layers; i <= layer_idx; ++ i)
layerms.emplace_back(m_layers[i]->regions()[region_id]);
// We need to perform a multi-layer intersection, so let's split it in pairs.
// Initialize the intersection with the candidates of the lowest layer.
diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp
index b3e314549..f0647736a 100644
--- a/src/libslic3r/Slicing.cpp
+++ b/src/libslic3r/Slicing.cpp
@@ -57,7 +57,7 @@ SlicingParameters SlicingParameters::create_from_config(
// In that case all the nozzles have to be of the same diameter.
coordf_t support_material_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_material_extruder.value - 1);
coordf_t support_material_interface_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_material_interface_extruder.value - 1);
- bool soluble_interface = object_config.support_material_contact_distance.value == 0.;
+ bool soluble_interface = object_config.support_material_contact_distance_type.value == zdNone;
SlicingParameters params;
params.layer_height = object_config.layer_height.value;
@@ -71,6 +71,7 @@ SlicingParameters SlicingParameters::create_from_config(
// Miniumum/maximum of the minimum layer height over all extruders.
params.min_layer_height = MIN_LAYER_HEIGHT;
params.max_layer_height = std::numeric_limits<double>::max();
+ params.exact_last_layer_height = object_config.exact_last_layer_height.value;
if (object_config.support_material.value || params.base_raft_layers > 0) {
// Has some form of support. Add the support layers to the minimum / maximum layer height limits.
params.min_layer_height = std::max(
@@ -94,9 +95,9 @@ SlicingParameters SlicingParameters::create_from_config(
params.max_layer_height = std::max(params.max_layer_height, params.layer_height);
if (! soluble_interface) {
- params.gap_raft_object = object_config.support_material_contact_distance.value;
- params.gap_object_support = object_config.support_material_contact_distance.value;
- params.gap_support_object = object_config.support_material_contact_distance.value;
+ params.gap_raft_object = object_config.support_material_contact_distance_top.value;
+ params.gap_object_support = object_config.support_material_contact_distance_bottom.value;
+ params.gap_support_object = object_config.support_material_contact_distance_top.value;
}
if (params.base_raft_layers > 0) {
@@ -216,6 +217,7 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
// Based on the work of @platsch
// Fill layer_height_profile by heights ensuring a prescribed maximum cusp height.
+// @Deprecated not used anymore (see PrintObject::update_layer_height_profile)
std::vector<coordf_t> layer_height_profile_adaptive(
const SlicingParameters &slicing_params,
const t_layer_height_ranges &layer_height_ranges,
@@ -551,7 +553,34 @@ std::vector<coordf_t> generate_object_layers(
out.push_back(print_z);
}
- //FIXME Adjust the last layer to align with the top object layer exactly?
+ // Adjust the last layer to align with the top object layer exactly
+ if (out.size() > 0 && slicing_params.object_print_z_height() != out[out.size() - 1] && slicing_params.exact_last_layer_height) {
+ float neededPrintZ = slicing_params.object_print_z_height();
+ int idx_layer = out.size() / 2 - 1;
+ float diffZ = neededPrintZ - out[idx_layer * 2 + 1];
+ while (diffZ > EPSILON || diffZ < -EPSILON && idx_layer >= 0){
+ float newH = out[idx_layer * 2 + 1] - out[idx_layer * 2];
+ if (diffZ > 0){
+ newH = std::min((float)slicing_params.max_layer_height, newH + diffZ);
+ } else{
+ newH = std::max((float)slicing_params.min_layer_height, newH + diffZ);
+ }
+ out[idx_layer * 2 + 1] = neededPrintZ;
+ out[idx_layer * 2] = neededPrintZ - newH;
+
+ //next item
+ neededPrintZ = out[idx_layer * 2];
+ idx_layer--;
+ if (idx_layer >= 0){
+ diffZ = neededPrintZ - out[idx_layer * 2 + 1];
+ } else{
+ //unlikely to happen. note: can create a layer outside the min/max bounds.
+ diffZ = 0;
+ out[idx_layer * 2] = 0;
+ }
+ }
+ }
+
return out;
}
diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp
index 094527850..cd38193cc 100644
--- a/src/libslic3r/Slicing.hpp
+++ b/src/libslic3r/Slicing.hpp
@@ -61,6 +61,7 @@ struct SlicingParameters
coordf_t min_layer_height;
coordf_t max_layer_height;
coordf_t max_suport_layer_height;
+ bool exact_last_layer_height;
// First layer height of the print, this may be used for the first layer of the raft
// or for the first layer of the print.
diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp
index 8cdc0ebfd..f208a2ed4 100644
--- a/src/libslic3r/SupportMaterial.cpp
+++ b/src/libslic3r/SupportMaterial.cpp
@@ -284,8 +284,8 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
// this->trim_support_layers_by_object(object, top_contacts, m_slicing_params.soluble_interface ? 0. : m_support_layer_height_min, 0., m_gap_xy);
this->trim_support_layers_by_object(object, top_contacts,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value, m_gap_xy);
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value,
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy);
#ifdef SLIC3R_DEBUG
for (const MyLayer *layer : top_contacts)
@@ -1207,7 +1207,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
new_layer.height = object.layers()[layer_id - 1]->height;
new_layer.bottom_z = (layer_id == 1) ? m_slicing_params.object_print_z_min : object.layers()[layer_id - 2]->print_z;
} else {
- new_layer.print_z = layer.print_z - layer.height - m_object_config->support_material_contact_distance;
+ new_layer.print_z = layer.print_z - layer.height - m_object_config->support_material_contact_distance_top;
new_layer.bottom_z = new_layer.print_z;
new_layer.height = 0.;
// Ignore this contact area if it's too low.
@@ -1230,11 +1230,14 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// Contact layer will be printed with a normal flow, but
// it will support layers printed with a bridging flow.
if (SupportMaterialInternal::has_bridging_extrusions(layer)) {
- coordf_t bridging_height = 0.;
- for (const LayerRegion *region : layer.regions())
- bridging_height += region->region()->bridging_height_avg(*m_print_config);
- bridging_height /= coordf_t(layer.regions().size());
- coordf_t bridging_print_z = layer.print_z - bridging_height - m_object_config->support_material_contact_distance;
+ coordf_t bridging_height = layer.height;
+ if (m_object_config->support_material_contact_distance_type == zdFilament) {
+ bridging_height = 0.;
+ for (const LayerRegion *region : layer.regions())
+ bridging_height += region->region()->bridging_height_avg(*m_print_config);
+ bridging_height /= coordf_t(layer.regions().size());
+ }
+ coordf_t bridging_print_z = layer.print_z - bridging_height - m_object_config->support_material_contact_distance_top;
if (bridging_print_z >= m_slicing_params.first_print_layer_height - EPSILON) {
// Not below the first layer height means this layer is printable.
if (new_layer.print_z < m_slicing_params.first_print_layer_height + EPSILON) {
@@ -1491,7 +1494,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
// top shapes so this can be done here
//FIXME calculate layer height based on the actual thickness of the layer:
// If the layer is extruded with no bridging flow, support just the normal extrusions.
- layer_new.height = m_slicing_params.soluble_interface ?
+ layer_new.height = m_slicing_params.soluble_interface ?
// Align the interface layer with the object's layer height.
object.layers()[layer_id + 1]->height :
// Place a bridge flow interface layer over the top surface.
@@ -1499,8 +1502,9 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
// According to Jindrich the bottom surfaces work well.
//FIXME test the bridging flow instead?
m_support_material_interface_flow.nozzle_diameter;
+ layer_new.height_block = ((m_object_config->support_material_contact_distance_type == zdPlane) ? object.layers()[layer_id + 1]->height : layer_new.height);
layer_new.print_z = m_slicing_params.soluble_interface ? object.layers()[layer_id + 1]->print_z :
- layer.print_z + layer_new.height + m_object_config->support_material_contact_distance.value;
+ (layer.print_z + layer_new.height_block + m_object_config->support_material_contact_distance_bottom.value);
layer_new.bottom_z = layer.print_z;
layer_new.idx_object_layer_below = layer_id;
layer_new.bridging = ! m_slicing_params.soluble_interface;
@@ -1534,6 +1538,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
}
}
}
+
#ifdef SLIC3R_DEBUG
Slic3r::SVG::export_expolygons(
debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z),
@@ -1637,8 +1642,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
std::reverse(bottom_contacts.begin(), bottom_contacts.end());
// trim_support_layers_by_object(object, bottom_contacts, 0., 0., m_gap_xy);
trim_support_layers_by_object(object, bottom_contacts,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value, m_gap_xy);
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value,
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy);
} // ! top_contacts.empty()
@@ -1801,9 +1806,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
assert(extr2->print_z >= m_slicing_params.first_print_layer_height + m_support_layer_height_min - EPSILON);
if (intermediate_layers.empty() || intermediate_layers.back()->print_z < m_slicing_params.first_print_layer_height) {
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.bottom_z = 0.;
- layer_new.print_z = m_slicing_params.first_print_layer_height;
- layer_new.height = m_slicing_params.first_print_layer_height;
+ layer_new.bottom_z = 0.;
+ layer_new.print_z = m_slicing_params.first_print_layer_height;
+ layer_new.height = m_slicing_params.first_print_layer_height;
+ layer_new.height_block = layer_new.height;
intermediate_layers.push_back(&layer_new);
}
continue;
@@ -1823,9 +1829,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
assert(extr2z >= m_slicing_params.first_print_layer_height + EPSILON);
// Generate a new intermediate layer.
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.bottom_z = 0.;
- layer_new.print_z = extr1z = m_slicing_params.first_print_layer_height;
- layer_new.height = extr1z;
+ layer_new.bottom_z = 0.;
+ layer_new.print_z = extr1z = m_slicing_params.first_print_layer_height;
+ layer_new.height = extr1z;
+ layer_new.height_block = layer_new.height;
intermediate_layers.push_back(&layer_new);
// Continue printing the other layers up to extr2z.
}
@@ -1842,18 +1849,20 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
++ idx_layer_object;
if (idx_layer_object == 0 && extr1z == m_slicing_params.raft_interface_top_z) {
// Insert one base support layer below the object.
- MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.print_z = m_slicing_params.object_print_z_min;
- layer_new.bottom_z = m_slicing_params.raft_interface_top_z;
- layer_new.height = layer_new.print_z - layer_new.bottom_z;
+ MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
+ layer_new.print_z = m_slicing_params.object_print_z_min;
+ layer_new.bottom_z = m_slicing_params.raft_interface_top_z;
+ layer_new.height = layer_new.print_z - layer_new.bottom_z;
+ layer_new.height_block = layer_new.height;
intermediate_layers.push_back(&layer_new);
}
// Emit all intermediate support layers synchronized with object layers up to extr2z.
for (; idx_layer_object < object.layers().size() && object.layers()[idx_layer_object]->print_z < extr2z + EPSILON; ++ idx_layer_object) {
- MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.print_z = object.layers()[idx_layer_object]->print_z;
- layer_new.height = object.layers()[idx_layer_object]->height;
- layer_new.bottom_z = (idx_layer_object > 0) ? object.layers()[idx_layer_object - 1]->print_z : (layer_new.print_z - layer_new.height);
+ MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
+ layer_new.print_z = object.layers()[idx_layer_object]->print_z;
+ layer_new.height = object.layers()[idx_layer_object]->height;
+ layer_new.height_block = layer_new.height;
+ layer_new.bottom_z = (idx_layer_object > 0) ? object.layers()[idx_layer_object - 1]->print_z : (layer_new.print_z - layer_new.height);
assert(intermediate_layers.empty() || intermediate_layers.back()->print_z < layer_new.print_z + EPSILON);
intermediate_layers.push_back(&layer_new);
}
@@ -1868,10 +1877,11 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
// between the 1st intermediate layer print_z and extr1->print_z is not too small.
assert(extr1->bottom_z + m_support_layer_height_min < extr1->print_z + EPSILON);
// Generate the first intermediate layer.
- MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.bottom_z = extr1->bottom_z;
- layer_new.print_z = extr1z = extr1->print_z;
- layer_new.height = extr1->height;
+ MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
+ layer_new.bottom_z = extr1->bottom_z;
+ layer_new.print_z = extr1z = extr1->print_z;
+ layer_new.height = extr1->height;
+ layer_new.height_block = layer_new.height;
intermediate_layers.push_back(&layer_new);
dist = extr2z - extr1z;
n_layers_extra = size_t(ceil(dist / m_slicing_params.max_suport_layer_height));
@@ -1898,12 +1908,14 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
layer_new.bottom_z = (i == 0) ? extr1z : intermediate_layers.back()->print_z;
layer_new.print_z = extr2z_large_steps;
layer_new.height = layer_new.print_z - layer_new.bottom_z;
+ layer_new.height_block = layer_new.height;
}
else {
// Intermediate layer, not the last added.
layer_new.height = step;
layer_new.bottom_z = extr1z + i * step;
layer_new.print_z = layer_new.bottom_z + step;
+ layer_new.height_block = layer_new.height;
}
assert(intermediate_layers.empty() || intermediate_layers.back()->print_z <= layer_new.print_z);
intermediate_layers.push_back(&layer_new);
@@ -2059,8 +2071,8 @@ void PrintObjectSupportMaterial::generate_base_layers(
// trim_support_layers_by_object(object, intermediate_layers, 0., 0., m_gap_xy);
this->trim_support_layers_by_object(object, intermediate_layers,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value,
- m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance.value, m_gap_xy);
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value,
+ m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy);
}
void PrintObjectSupportMaterial::trim_support_layers_by_object(
@@ -2094,7 +2106,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
// BOOST_LOG_TRIVIAL(trace) << "Support generator - trim_support_layers_by_object - trimmming non-empty layer " << idx_layer << " of " << nonempty_layers.size();
assert(! support_layer.polygons.empty() && support_layer.print_z >= m_slicing_params.raft_contact_top_z + EPSILON);
// Find the overlapping object layers including the extra above / below gap.
- coordf_t z_threshold = support_layer.print_z - support_layer.height - gap_extra_below + EPSILON;
+ coordf_t z_threshold = support_layer.print_z - support_layer.height_block - gap_extra_below + EPSILON;
idx_object_layer_overlapping = idx_higher_or_equal(
object.layers(), idx_object_layer_overlapping,
[z_threshold](const Layer *layer){ return layer->print_z >= z_threshold; });
@@ -2107,13 +2119,15 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
break;
polygons_append(polygons_trimming, offset(object_layer.slices.expolygons, gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS));
}
- if (! m_slicing_params.soluble_interface) {
+ if (!m_slicing_params.soluble_interface) {
// Collect all bottom surfaces, which will be extruded with a bridging flow.
for (; i < object.layers().size(); ++ i) {
const Layer &object_layer = *object.layers()[i];
bool some_region_overlaps = false;
for (LayerRegion *region : object_layer.regions()) {
- coordf_t bridging_height = region->region()->bridging_height_avg(*this->m_print_config);
+ coordf_t bridging_height = m_object_config->support_material_contact_distance_type == zdFilament
+ ? region->region()->bridging_height_avg(*this->m_print_config)
+ : object_layer.height;
if (object_layer.print_z - bridging_height > support_layer.print_z + gap_extra_above - EPSILON)
break;
some_region_overlaps = true;
@@ -2318,11 +2332,7 @@ static inline void fill_expolygons_generate_paths(
fill_params.dont_adjust = true;
for (const ExPolygon &expoly : expolygons) {
Surface surface(stInternal, expoly);
- extrusion_entities_append_paths(
- dst,
- filler->fill_surface(&surface, fill_params),
- role,
- flow.mm3_per_mm(), flow.width, flow.height);
+ filler->fill_surface_extrusion(&surface, fill_params, flow, role, dst);
}
}
@@ -2340,11 +2350,7 @@ static inline void fill_expolygons_generate_paths(
fill_params.dont_adjust = true;
for (ExPolygon &expoly : expolygons) {
Surface surface(stInternal, std::move(expoly));
- extrusion_entities_append_paths(
- dst,
- filler->fill_surface(&surface, fill_params),
- role,
- flow.mm3_per_mm(), flow.width, flow.height);
+ filler->fill_surface_extrusion(&surface, fill_params, flow, role, dst);
}
}
@@ -2395,8 +2401,8 @@ struct MyLayerExtruded
*m_polygons_to_extrude = union_(*m_polygons_to_extrude, true);
}
// 2) Merge the extrusions.
- this->extrusions.insert(this->extrusions.end(), other.extrusions.begin(), other.extrusions.end());
- other.extrusions.clear();
+ this->extrusions.entities.insert(this->extrusions.entities.end(), other.extrusions.entities.begin(), other.extrusions.entities.end());
+ other.extrusions.entities.clear();
// 3) Merge the infill polygons.
Slic3r::polygons_append(this->layer->polygons, std::move(other.layer->polygons));
this->layer->polygons = union_(this->layer->polygons, true);
@@ -2411,7 +2417,7 @@ struct MyLayerExtruded
// The source layer. It carries the height and extrusion type (bridging / non bridging, extrusion height).
PrintObjectSupportMaterial::MyLayer *layer;
// Collect extrusions. They will be exported sorted by the bottom height.
- ExtrusionEntitiesPtr extrusions;
+ ExtrusionEntityCollection extrusions;
// In case the extrusions are non-empty, m_polygons_to_extrude may contain the rest areas yet to be filled by additional support.
// This is useful mainly for the loop interfaces, which are generated before the zig-zag infills.
Polygons *m_polygons_to_extrude;
@@ -2645,7 +2651,7 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
// Transform loops into ExtrusionPath objects.
extrusion_entities_append_paths(
- top_contact_layer.extrusions,
+ top_contact_layer.extrusions.entities,
std::move(loop_lines),
erSupportMaterialInterface, flow.mm3_per_mm(), flow.width, flow.height);
}
@@ -2672,7 +2678,7 @@ static std::string dbg_index_to_color(int idx)
// to stick too firmly to the object.
void modulate_extrusion_by_overlapping_layers(
// Extrusions generated for this_layer.
- ExtrusionEntitiesPtr &extrusions_in_out,
+ ExtrusionEntityCollection &extrusions_in_out,
const PrintObjectSupportMaterial::MyLayer &this_layer,
// Multiple layers overlapping with this_layer, sorted bottom up.
const PrintObjectSupportMaterial::MyLayersPtr &overlapping_layers)
@@ -2682,10 +2688,12 @@ void modulate_extrusion_by_overlapping_layers(
// The extrusions do not overlap with any other extrusion.
return;
+ ExtrusionEntityCollection flatten_extrusions_in_out = extrusions_in_out.flatten();
+
// Get the initial extrusion parameters.
- ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(extrusions_in_out.front());
+ ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(flatten_extrusions_in_out.entities.front());
assert(extrusion_path_template != nullptr);
- ExtrusionRole extrusion_role = extrusion_path_template->role();
+ ExtrusionRole extrusion_role = extrusion_path_template->role();
float extrusion_width = extrusion_path_template->width;
struct ExtrusionPathFragment
@@ -2758,7 +2766,7 @@ void modulate_extrusion_by_overlapping_layers(
// Collect the paths of this_layer.
{
Polylines &polylines = path_fragments.back().polylines;
- for (ExtrusionEntitiesPtr::const_iterator it = extrusions_in_out.begin(); it != extrusions_in_out.end(); ++ it) {
+ for (ExtrusionEntitiesPtr::const_iterator it = flatten_extrusions_in_out.entities.begin(); it != flatten_extrusions_in_out.entities.end(); ++it) {
ExtrusionPath *path = dynamic_cast<ExtrusionPath*>(*it);
assert(path != nullptr);
polylines.emplace_back(Polyline(std::move(path->polyline)));
@@ -2896,18 +2904,18 @@ void modulate_extrusion_by_overlapping_layers(
if (!multipath.paths.empty()) {
if (multipath.paths.size() == 1) {
// This path was not fragmented.
- extrusions_in_out.push_back(new ExtrusionPath(std::move(multipath.paths.front())));
+ extrusions_in_out.entities.push_back(new ExtrusionPath(std::move(multipath.paths.front())));
} else {
// This path was fragmented. Copy the collection as a whole object, so the order inside the collection will not be changed
// during the chaining of extrusions_in_out.
- extrusions_in_out.push_back(new ExtrusionMultiPath(std::move(multipath)));
+ extrusions_in_out.entities.push_back(new ExtrusionMultiPath(std::move(multipath)));
}
}
}
// If there are any non-consumed fragments, add them separately.
//FIXME this shall not happen, if the Clipper works as expected and all paths split to fragments could be re-connected.
for (auto it_fragment = path_fragments.begin(); it_fragment != path_fragments.end(); ++ it_fragment)
- extrusion_entities_append_paths(extrusions_in_out, std::move(it_fragment->polylines), extrusion_role, it_fragment->mm3_per_mm, it_fragment->width, it_fragment->height);
+ extrusion_entities_append_paths(extrusions_in_out.entities, std::move(it_fragment->polylines), extrusion_role, it_fragment->mm3_per_mm, it_fragment->width, it_fragment->height);
}
void PrintObjectSupportMaterial::generate_toolpaths(
@@ -2998,7 +3006,8 @@ void PrintObjectSupportMaterial::generate_toolpaths(
MyLayer &raft_layer = *raft_layers[support_layer_id];
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(ipRectilinear));
- std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern));
+ std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern));
+ std::unique_ptr<Fill> filler_dense = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter));
filler_interface->set_bounding_box(bbox_object);
filler_support->set_bounding_box(bbox_object);
@@ -3029,7 +3038,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
if (! to_infill.empty()) {
// We don't use $base_flow->spacing because we need a constant spacing
// value that guarantees that all layers are correctly aligned.
- Fill *filler = filler_support.get();
+ Fill *filler = filler_support.get();
filler->angle = raft_angle_base;
filler->spacing = m_support_material_flow.spacing();
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density));
@@ -3051,10 +3060,16 @@ void PrintObjectSupportMaterial::generate_toolpaths(
float density = 0.f;
if (support_layer_id == 0) {
// Base flange.
- filler->angle = raft_angle_1st_layer;
+ if (this->m_object_config->support_material_solid_first_layer.value) {
+ filler = filler_dense.get();
+ density = 1.f;
+ filler->angle = 0;
+ } else {
+ filler->angle = raft_angle_1st_layer;
+ // 70% of density on the 1st layer.
+ density = 0.7f;
+ }
filler->spacing = m_first_layer_flow.spacing();
- // 70% of density on the 1st layer.
- density = 0.7f;
} else if (support_layer_id >= m_slicing_params.base_raft_layers) {
filler->angle = raft_angle_interface;
// We don't use $base_flow->spacing because we need a constant spacing
@@ -3100,8 +3115,9 @@ void PrintObjectSupportMaterial::generate_toolpaths(
size_t idx_layer_top_contact = size_t(-1);
size_t idx_layer_intermediate = size_t(-1);
size_t idx_layer_inteface = size_t(-1);
- std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear));
- std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern));
+ std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(m_slicing_params.soluble_interface ? ipRectilinear : ipRectilinear));
+ std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern));
+ std::unique_ptr<Fill> filler_solid = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter));
filler_interface->set_bounding_box(bbox_object);
filler_support->set_bounding_box(bbox_object);
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
@@ -3176,20 +3192,31 @@ void PrintObjectSupportMaterial::generate_toolpaths(
float(layer_ex.layer->height),
m_support_material_interface_flow.nozzle_diameter,
layer_ex.layer->bridging);
- filler_interface->angle = interface_as_base ?
+ Fill *filler = filler_interface.get();
+ float density = interface_density;
+ //if first layer and solid first layer : draw concentric with 100% density
+ if (support_layer.id() == 0 && this->m_object_config->support_material_solid_first_layer.value) {
+ filler = filler_solid.get();
+ density = 1.f;
+ interface_flow = m_first_layer_flow;
+ filler->angle = 0;
+ filler->spacing = interface_flow.spacing();
+ } else {
+ filler->angle = interface_as_base ?
// If zero interface layers are configured, use the same angle as for the base layers.
angles[support_layer_id % angles.size()] :
// Use interface angle for the interface layers.
interface_angle;
- filler_interface->spacing = m_support_material_interface_flow.spacing();
- filler_interface->link_max_length = coord_t(scale_(filler_interface->spacing * link_max_length_factor / interface_density));
+ filler->spacing = m_support_material_interface_flow.spacing();
+ filler->link_max_length = coord_t(scale_(filler_interface->spacing * link_max_length_factor / density));
+ }
fill_expolygons_generate_paths(
// Destination
- layer_ex.extrusions,
+ layer_ex.extrusions.entities,
// Regions to fill
union_ex(layer_ex.polygons_to_extrude(), true),
// Filler and its parameters
- filler_interface.get(), float(interface_density),
+ filler, float(density),
// Extrusion parameters
erSupportMaterialInterface, interface_flow);
}
@@ -3215,16 +3242,21 @@ void PrintObjectSupportMaterial::generate_toolpaths(
offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON)) :
offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width()));
if (base_layer.layer->bottom_z < EPSILON) {
- // Base flange (the 1st layer).
- filler = filler_interface.get();
- filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.));
- density = 0.5f;
- flow = m_first_layer_flow;
+ if (this->m_object_config->support_material_solid_first_layer.value) {
+ // Base flange (the 1st layer).
+ filler = filler_solid.get();
+ filler->angle = 0;
+ density = 1.f;
+ } else {
+ filler = filler_interface.get();
+ filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.));
+ density = 0.5f;
+ filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
+ }
// use the proper spacing for first layer as we don't need to align
// its pattern to the other layers
- //FIXME When paralellizing, each thread shall have its own copy of the fillers.
+ flow = m_first_layer_flow;
filler->spacing = flow.spacing();
- filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
} else if (with_sheath) {
// Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove.
// TODO: use brim ordering algorithm
@@ -3232,13 +3264,13 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// TODO: use offset2_ex()
to_infill = offset_ex(to_infill, - 0.4 * float(flow.scaled_spacing()));
extrusion_entities_append_paths(
- base_layer.extrusions,
+ base_layer.extrusions.entities,
to_polylines(std::move(to_infill_polygons)),
erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
}
fill_expolygons_generate_paths(
// Destination
- base_layer.extrusions,
+ base_layer.extrusions.entities,
// Regions to fill
std::move(to_infill),
// Filler and its parameters
@@ -3248,13 +3280,13 @@ void PrintObjectSupportMaterial::generate_toolpaths(
}
layer_cache.overlaps.reserve(4);
- if (! bottom_contact_layer.empty())
+ if (!bottom_contact_layer.empty() && !bottom_contact_layer.extrusions.empty())
layer_cache.overlaps.push_back(&bottom_contact_layer);
- if (! top_contact_layer.empty())
+ if (!top_contact_layer.empty() && !top_contact_layer.extrusions.empty())
layer_cache.overlaps.push_back(&top_contact_layer);
- if (! interface_layer.empty())
+ if (!interface_layer.empty() && !interface_layer.extrusions.empty())
layer_cache.overlaps.push_back(&interface_layer);
- if (! base_layer.empty())
+ if (!base_layer.empty() && !base_layer.extrusions.empty())
layer_cache.overlaps.push_back(&base_layer);
// Sort the layers with the same print_z coordinate by their heights, thickest first.
std::sort(layer_cache.overlaps.begin(), layer_cache.overlaps.end(), [](const LayerCacheItem &lc1, const LayerCacheItem &lc2) { return lc1.layer_extruded->layer->height > lc2.layer_extruded->layer->height; });
diff --git a/src/libslic3r/SupportMaterial.hpp b/src/libslic3r/SupportMaterial.hpp
index 2e1a05946..743fccc40 100644
--- a/src/libslic3r/SupportMaterial.hpp
+++ b/src/libslic3r/SupportMaterial.hpp
@@ -52,11 +52,12 @@ public:
class MyLayer
{
public:
- MyLayer() :
- layer_type(sltUnknown),
- print_z(0.),
- bottom_z(0.),
- height(0.),
+ MyLayer() :
+ layer_type(sltUnknown),
+ print_z(0.),
+ bottom_z(0.),
+ height(0.),
+ height_block(0.),
idx_object_layer_above(size_t(-1)),
idx_object_layer_below(size_t(-1)),
bridging(false),
@@ -77,6 +78,7 @@ public:
print_z = 0.;
bottom_z = 0.;
height = 0.;
+ height_block = 0.;
idx_object_layer_above = size_t(-1);
idx_object_layer_below = size_t(-1);
bridging = false;
@@ -119,9 +121,11 @@ public:
coordf_t print_z;
// Bottom Z of this layer. For soluble layers, bottom_z + height = print_z,
// otherwise bottom_z + gap + height = print_z.
- coordf_t bottom_z;
- // Layer height in unscaled coordinates.
- coordf_t height;
+ coordf_t bottom_z;
+ // Layer height in unscaled coordinates.
+ coordf_t height;
+ // Layer height for collision in unscaled coordinates.
+ coordf_t height_block;
// Index of a PrintObject layer_id supported by this layer. This will be set for top contact layers.
// If this is not a contact layer, it will be set to size_t(-1).
size_t idx_object_layer_above;
diff --git a/src/libslic3r/Surface.cpp b/src/libslic3r/Surface.cpp
index 0e9eca7fd..40abc82d6 100644
--- a/src/libslic3r/Surface.cpp
+++ b/src/libslic3r/Surface.cpp
@@ -22,7 +22,9 @@ Surface::is_solid() const
|| this->surface_type == stBottom
|| this->surface_type == stBottomBridge
|| this->surface_type == stInternalSolid
- || this->surface_type == stInternalBridge;
+ || this->surface_type == stInternalBridge
+ || this->surface_type == stInternalOverBridge
+ || this->surface_type == stTopOverBridge;
}
bool
@@ -30,7 +32,15 @@ Surface::is_external() const
{
return this->surface_type == stTop
|| this->surface_type == stBottom
- || this->surface_type == stBottomBridge;
+ || this->surface_type == stBottomBridge
+ || this->surface_type == stTopOverBridge;
+}
+
+bool
+Surface::is_top() const
+{
+ return this->surface_type == stTop
+ || this->surface_type == stTopOverBridge;
}
bool
@@ -38,6 +48,7 @@ Surface::is_internal() const
{
return this->surface_type == stInternal
|| this->surface_type == stInternalBridge
+ || this->surface_type == stInternalOverBridge
|| this->surface_type == stInternalSolid
|| this->surface_type == stInternalVoid;
}
@@ -55,6 +66,12 @@ Surface::is_bridge() const
return this->surface_type == stBottomBridge
|| this->surface_type == stInternalBridge;
}
+bool
+Surface::is_overBridge() const
+{
+ return this->surface_type == stInternalOverBridge
+ || this->surface_type == stTopOverBridge;
+}
BoundingBox get_extents(const Surface &surface)
{
@@ -91,7 +108,8 @@ const char* surface_type_to_color_name(const SurfaceType surface_type)
case stBottomBridge: return "rgb(0,0,255)"; // "blue";
case stInternal: return "rgb(255,255,128)"; // yellow
case stInternalSolid: return "rgb(255,0,255)"; // magenta
- case stInternalBridge: return "rgb(0,255,255)";
+ case stInternalBridge: return "rgb(0,255,255)"; // cyan
+ case stInternalOverBridge: return "rgb(0,255,128)"; // green-cyan
case stInternalVoid: return "rgb(128,128,128)";
case stPerimeter: return "rgb(128,0,0)"; // maroon
default: return "rgb(64,64,64)";
@@ -128,6 +146,8 @@ void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal bridge", surface_type_to_color_name(stInternalBridge));
pos_x += step_x;
+ svg.draw_legend(Point(pos_x, pos_y), "internal over bridge", surface_type_to_color_name(stInternalOverBridge));
+ pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal void" , surface_type_to_color_name(stInternalVoid));
}
diff --git a/src/libslic3r/Surface.hpp b/src/libslic3r/Surface.hpp
index c2cec3793..f9bba7891 100644
--- a/src/libslic3r/Surface.hpp
+++ b/src/libslic3r/Surface.hpp
@@ -19,6 +19,9 @@ enum SurfaceType {
stInternalSolid,
// 1st layer of dense infill over sparse infill, printed with a bridging extrusion flow.
stInternalBridge,
+ // 2nd layer of dense infill over sparse infill/nothing, printed with an over-extruding flow.
+ stInternalOverBridge,
+ stTopOverBridge,
// stInternal turns into void surfaces if the sparse infill is used for supports only,
// or if sparse infill layers get combined into a single layer.
stInternalVoid,
@@ -34,39 +37,47 @@ class Surface
public:
SurfaceType surface_type;
ExPolygon expolygon;
+ ExPolygons notOverlaps;
double thickness; // in mm
unsigned short thickness_layers; // in layers
double bridge_angle; // in radians, ccw, 0 = East, only 0+ (negative means undefined)
unsigned short extra_perimeters;
+ uint16_t maxNbSolidLayersOnTop;
Surface(const Slic3r::Surface &rhs)
: surface_type(rhs.surface_type), expolygon(rhs.expolygon),
thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),
- bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters)
+ bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters),
+ maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop)
{};
Surface(SurfaceType _surface_type, const ExPolygon &_expolygon)
: surface_type(_surface_type), expolygon(_expolygon),
- thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0)
+ thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0),
+ maxNbSolidLayersOnTop(-1)
{};
Surface(const Surface &other, const ExPolygon &_expolygon)
: surface_type(other.surface_type), expolygon(_expolygon),
thickness(other.thickness), thickness_layers(other.thickness_layers),
- bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters)
+ bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters),
+ maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop)
{};
Surface(Surface &&rhs)
: surface_type(rhs.surface_type), expolygon(std::move(rhs.expolygon)),
thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),
- bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters)
+ bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters),
+ maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop)
{};
Surface(SurfaceType _surface_type, const ExPolygon &&_expolygon)
: surface_type(_surface_type), expolygon(std::move(_expolygon)),
- thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0)
+ thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0),
+ maxNbSolidLayersOnTop(-1)
{};
Surface(const Surface &other, const ExPolygon &&_expolygon)
: surface_type(other.surface_type), expolygon(std::move(_expolygon)),
thickness(other.thickness), thickness_layers(other.thickness_layers),
- bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters)
+ bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters),
+ maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop)
{};
Surface& operator=(const Surface &rhs)
@@ -77,6 +88,7 @@ public:
thickness_layers = rhs.thickness_layers;
bridge_angle = rhs.bridge_angle;
extra_perimeters = rhs.extra_perimeters;
+ maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop;
return *this;
}
@@ -88,6 +100,7 @@ public:
thickness_layers = rhs.thickness_layers;
bridge_angle = rhs.bridge_angle;
extra_perimeters = rhs.extra_perimeters;
+ maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop;
return *this;
}
@@ -97,9 +110,11 @@ public:
void clear() { expolygon.clear(); }
bool is_solid() const;
bool is_external() const;
+ bool is_top() const;
bool is_internal() const;
bool is_bottom() const;
bool is_bridge() const;
+ bool is_overBridge() const;
};
typedef std::vector<Surface> Surfaces;
@@ -146,12 +161,12 @@ inline ExPolygons to_expolygons(const Surfaces &src)
inline ExPolygons to_expolygons(Surfaces &&src)
{
- ExPolygons expolygons;
- expolygons.reserve(src.size());
- for (Surfaces::const_iterator it = src.begin(); it != src.end(); ++it)
- expolygons.emplace_back(ExPolygon(std::move(it->expolygon)));
- src.clear();
- return expolygons;
+ ExPolygons expolygons;
+ expolygons.reserve(src.size());
+ for (Surfaces::const_iterator it = src.begin(); it != src.end(); ++it)
+ expolygons.emplace_back(ExPolygon(std::move(it->expolygon)));
+ src.clear();
+ return expolygons;
}
inline ExPolygons to_expolygons(const SurfacesPtr &src)
diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp
index 4648b95c0..d27d90c26 100644
--- a/src/libslic3r/TriangleMesh.cpp
+++ b/src/libslic3r/TriangleMesh.cpp
@@ -1699,7 +1699,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
// 0.0499 comes from https://github.com/slic3r/Slic3r/issues/959
// double safety_offset = scale_(0.0499);
// 0.0001 is set to satisfy GH #520, #1029, #1364
- double safety_offset = scale_(0.0001);
+// double safety_offset = scale_(0.0001); // now a config value
/* The following line is commented out because it can generate wrong polygons,
see for example issue #661 */
diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp
index fc2b40013..63e067e84 100644
--- a/src/libslic3r/TriangleMesh.hpp
+++ b/src/libslic3r/TriangleMesh.hpp
@@ -175,6 +175,7 @@ public:
const float min_z, const float max_z, IntersectionLine *line_out) const;
void cut(float z, TriangleMesh* upper, TriangleMesh* lower) const;
+ double safety_offset = scale_(0.02);
private:
const TriangleMesh *mesh;
// Map from a facet to an edge index.
diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h
index 19c6d3065..fb5972ddc 100644
--- a/src/libslic3r/libslic3r.h
+++ b/src/libslic3r/libslic3r.h
@@ -41,9 +41,6 @@ typedef double coordf_t;
// Maximum perimeter length for the loop to apply the small perimeter speed.
#define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI
#define INSET_OVERLAP_TOLERANCE 0.4
-// 3mm ring around the top / bottom / bridging areas.
-//FIXME This is quite a lot.
-#define EXTERNAL_INFILL_MARGIN 3.
//FIXME Better to use an inline function with an explicit return type.
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) ((val) / SCALING_FACTOR)
@@ -85,6 +82,8 @@ namespace Slic3r {
template<typename T, typename Q>
inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); }
+inline double unscaled(double v) { return v * SCALING_FACTOR; }
+
enum Axis { X=0, Y, Z, E, F, NUM_AXES };
template <class T>
diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp
index 08c8839c7..c3d75ef57 100644
--- a/src/slic3r/GUI/AboutDialog.cpp
+++ b/src/slic3r/GUI/AboutDialog.cpp
@@ -54,7 +54,7 @@ AboutDialog::AboutDialog()
// title
{
- wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r Prusa Edition", wxDefaultPosition, wxDefaultSize);
+ wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r++", wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
title_font.SetWeight(wxFONTWEIGHT_BOLD);
title_font.SetFamily(wxFONTFAMILY_ROMAN);
@@ -93,12 +93,13 @@ AboutDialog::AboutDialog()
"<html>"
"<body bgcolor= %s link= %s>"
"<font color=%s>"
+ "Copyright &copy; 2018 Durand Rémi. <br />"
"Copyright &copy; 2016-2018 Prusa Research. <br />"
"Copyright &copy; 2011-2017 Alessandro Ranellucci. <br />"
"<a href=\"http://slic3r.org/\">Slic3r</a> is licensed under the "
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">GNU Affero General Public License, version 3</a>."
"<br /><br />"
- "Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others. "
+ "Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik, Durand Rémi and numerous others. "
"Manual by Gary Hodgson. Inspired by the RepRap community. <br />"
"Slic3r logo designed by Corey Daniels, <a href=\"http://www.famfamfam.com/lab/icons/silk/\">Silk Icon Set</a> designed by Mark James. "
"</font>"
diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 6cf45166d..42b35fec8 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -23,6 +23,7 @@
namespace Slic3r {
namespace GUI {
+#define MAIN_VENDOR "None"
// Printer model picker GUI control
@@ -95,7 +96,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons
auto *cbox = new Checkbox(variants_panel, label, model_id, variant.name);
const size_t idx = cboxes.size();
cboxes.push_back(cbox);
- bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant.name);
+ bool enabled = appconfig_vendors.get_variant(MAIN_VENDOR, model_id, variant.name);
variants_checked += enabled;
cbox->SetValue(enabled);
variants_sizer->Add(cbox, 0, wxBOTTOM, 3);
@@ -231,7 +232,7 @@ PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) :
if (wizard_p()->run_reason == ConfigWizard::RR_DATA_EMPTY) {
wxString::Format(_(L("Run %s")), ConfigWizard::name());
append_text(wxString::Format(
- _(L("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.")),
+ _(L("Hello, welcome to Slic3r++ (fork of Slic3r Slic3r++)! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")),
ConfigWizard::name())
);
} else {
@@ -240,7 +241,8 @@ PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) :
}
const auto &vendors = wizard_p()->vendors;
- const auto vendor_prusa = vendors.find("PrusaResearch");
+ printf("vendors count : %d", vendors.size());
+ const auto vendor_prusa = vendors.find(MAIN_VENDOR);
if (vendor_prusa != vendors.cend()) {
AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
@@ -329,7 +331,7 @@ PageVendors::PageVendors(ConfigWizard *parent) :
for (const auto vendor_pair : wizard_p()->vendors) {
const auto &vendor = vendor_pair.second;
- if (vendor.id == "PrusaResearch") { continue; }
+ if (vendor.id == MAIN_VENDOR) { continue; }
auto *picker = new PrinterPicker(this, vendor, appconfig_vendors);
picker->Hide();
@@ -631,8 +633,8 @@ static const std::unordered_map<std::string, std::pair<std::string, std::string>
void ConfigWizard::priv::load_vendors()
{
- const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
- const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles";
+ const fs::path vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
+ const fs::path rsrc_vendor_dir = fs::path(resources_dir()) / "profiles";
// Load vendors from the "vendors" directory in datadir
for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
@@ -678,7 +680,7 @@ void ConfigWizard::priv::load_vendors()
const auto &model = needle->second.first;
const auto &variant = needle->second.second;
- appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
+ appconfig_vendors.set_variant(MAIN_VENDOR, model, variant, true);
}
}
}
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index 3dd160432..4698a5892 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -628,7 +628,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
}
case coEnum: {
int val = boost::any_cast<int>(value);
- if (m_opt_id.compare("external_fill_pattern") == 0)
+ if (m_opt_id.compare("top_fill_pattern") == 0 || m_opt_id.compare("bottom_fill_pattern") == 0 )
{
if (!m_opt.enum_values.empty()) {
std::string key;
@@ -652,7 +652,28 @@ void Choice::set_value(const boost::any& value, bool change_event)
}
else
val = 0;
- }
+ } else if (m_opt_id.compare("perimeter_loop_seam") == 0) {
+ if (!m_opt.enum_values.empty()) {
+ std::string key;
+ t_config_enum_values map_names = ConfigOptionEnum<SeamPosition>::get_enum_values();
+ for (auto it : map_names) {
+ if (val == it.second) {
+ key = it.first;
+ break;
+ }
+ }
+
+ size_t idx = 0;
+ for (auto el : m_opt.enum_values) {
+ if (el.compare(key) == 0)
+ break;
+ ++idx;
+ }
+
+ val = idx == m_opt.enum_values.size() ? 0 : idx;
+ } else
+ val = 3;
+ }
dynamic_cast<wxComboBox*>(window)->SetSelection(val);
break;
}
@@ -697,7 +718,7 @@ boost::any& Choice::get_value()
if (m_opt.type == coEnum)
{
int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();
- if (m_opt_id.compare("external_fill_pattern") == 0)
+ if (m_opt_id.compare("top_fill_pattern") == 0 || m_opt_id.compare("bottom_fill_pattern") == 0 )
{
if (!m_opt.enum_values.empty()) {
std::string key = m_opt.enum_values[ret_enum];
@@ -714,11 +735,23 @@ boost::any& Choice::get_value()
else if (m_opt_id.compare("gcode_flavor") == 0)
m_value = static_cast<GCodeFlavor>(ret_enum);
else if (m_opt_id.compare("support_material_pattern") == 0)
- m_value = static_cast<SupportMaterialPattern>(ret_enum);
- else if (m_opt_id.compare("seam_position") == 0)
- m_value = static_cast<SeamPosition>(ret_enum);
- else if (m_opt_id.compare("host_type") == 0)
- m_value = static_cast<PrintHostType>(ret_enum);
+ m_value = static_cast<SupportMaterialPattern>(ret_enum);
+ else if (m_opt_id.compare("seam_position") == 0)
+ m_value = static_cast<SeamPosition>(ret_enum);
+ else if (m_opt_id.compare("perimeter_loop_seam") == 0) {
+ if (!m_opt.enum_values.empty()) {
+ std::string key = m_opt.enum_values[ret_enum];
+ t_config_enum_values map_names = ConfigOptionEnum<SeamPosition>::get_enum_values();
+ int value = map_names.at(key);
+ m_value = static_cast<SeamPosition>(value);
+ } else
+ m_value = static_cast<SeamPosition>(3);
+ } else if (m_opt_id.compare("host_type") == 0)
+ m_value = static_cast<PrintHostType>(ret_enum);
+ else if (m_opt_id.compare("infill_dense_algo") == 0)
+ m_value = static_cast<DenseInfillAlgo>(ret_enum);
+ else if (m_opt_id.compare("support_material_contact_distance_type") == 0)
+ m_value = static_cast<SupportZDistanceType>(ret_enum);
else if (m_opt_id.compare("display_orientation") == 0)
m_value = static_cast<SLADisplayOrientation>(ret_enum);
else if (m_opt_id.compare("support_pillar_connection_mode") == 0)
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index ee8a7ebbd..9a63986c5 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -7385,6 +7385,7 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
case GCodePreviewData::Extrusion::VolumetricRate:
return path.feedrate * (float)path.mm3_per_mm;
case GCodePreviewData::Extrusion::Tool:
+ case GCodePreviewData::Extrusion::Filament:
return (float)path.extruder_id;
case GCodePreviewData::Extrusion::ColorPrint:
return (float)path.cp_color_id;
@@ -7410,6 +7411,7 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
case GCodePreviewData::Extrusion::VolumetricRate:
return data.get_volumetric_rate_color(value);
case GCodePreviewData::Extrusion::Tool:
+ case GCodePreviewData::Extrusion::Filament:
{
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (unsigned int)value * 4), 4 * sizeof(float));
@@ -7552,6 +7554,7 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data,
break;
}
case GCodePreviewData::Extrusion::Tool:
+ case GCodePreviewData::Extrusion::Filament:
{
res = _travel_paths_by_tool(preview_data, tool_colors);
break;
diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp
index 148285e86..64854f4b7 100644
--- a/src/slic3r/GUI/GUI.cpp
+++ b/src/slic3r/GUI/GUI.cpp
@@ -187,24 +187,28 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
break;
case coEnum:{
- if (opt_key.compare("external_fill_pattern") == 0 ||
+ if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
else if (opt_key.compare("gcode_flavor") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));
else if (opt_key.compare("support_material_pattern") == 0)
- config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
- else if (opt_key.compare("seam_position") == 0)
- config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
+ config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
+ else if (opt_key.compare("seam_position") == 0 || opt_key.compare("perimeter_loop_seam") == 0)
+ config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
else if (opt_key.compare("host_type") == 0)
- config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
+ config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
+ else if (opt_key.compare("infill_dense_algo") == 0)
+ config.set_key_value(opt_key, new ConfigOptionEnum<DenseInfillAlgo>(boost::any_cast<DenseInfillAlgo>(value)));
+ else if (opt_key.compare("support_material_contact_distance_type") == 0)
+ config.set_key_value(opt_key, new ConfigOptionEnum<SupportZDistanceType>(boost::any_cast<SupportZDistanceType>(value)));
else if (opt_key.compare("display_orientation") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SLADisplayOrientation>(boost::any_cast<SLADisplayOrientation>(value)));
else if(opt_key.compare("support_pillar_connection_mode") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SLAPillarConnectionMode>(boost::any_cast<SLAPillarConnectionMode>(value)));
}
break;
- case coPoints:{
+ case coPoints:{
if (opt_key.compare("bed_shape") == 0) {
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
break;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index c22219fea..820d8c40a 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -92,8 +92,8 @@ bool GUI_App::OnInit()
wxCHECK_MSG(m_imgui->init(), false, "Failed to initialize ImGui");
#endif // ENABLE_IMGUI
- SetAppName("Slic3rPE-alpha");
- SetAppDisplayName("Slic3r Prusa Edition");
+ SetAppName("Slic3r++_alpha");
+ SetAppDisplayName("Slic3r++");
// Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
@@ -419,7 +419,7 @@ bool GUI_App::select_language( wxArrayString & names,
m_wxLocale = new wxLocale;
m_wxLocale->Init(identifiers[index]);
m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir()));
- m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE");
+ m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3r++");
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
wxSetlocale(LC_NUMERIC, "C");
Preset::update_suffix_modified();
@@ -447,7 +447,7 @@ bool GUI_App::load_language()
m_wxLocale = new wxLocale;
m_wxLocale->Init(identifiers[i]);
m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir()));
- m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE");
+ m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3r++");
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
wxSetlocale(LC_NUMERIC, "C");
Preset::update_suffix_modified();
@@ -491,7 +491,7 @@ void GUI_App::get_installed_languages(wxArrayString & names, wxArrayLong & ident
{
auto full_file_name = dir.GetName() + wxFileName::GetPathSeparator() +
filename + wxFileName::GetPathSeparator() +
- /*GetAppName()*/"Slic3rPE" +
+ /*GetAppName()*/"Slic3r++" +
wxT(".mo");
if (wxFileExists(full_file_name))
{
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index d47c7f4e8..00bb74bb3 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -50,7 +50,7 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL
m_statusbar->embed(this);
m_statusbar->set_status_text(_(L("Version")) + " " +
SLIC3R_VERSION +
- _(L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases")));
+ _(L(" - Remember to check for updates at http://github.com/supermerill/slic3r/releases")));
// initialize tabpanel and menubar
init_tabpanel();
@@ -412,10 +412,12 @@ void MainFrame::init_menubar()
// Help menu
auto helpMenu = new wxMenu();
{
- append_menu_item(helpMenu, wxID_ANY, _(L("Prusa 3D &Drivers")), _(L("Open the Prusa3D drivers download page in your browser")),
- [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://www.prusa3d.com/drivers/"); });
- append_menu_item(helpMenu, wxID_ANY, _(L("Prusa Edition &Releases")), _(L("Open the Prusa Edition releases page in your browser")),
- [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/releases"); });
+ append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r++ Releases")), _(L("Open the slic3r++ releases page in your browser")),
+ [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/supermerill/slic3r/releases"); });
+ append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r++ website")), _(L("Open the slic3r++ website in your browser")),
+ [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/supermerill/slic3r"); });
+ append_menu_item(helpMenu, wxID_ANY, _(L("Prusa Edition website")), _(L("Open the Prusa Edition website in your browser")),
+ [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r"); });
//# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{
//# wxTheApp->check_version(1);
//# });
@@ -429,8 +431,8 @@ void MainFrame::init_menubar()
[this](wxCommandEvent&) { wxGetApp().system_info(); });
append_menu_item(helpMenu, wxID_ANY, _(L("Show &Configuration Folder")), _(L("Show user configuration folder (datadir)")),
[this](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
- append_menu_item(helpMenu, wxID_ANY, _(L("Report an I&ssue")), _(L("Report an issue on the Slic3r Prusa Edition")),
- [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); });
+ append_menu_item(helpMenu, wxID_ANY, _(L("Report an Issue")), _(L("Report an issue on Slic3r++")),
+ [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/supermerill/issues/new"); });
append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")),
[this](wxCommandEvent&) { Slic3r::GUI::about(); });
helpMenu->AppendSeparator();
@@ -441,15 +443,15 @@ void MainFrame::init_menubar()
// menubar
// assign menubar to frame after appending items, otherwise special items
// will not be handled correctly
- auto menubar = new wxMenuBar();
+ auto menubar = new wxMenuBar();
menubar->Append(fileMenu, _(L("&File")));
if (editMenu) menubar->Append(editMenu, _(L("&Edit")));
menubar->Append(windowMenu, _(L("&Window")));
if (viewMenu) menubar->Append(viewMenu, _(L("&View")));
- // Add additional menus from C++
- wxGetApp().add_config_menu(menubar);
+ // Add additional menus from C++
+ wxGetApp().add_config_menu(menubar);
menubar->Append(helpMenu, _(L("&Help")));
- SetMenuBar(menubar);
+ SetMenuBar(menubar);
#ifdef __APPLE__
// This fixes a bug on Mac OS where the quit command doesn't emit window close events
@@ -665,15 +667,15 @@ void MainFrame::export_config()
// Load a config file containing a Print, Filament & Printer preset.
void MainFrame::load_config_file()
{
- if (!wxGetApp().check_unsaved_changes())
- return;
- auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")),
- !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
- "config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
+ if (!wxGetApp().check_unsaved_changes())
+ return;
+ auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")),
+ !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
+ "config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
wxString file;
if (dlg->ShowModal() == wxID_OK)
- file = dlg->GetPath();
- dlg->Destroy();
+ file = dlg->GetPath();
+ dlg->Destroy();
if (! file.IsEmpty() && this->load_config_file(file.ToUTF8().data())) {
wxGetApp().app_config->update_config_dir(get_dir_name(file));
m_last_config = file;
@@ -689,7 +691,7 @@ bool MainFrame::load_config_file(const std::string &path)
show_error(this, ex.what());
return false;
}
- wxGetApp().load_current_presets();
+ wxGetApp().load_current_presets();
return true;
}
@@ -736,11 +738,11 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re
"config.ini", file_wildcards(FT_INI), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dlg->ShowModal() != wxID_OK) {
dlg->Destroy();
- return;
+ return;
}
file = dlg->GetPath();
- dlg->Destroy();
- }
+ dlg->Destroy();
+ }
wxGetApp().app_config->update_config_dir(get_dir_name(file));
@@ -770,11 +772,11 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
this->plater()->set_printer_technology(printer_technology);
}
#if 0
- for (auto tab : wxGetApp().tabs_list)
+ for (auto tab : wxGetApp().tabs_list)
if (tab->supports_printer_technology(printer_technology)) {
if (tab->name() == "printer")
static_cast<TabPrinter*>(tab)->update_pages();
- tab->load_config(config);
+ tab->load_config(config);
}
if (m_plater)
m_plater->on_config_change(config);
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 78bbe4fec..19db473d6 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -538,7 +538,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = config.opt_int(opt_key, idx);
break;
case coEnum:{
- if (opt_key.compare("external_fill_pattern") == 0 ||
+ if (opt_key.compare("top_fill_pattern") == 0 || opt_key.compare("bottom_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0 ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
}
@@ -547,13 +547,19 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
}
else if (opt_key.compare("support_material_pattern") == 0) {
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
- }
- else if (opt_key.compare("seam_position") == 0) {
- ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
- }
- else if (opt_key.compare("host_type") == 0) {
- ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
- }
+ }
+ else if (opt_key.compare("seam_position") == 0 || opt_key.compare("perimeter_loop_seam") == 0) {
+ ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
+ }
+ else if (opt_key.compare("host_type") == 0) {
+ ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
+ }
+ else if (opt_key.compare("infill_dense_algo") == 0){
+ ret = static_cast<int>(config.option<ConfigOptionEnum<DenseInfillAlgo>>(opt_key)->value);
+ }
+ else if (opt_key.compare("support_material_contact_distance_type") == 0){
+ ret = static_cast<int>(config.option<ConfigOptionEnum<SupportZDistanceType>>(opt_key)->value);
+ }
else if (opt_key.compare("display_orientation") == 0) {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLADisplayOrientation>>(opt_key)->value);
}
diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp
index d4ee9cf5f..cf15643f5 100644
--- a/src/slic3r/GUI/Preset.cpp
+++ b/src/slic3r/GUI/Preset.cpp
@@ -186,7 +186,7 @@ void Preset::set_num_extruders(DynamicPrintConfig &config, unsigned int num_extr
continue;
auto *opt = config.option(key, false);
assert(opt != nullptr);
- assert(opt->is_vector());
+ //assert(opt->is_vector());
if (opt != nullptr && opt->is_vector())
static_cast<ConfigOptionVectorBase*>(opt)->resize(num_extruders, defaults.option(key));
}
@@ -319,28 +319,45 @@ const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
- "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
- "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
+ "extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
+ "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
- "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
+ "bridge_speed", "gap_fill", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
- "min_skirt_length", "brim_width", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
+ "min_skirt_length", "brim_width", "brim_ears", "brim_ears_max_angle",
+ "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
- "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
- "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
+ "support_material_interface_spacing", "support_material_interface_contact_loops"
+ , "support_material_contact_distance_type"
+ , "support_material_contact_distance_top"
+ , "support_material_contact_distance_bottom"
+ , "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
- "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
- "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
- "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming",
- "compatible_printers", "compatible_printers_condition", "inherits"
+ "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio",
+ "clip_multipart_objects",
+ "over_bridge_flow_ratio", "clip_multipart_objects", "enforce_full_fill_volume", "external_infill_margin", "bridged_infill_margin",
+ "elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", "threads", "resolution",
+ "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging",
+ "only_one_perimeter_top", "single_extruder_multi_material_priming", "compatible_printers", "compatible_printers_condition", "inherits",
+ "infill_dense", "infill_dense_algo", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only",
+ "support_material_solid_first_layer"
+ , "exact_last_layer_height"
+ , "perimeter_loop"
+ , "perimeter_loop_seam"
+ , "seam_travel"
+ , "remove_small_gaps"
+ , "infill_not_connected"
+ , "first_layer_infill_speed"
+ , "label_printed_objects"
+ , "thin_walls_min_width"
};
return s_opts;
}
@@ -350,12 +367,13 @@ const std::vector<std::string>& Preset::filament_options()
static std::vector<std::string> s_opts {
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
"extrusion_multiplier", "filament_density", "filament_cost", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
- "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves",
+ "filament_unloading_speed", "filament_toolchange_delay", "filament_unloading_speed_start", "filament_unload_time", "filament_cooling_moves",
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
- "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
- "start_filament_gcode", "end_filament_gcode",
- "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
+ "max_fan_speed", "bridge_fan_speed", "top_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time",
+ "min_print_speed", "start_filament_gcode", "end_filament_gcode",
+ "compatible_prints", "compatible_prints_condition",
+ "compatible_printers", "compatible_printers_condition", "inherits"
};
return s_opts;
}
@@ -391,7 +409,9 @@ const std::vector<std::string>& Preset::nozzle_options()
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
static std::vector<std::string> s_opts {
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
- "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
+ "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below",
+ "retract_lift_not_last_layer",
+ "retract_speed", "deretract_speed",
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
"retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour",
"default_filament_profile"
@@ -913,7 +933,7 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
ui->SetSelection(selected_preset_item);
ui->SetToolTip(ui->GetString(selected_preset_item));
- ui->Thaw();
+ ui->Thaw();
}
size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible)
diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp
index 4c6c52763..798ed83d0 100644
--- a/src/slic3r/GUI/PresetBundle.cpp
+++ b/src/slic3r/GUI/PresetBundle.cpp
@@ -28,7 +28,7 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
-// Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir.
+// Store the print/filament/printer presets into a "presets" subdirectory of the Slic3r++ config dir.
// This breaks compatibility with the upstream Slic3r if the --datadir is used to switch between the two versions.
// #define SLIC3R_PROFILE_USE_PRESETS_SUBDIR
diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp
index 1835aacc1..01f240975 100644
--- a/src/slic3r/GUI/PresetHints.cpp
+++ b/src/slic3r/GUI/PresetHints.cpp
@@ -85,6 +85,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
double support_material_interface_speed = print_config.get_abs_value("support_material_interface_speed", support_material_speed);
double bridge_speed = print_config.opt_float("bridge_speed");
double bridge_flow_ratio = print_config.opt_float("bridge_flow_ratio");
+ double over_bridge_flow_ratio = print_config.opt_float("over_bridge_flow_ratio");
double perimeter_speed = print_config.opt_float("perimeter_speed");
double external_perimeter_speed = print_config.get_abs_value("external_perimeter_speed", perimeter_speed);
double gap_fill_speed = print_config.opt_float("gap_fill_speed");
@@ -106,6 +107,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
const auto &support_material_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("support_material_extrusion_width");
const auto &top_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("top_infill_extrusion_width");
const auto &first_layer_speed = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_speed");
+ const auto &first_layer_infill_speed = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_infill_speed");
// Index of an extruder assigned to a feature. If set to 0, an active extruder will be used for a multi-material print.
// If different from idx_extruder, it will not be taken into account for this hint.
@@ -142,6 +144,12 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
speed_normal = first_layer_speed.get_abs_value(speed_normal);
return (speed_normal > 0.) ? speed_normal : speed_max;
};
+ auto limit_infill_by_first_layer_speed = [&first_layer_infill_speed, first_layer](double speed_normal, double speed_max) {
+ if (first_layer && first_layer_infill_speed.value > 0)
+ // Apply the first layer limit.
+ speed_normal = first_layer_infill_speed.get_abs_value(speed_normal);
+ return (speed_normal > 0.) ? speed_normal : speed_max;
+ };
if (perimeter_extruder_active) {
double external_perimeter_rate = Flow::new_from_config_width(frExternalPerimeter,
first_positive(first_layer_extrusion_width_ptr, external_perimeter_extrusion_width, extrusion_width),
@@ -165,7 +173,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (! bridging && infill_extruder_active) {
double infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, infill_extrusion_width, extrusion_width),
- nozzle_diameter, lh, bfr).mm3_per_mm() * limit_by_first_layer_speed(infill_speed, max_print_speed);
+ nozzle_diameter, lh, bfr).mm3_per_mm() * limit_infill_by_first_layer_speed(infill_speed, max_print_speed);
if (max_flow < infill_rate) {
max_flow = infill_rate;
max_flow_extrusion_type = _CHB(L("infill"));
@@ -175,7 +183,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
double solid_infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, solid_infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, 0).mm3_per_mm() *
- (bridging ? bridge_speed : limit_by_first_layer_speed(solid_infill_speed, max_print_speed));
+ (bridging ? bridge_speed : limit_infill_by_first_layer_speed(solid_infill_speed, max_print_speed));
if (max_flow < solid_infill_rate) {
max_flow = solid_infill_rate;
max_flow_extrusion_type = _CHB(L("solid infill"));
@@ -183,7 +191,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (! bridging) {
double top_solid_infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, top_infill_extrusion_width, extrusion_width),
- nozzle_diameter, lh, bfr).mm3_per_mm() * limit_by_first_layer_speed(top_solid_infill_speed, max_print_speed);
+ nozzle_diameter, lh, bfr).mm3_per_mm() * limit_infill_by_first_layer_speed(top_solid_infill_speed, max_print_speed);
if (max_flow < top_solid_infill_rate) {
max_flow = top_solid_infill_rate;
max_flow_extrusion_type = _CHB(L("top solid infill"));
@@ -244,7 +252,7 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
std::string out;
if (layer_height <= 0.f){
- out += _CHB(L("Recommended object thin wall thickness: Not available due to invalid layer height."));
+ out += _CHB(L("Recommended object min wall thickness: Not available due to invalid layer height."));
return out;
}
@@ -261,14 +269,14 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
if (num_perimeters > 0) {
int num_lines = std::min(num_perimeters * 2, 10);
char buf[MIN_BUF_LENGTH/*256*/];
- sprintf(buf, _CHB(L("Recommended object thin wall thickness for layer height %.2f and ")), layer_height);
+ sprintf(buf, _CHB(L("Recommended object min wall thickness for layer height %.2f and ")), layer_height);
out += buf;
// Start with the width of two closely spaced
double width = external_perimeter_flow.width + external_perimeter_flow.spacing();
for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) {
if (i > 2)
out += ", ";
- sprintf(buf, _CHB(L("%d lines: %.2lf mm")), i, width);
+ sprintf(buf, _CHB(L("%d perimeter: %.2lf mm")), i/2, width);
out += buf;
width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f);
}
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 79952f184..da88789c2 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -529,8 +529,8 @@ void Tab::update_changed_tree_ui()
} else {
if (m_type == Slic3r::Preset::TYPE_FILAMENT || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL)
get_sys_and_mod_flags("compatible_prints", sys_page, modified_page);
- get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
- }
+ get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
+ }
}
for (auto group : page->m_optgroups)
{
@@ -916,7 +916,8 @@ void TabPrint::build()
auto page = add_options_page(_(L("Layers and perimeters")), "layers.png");
auto optgroup = page->new_optgroup(_(L("Layer height")));
optgroup->append_single_option_line("layer_height");
- optgroup->append_single_option_line("first_layer_height");
+ optgroup->append_single_option_line("first_layer_height");
+ optgroup->append_single_option_line("exact_last_layer_height");
optgroup = page->new_optgroup(_(L("Vertical shells")));
optgroup->append_single_option_line("perimeters");
@@ -933,36 +934,70 @@ void TabPrint::build()
line = { _(L("Solid layers")), "" };
line.append_option(optgroup->get_option("top_solid_layers"));
line.append_option(optgroup->get_option("bottom_solid_layers"));
- optgroup->append_line(line);
+ optgroup->append_line(line);
+ optgroup->append_single_option_line("enforce_full_fill_volume");
optgroup = page->new_optgroup(_(L("Quality (slower slicing)")));
optgroup->append_single_option_line("extra_perimeters");
+ optgroup->append_single_option_line("only_one_perimeter_top");
optgroup->append_single_option_line("ensure_vertical_shell_thickness");
optgroup->append_single_option_line("avoid_crossing_perimeters");
- optgroup->append_single_option_line("thin_walls");
+ line = { _(L("Thin walls")), "" };
+ line.append_option(optgroup->get_option("thin_walls"));
+ line.append_option(optgroup->get_option("thin_walls_min_width"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("overhangs");
+ line = { _(L("Avoid unsupported perimeters")), "" };
+ line.append_option(optgroup->get_option("no_perimeter_unsupported"));
+ line.append_option(optgroup->get_option("min_perimeter_unsupported"));
+ line.append_option(optgroup->get_option("noperi_bridge_only"));
+ optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Advanced")));
- optgroup->append_single_option_line("seam_position");
- optgroup->append_single_option_line("external_perimeters_first");
-
- page = add_options_page(_(L("Infill")), "infill.png");
- optgroup = page->new_optgroup(_(L("Infill")));
- optgroup->append_single_option_line("fill_density");
- optgroup->append_single_option_line("fill_pattern");
- optgroup->append_single_option_line("external_fill_pattern");
+ optgroup = page->new_optgroup(_(L("Advanced")));
+ optgroup->append_single_option_line("remove_small_gaps");
+ line = { _(L("Seam")), "" };
+ line.append_option(optgroup->get_option("seam_position"));
+ line.append_option(optgroup->get_option("seam_travel"));
+ optgroup->append_line(line);
+ optgroup->append_single_option_line("external_perimeters_first");
+ line = { _(L("Looping perimeter")), "" };
+ line.append_option(optgroup->get_option("perimeter_loop"));
+ line.append_option(optgroup->get_option("perimeter_loop_seam"));
+ optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Reducing printing time")));
- optgroup->append_single_option_line("infill_every_layers");
- optgroup->append_single_option_line("infill_only_where_needed");
+ page = add_options_page(_(L("Infill")), "infill.png");
+ optgroup = page->new_optgroup(_(L("Infill")));
+ optgroup->append_single_option_line("fill_density");
+ line = { _(L("Fill internal")), "" };
+ line.append_option(optgroup->get_option("fill_pattern"));
+ line.append_option(optgroup->get_option("infill_not_connected"));
+ optgroup->append_line(line);
+ line = { _(L("Fill external")), "" };
+ line.append_option(optgroup->get_option("top_fill_pattern"));
+ line.append_option(optgroup->get_option("bottom_fill_pattern"));
+ optgroup->append_line(line);
+ optgroup = page->new_optgroup(_(L("Reducing printing time")));
+ optgroup->append_single_option_line("infill_every_layers");
+ optgroup->append_single_option_line("infill_only_where_needed");
+ line = { _(L("Supporting dense layer")), "" };
+ line.append_option(optgroup->get_option("infill_dense"));
+ line.append_option(optgroup->get_option("infill_dense_algo"));
+ optgroup->append_line(line);
optgroup = page->new_optgroup(_(L("Advanced")));
optgroup->append_single_option_line("solid_infill_every_layers");
- optgroup->append_single_option_line("fill_angle");
optgroup->append_single_option_line("solid_infill_below_area");
- optgroup->append_single_option_line("bridge_angle");
+ line = { _(L("Angle")), "" };
+ line.append_option(optgroup->get_option("fill_angle"));
+ line.append_option(optgroup->get_option("bridge_angle"));
+ optgroup->append_line(line);
+ line = { _(L("Anchor solid infill by X mm")), "" };
+ line.append_option(optgroup->get_option("external_infill_margin"));
+ line.append_option(optgroup->get_option("bridged_infill_margin"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("only_retract_when_crossing_perimeters");
- optgroup->append_single_option_line("infill_first");
+ optgroup->append_single_option_line("infill_first");
+ optgroup->append_single_option_line("gap_fill");
page = add_options_page(_(L("Skirt and brim")), "box.png");
optgroup = page->new_optgroup(_(L("Skirt")));
@@ -972,7 +1007,11 @@ void TabPrint::build()
optgroup->append_single_option_line("min_skirt_length");
optgroup = page->new_optgroup(_(L("Brim")));
- optgroup->append_single_option_line("brim_width");
+ optgroup->append_single_option_line("brim_width");
+ line = { _(L("Brim ears")), "" };
+ line.append_option(optgroup->get_option("brim_ears"));
+ line.append_option(optgroup->get_option("brim_ears_max_angle"));
+ optgroup->append_line(line);
page = add_options_page(_(L("Support material")), "building.png");
optgroup = page->new_optgroup(_(L("Support material")));
@@ -981,12 +1020,17 @@ void TabPrint::build()
optgroup->append_single_option_line("support_material_threshold");
optgroup->append_single_option_line("support_material_enforce_layers");
- optgroup = page->new_optgroup(_(L("Raft")));
- optgroup->append_single_option_line("raft_layers");
+ optgroup = page->new_optgroup(_(L("Raft")));
+ optgroup->append_single_option_line("support_material_solid_first_layer");
+ optgroup->append_single_option_line("raft_layers");
// # optgroup->append_single_option_line(get_option_("raft_contact_distance");
optgroup = page->new_optgroup(_(L("Options for support material and raft")));
- optgroup->append_single_option_line("support_material_contact_distance");
+ line = { _(L("Z-offset")), "" };
+ line.append_option(optgroup->get_option("support_material_contact_distance_type"));
+ line.append_option(optgroup->get_option("support_material_contact_distance_top"));
+ line.append_option(optgroup->get_option("support_material_contact_distance_bottom"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("support_material_pattern");
optgroup->append_single_option_line("support_material_with_sheath");
optgroup->append_single_option_line("support_material_spacing");
@@ -1000,23 +1044,32 @@ void TabPrint::build()
optgroup->append_single_option_line("support_material_synchronize_layers");
page = add_options_page(_(L("Speed")), "time.png");
- optgroup = page->new_optgroup(_(L("Speed for print moves")));
- optgroup->append_single_option_line("perimeter_speed");
- optgroup->append_single_option_line("small_perimeter_speed");
- optgroup->append_single_option_line("external_perimeter_speed");
- optgroup->append_single_option_line("infill_speed");
- optgroup->append_single_option_line("solid_infill_speed");
- optgroup->append_single_option_line("top_solid_infill_speed");
- optgroup->append_single_option_line("support_material_speed");
- optgroup->append_single_option_line("support_material_interface_speed");
+ optgroup = page->new_optgroup(_(L("Speed for print moves")));
+ line = { _(L("Perimeter speed")), "" };
+ line.append_option(optgroup->get_option("perimeter_speed"));
+ line.append_option(optgroup->get_option("external_perimeter_speed"));
+ line.append_option(optgroup->get_option("small_perimeter_speed"));
+ optgroup->append_line(line);
+ line = { _(L("Infill speed")), "" };
+ line.append_option(optgroup->get_option("infill_speed"));
+ line.append_option(optgroup->get_option("solid_infill_speed"));
+ line.append_option(optgroup->get_option("top_solid_infill_speed"));
+ optgroup->append_line(line);
+ line = { _(L("Support speed")), "" };
+ line.append_option(optgroup->get_option("support_material_speed"));
+ line.append_option(optgroup->get_option("support_material_interface_speed"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("bridge_speed");
optgroup->append_single_option_line("gap_fill_speed");
optgroup = page->new_optgroup(_(L("Speed for non-print moves")));
optgroup->append_single_option_line("travel_speed");
- optgroup = page->new_optgroup(_(L("Modifiers")));
- optgroup->append_single_option_line("first_layer_speed");
+ optgroup = page->new_optgroup(_(L("Modifiers")));
+ line = { _(L("First layer speed")), "" };
+ line.append_option(optgroup->get_option("first_layer_speed"));
+ line.append_option(optgroup->get_option("first_layer_infill_speed"));
+ optgroup->append_line(line);
optgroup = page->new_optgroup(_(L("Acceleration control (advanced)")));
optgroup->append_single_option_line("perimeter_acceleration");
@@ -1044,9 +1097,11 @@ void TabPrint::build()
optgroup->append_single_option_line("standby_temperature_delta");
optgroup = page->new_optgroup(_(L("Wipe tower")));
- optgroup->append_single_option_line("wipe_tower");
- optgroup->append_single_option_line("wipe_tower_x");
- optgroup->append_single_option_line("wipe_tower_y");
+ optgroup->append_single_option_line("wipe_tower");
+ line = { _(L("Wipe tower position")), "" };
+ line.append_option(optgroup->get_option("wipe_tower_x"));
+ line.append_option(optgroup->get_option("wipe_tower_y"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("wipe_tower_width");
optgroup->append_single_option_line("wipe_tower_rotation_angle");
optgroup->append_single_option_line("wipe_tower_bridging");
@@ -1069,13 +1124,19 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Overlap")));
optgroup->append_single_option_line("infill_overlap");
- optgroup = page->new_optgroup(_(L("Flow")));
- optgroup->append_single_option_line("bridge_flow_ratio");
+ optgroup = page->new_optgroup(_(L("Flow")));
+ line = { _(L("Bridge flow ratio")), "" };
+ line.append_option(optgroup->get_option("bridge_flow_ratio"));
+ line.append_option(optgroup->get_option("over_bridge_flow_ratio"));
+ optgroup->append_line(line);
optgroup = page->new_optgroup(_(L("Other")));
- optgroup->append_single_option_line("clip_multipart_objects");
- optgroup->append_single_option_line("elefant_foot_compensation");
- optgroup->append_single_option_line("xy_size_compensation");
+ optgroup->append_single_option_line("clip_multipart_objects");
+ line = { _(L("XY compensation")), "" };
+ line.append_option(optgroup->get_option("xy_size_compensation"));
+ line.append_option(optgroup->get_option("elefant_foot_compensation"));
+ line.append_option(optgroup->get_option("hole_size_compensation"));
+ optgroup->append_line(line);
// # optgroup->append_single_option_line("threads");
optgroup->append_single_option_line("resolution");
@@ -1091,8 +1152,9 @@ void TabPrint::build()
line.append_option(option);
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Output file")));
- optgroup->append_single_option_line("gcode_comments");
+ optgroup = page->new_optgroup(_(L("Output file")));
+ optgroup->append_single_option_line("gcode_comments");
+ optgroup->append_single_option_line("label_printed_objects");
option = optgroup->get_option("output_filename_format");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
@@ -1152,15 +1214,22 @@ void TabPrint::update()
double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value;
- if (m_config->opt_bool("spiral_vase") &&
- !(m_config->opt_int("perimeters") == 1 && m_config->opt_int("top_solid_layers") == 0 &&
- fill_density == 0)) {
+ if (m_config->opt_bool("spiral_vase") && !(
+ m_config->opt_int("perimeters") == 1
+ && m_config->opt_int("top_solid_layers") == 0
+ && fill_density == 0
+ && m_config->opt_bool("support_material") == false
+ && m_config->opt_int("support_material_enforce_layers") == 0
+ && m_config->opt_bool("exact_last_layer_height") == false
+ && m_config->opt_bool("ensure_vertical_shell_thickness") == false
+ )) {
wxString msg_text = _(L("The Spiral Vase mode requires:\n"
"- one perimeter\n"
"- no top solid layers\n"
"- 0% fill density\n"
"- no support material\n"
"- no ensure_vertical_shell_thickness\n"
+ "- unchecked 'exact last layer height'\n"
"\nShall I adjust those settings in order to enable Spiral Vase?"));
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO);
is_msg_dlg_already_exist = true;
@@ -1170,7 +1239,8 @@ void TabPrint::update()
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
- new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
+ new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
+ new_conf.set_key_value("exact_last_layer_height", new ConfigOptionBool(false));
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
fill_density = 0;
}
@@ -1183,7 +1253,7 @@ void TabPrint::update()
}
if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") &&
- m_config->opt_float("support_material_contact_distance") > 0. &&
+ ((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value != zdNone &&
(m_config->opt_int("support_material_extruder") != 0 || m_config->opt_int("support_material_interface_extruder") != 0)) {
wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
"if they are printed with the current extruder without triggering a tool change.\n"
@@ -1201,7 +1271,7 @@ void TabPrint::update()
}
if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") &&
- m_config->opt_float("support_material_contact_distance") == 0 &&
+ ((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value == zdNone &&
!m_config->opt_bool("support_material_synchronize_layers")) {
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
"need to be synchronized with the object layers.\n"
@@ -1255,14 +1325,20 @@ void TabPrint::update()
break;
}
}
- if (!str_fill_pattern.empty()) {
- const std::vector<std::string> &external_fill_pattern = m_config->def()->get("external_fill_pattern")->enum_values;
+ if (!str_fill_pattern.empty()){
+ const std::vector<std::string> top_fill_pattern = m_config->def()->get("top_fill_pattern")->enum_values;
bool correct_100p_fill = false;
- for (const std::string &fill : external_fill_pattern)
+ for (const std::string &fill : top_fill_pattern)
{
if (str_fill_pattern == fill)
correct_100p_fill = true;
}
+ const std::vector<std::string> bottom_fill_pattern = m_config->def()->get("bottom_fill_pattern")->enum_values;
+ for (const std::string &fill : bottom_fill_pattern)
+ {
+ if (str_fill_pattern.compare(fill) == 0)
+ correct_100p_fill = true;
+ }
// get fill_pattern name from enum_labels for using this one at dialog_msg
str_fill_pattern = m_config->def()->get("fill_pattern")->enum_labels[fill_pattern];
if (!correct_100p_fill) {
@@ -1283,11 +1359,19 @@ void TabPrint::update()
}
}
- bool have_perimeters = m_config->opt_int("perimeters") > 0;
- for (auto el : {"extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
- "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
- "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" })
- get_field(el)->toggle(have_perimeters);
+ bool have_perimeters = m_config->opt_int("perimeters") > 0;
+ for (auto el : { "extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
+ "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width", "thin_walls_min_width",
+ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "perimeter_loop", "perimeter_loop_seam" })
+ get_field(el)->toggle(have_perimeters);
+
+ get_field("thin_walls_min_width")->toggle(m_config->opt_bool("thin_walls"));
+ get_field("perimeter_loop_seam")->toggle(m_config->opt_bool("perimeter_loop"));
+
+ bool have_no_perimeter_unsupported = have_perimeters && m_config->opt_bool("no_perimeter_unsupported");
+ for (auto el : { "min_perimeter_unsupported", "noperi_bridge_only" })
+ get_field(el)->toggle(have_no_perimeter_unsupported);
+
bool have_infill = m_config->option<ConfigOptionPercent>("fill_density")->value > 0;
// infill_extruder uses the same logic as in Print::extruders()
@@ -1295,17 +1379,24 @@ void TabPrint::update()
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
get_field(el)->toggle(have_infill);
+ bool can_have_infill_dense = m_config->option<ConfigOptionPercent>("fill_density")->value < 50;
+ for (auto el : { "infill_dense" })
+ get_field(el)->toggle(can_have_infill_dense);
+ bool have_infill_dense = m_config->opt_bool("infill_dense") && can_have_infill_dense;
+ for (auto el : { "infill_dense_algo" })
+ get_field(el)->toggle(have_infill_dense);
+
bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0;
// solid_infill_extruder uses the same logic as in Print::extruders()
- for (auto el : {"external_fill_pattern", "infill_first", "solid_infill_extruder",
- "solid_infill_extrusion_width", "solid_infill_speed" })
+ for (auto el : {"top_fill_pattern", "bottom_fill_pattern", "enforce_full_fill_volume", "external_infill_margin", "infill_first",
+ "solid_infill_extruder", "solid_infill_extrusion_width", "solid_infill_speed" })
get_field(el)->toggle(have_solid_infill);
for (auto el : {"fill_angle", "bridge_angle", "infill_extrusion_width",
"infill_speed", "bridge_speed" })
get_field(el)->toggle(have_infill || have_solid_infill);
- get_field("gap_fill_speed")->toggle(have_perimeters && have_infill);
+ get_field("gap_fill_speed")->toggle(have_perimeters && m_config->opt_bool("gap_fill"));
bool have_top_solid_infill = m_config->opt_int("top_solid_layers") > 0;
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
@@ -1324,17 +1415,24 @@ void TabPrint::update()
// perimeter_extruder uses the same logic as in Print::extruders()
get_field("perimeter_extruder")->toggle(have_perimeters || have_brim);
+ get_field("brim_ears")->toggle(have_brim);
+ get_field("brim_ears_max_angle")->toggle(have_brim && m_config->opt_bool("brim_ears"));
+
bool have_raft = m_config->opt_int("raft_layers") > 0;
bool have_support_material = m_config->opt_bool("support_material") || have_raft;
bool have_support_material_auto = have_support_material && m_config->opt_bool("support_material_auto");
bool have_support_interface = m_config->opt_int("support_material_interface_layers") > 0;
- bool have_support_soluble = have_support_material && m_config->opt_float("support_material_contact_distance") == 0;
+ bool have_support_soluble = have_support_material && ((ConfigOptionEnumGeneric*)m_config->option("support_material_contact_distance_type"))->value == zdNone;
for (auto el : {"support_material_pattern", "support_material_with_sheath",
"support_material_spacing", "support_material_angle", "support_material_interface_layers",
- "dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
+ "dont_support_bridges", "support_material_extrusion_width",
+ "support_material_contact_distance_type",
"support_material_xy_spacing" })
get_field(el)->toggle(have_support_material);
- get_field("support_material_threshold")->toggle(have_support_material_auto);
+ get_field("support_material_threshold")->toggle(have_support_material_auto);
+ for (auto el : { "support_material_contact_distance_top",
+ "support_material_contact_distance_bottom"})
+ get_field(el)->toggle(have_support_material && !have_support_soluble);
for (auto el : {"support_material_interface_spacing", "support_material_interface_extruder",
"support_material_interface_speed", "support_material_interface_contact_loops" })
@@ -1411,7 +1509,8 @@ void TabFilament::build()
line.append_option(optgroup->get_option("max_fan_speed"));
optgroup->append_line(line);
- optgroup->append_single_option_line("bridge_fan_speed");
+ optgroup->append_single_option_line("bridge_fan_speed");
+ optgroup->append_single_option_line("top_fan_speed");
optgroup->append_single_option_line("disable_fan_first_layers");
optgroup = page->new_optgroup(_(L("Cooling thresholds")), 250);
@@ -2131,8 +2230,9 @@ void TabPrinter::build_extruder_pages()
optgroup->append_single_option_line("retract_length", extruder_idx);
optgroup->append_single_option_line("retract_lift", extruder_idx);
Line line = { _(L("Only lift Z")), "" };
- line.append_option(optgroup->get_option("retract_lift_above", extruder_idx));
- line.append_option(optgroup->get_option("retract_lift_below", extruder_idx));
+ line.append_option(optgroup->get_option("retract_lift_above", extruder_idx));
+ line.append_option(optgroup->get_option("retract_lift_below", extruder_idx));
+ line.append_option(optgroup->get_option("retract_lift_not_last_layer", extruder_idx));
optgroup->append_line(line);
optgroup->append_single_option_line("retract_speed", extruder_idx);
@@ -2263,7 +2363,7 @@ void TabPrinter::update_fff()
// retract lift above / below only applies if using retract lift
vec.resize(0);
- vec = { "retract_lift_above", "retract_lift_below" };
+ vec = { "retract_lift_above", "retract_lift_below", "retract_lift_not_last_layer" };
for (auto el : vec)
get_field(el, i)->toggle(retraction && m_config->opt_float("retract_lift", i) > 0);
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index e00e87b62..8273dac78 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -339,7 +339,7 @@ public:
PrinterTechnology m_printer_technology = ptFFF;
- TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), "printer") {}
+ TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Hardware Settings")), "printer") {}
~TabPrinter() {}
void build() override;
diff --git a/t/fill.t b/t/fill.t
index 5cbd568dd..88cc35801 100644
--- a/t/fill.t
+++ b/t/fill.t
@@ -166,7 +166,8 @@ for my $pattern (qw(rectilinear honeycomb hilbertcurve concentric)) {
my $config = Slic3r::Config::new_from_defaults;
$config->set('nozzle_diameter', [0.4,0.4,0.4,0.4]);
$config->set('fill_pattern', $pattern);
- $config->set('external_fill_pattern', $pattern);
+ $config->set('top_fill_pattern', $pattern);
+ $config->set('bottom_fill_pattern', $pattern);
$config->set('perimeters', 1);
$config->set('skirts', 0);
$config->set('fill_density', 20);
diff --git a/t/flow.t b/t/flow.t
index 2fa0d8f10..e2de6542a 100644
--- a/t/flow.t
+++ b/t/flow.t
@@ -44,6 +44,7 @@ use Slic3r::Test;
my $config = Slic3r::Config::new_from_defaults;
$config->set('bridge_speed', 99);
$config->set('bridge_flow_ratio', 1);
+ $config->set('over_bridge_flow_ratio', 1);
$config->set('cooling', [ 0 ]); # to prevent speeds from being altered
$config->set('first_layer_speed', '100%'); # to prevent speeds from being altered
diff --git a/t/perimeters.t b/t/perimeters.t
index d0657cb23..0a2df78d0 100644
--- a/t/perimeters.t
+++ b/t/perimeters.t
@@ -248,6 +248,7 @@ use Slic3r::Test;
$config->set('slowdown_below_layer_time', [ 0 ]);
$config->set('bridge_fan_speed', [ 100 ]);
$config->set('bridge_flow_ratio', 33); # arbitrary value
+ $config->set('over_bridge_flow_ratio', 110); # arbitrary value
$config->set('overhangs', 1);
my $print = Slic3r::Test::init_print('overhang', config => $config);
my %layer_speeds = (); # print Z => [ speeds ]
@@ -290,6 +291,7 @@ use Slic3r::Test;
$config->set('layer_height', 0.4);
$config->set('first_layer_height', 0.35);
$config->set('extra_perimeters', 1);
+ $config->set('only_one_perimeter_top', 1);
$config->set('cooling', [ 0 ]); # to prevent speeds from being altered
$config->set('first_layer_speed', '100%'); # to prevent speeds from being altered
$config->set('perimeter_speed', 99);
diff --git a/t/thin.t b/t/thin.t
index 9147236ee..fcab28470 100644
--- a/t/thin.t
+++ b/t/thin.t
@@ -1,4 +1,4 @@
-use Test::More tests => 23;
+use Test::More tests => 29;
use strict;
use warnings;
@@ -102,7 +102,9 @@ if (0) {
is scalar(@$res), 1, 'medial axis of a semicircumference is a single line';
# check whether turns are all CCW or all CW
- my @lines = @{$res->[0]->lines};
+ my @alllines = @{$res->[0]->lines};
+ # remove lines taht are near the end.
+ my @lines = grep($_->a->y >= 1578184 || $_->b->y >= 1578184, @alllines);
my @angles = map { $lines[$_-1]->ccw($lines[$_]->b) } 1..$#lines;
ok !!(none { $_ < 0 } @angles) || (none { $_ > 0 } @angles),
'all medial axis segments of a semicircumference have the same orientation';
@@ -110,6 +112,37 @@ if (0) {
{
my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new_scale(
+ [4.3, 4], [4.3, 0], [4,0], [4,4], [0,4], [0,4.5], [4,4.5], [4,10], [4.3,10], [4.3, 4.5],
+ [6, 4.5], [6,10], [6.2,10], [6.2,4.5], [10,4.5], [10,4], [6.2,4], [6.2,0], [6, 0], [6, 4],
+ ));
+ $expolygon->contour->make_counter_clockwise();
+ my $res = $expolygon->medial_axis(scale 0.55, scale 0.25);
+ is scalar(@$res), 2, 'medial axis of a (bit too narrow) french cross is two lines';
+ ok unscale($res->[0]->length) >= (9.9) - epsilon, 'medial axis has reasonable length';
+ ok unscale($res->[1]->length) >= (9.9) - epsilon, 'medial axis has reasonable length';
+ my @lines1 = @{$res->[0]->lines};
+ my @angles1 = map { $lines1[$_-1]->ccw($lines1[$_]->b) } 1..$#lines1;
+ my @lines2 = @{$res->[1]->lines};
+ my @angles2 = map { $lines2[$_-1]->ccw($lines2[$_]->b) } 1..$#lines2;
+ my @angles = (@angles1, @angles2);
+ ok !!(none { $_ != 0 } @angles),
+ 'medial axis of a (bit too narrow) french cross is two lines has only strait lines';
+}
+
+{
+ my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new_scale(
+ [0.86526705,1.4509841], [0.57696039,1.8637021], [0.4502297,2.5569978], [0.45626199,3.2965596], [1.1218851,3.3049455], [0.96681072,2.8243202], [0.86328971,2.2056997], [0.85367905,1.7790778],
+ ));
+ $expolygon->contour->make_counter_clockwise();
+ my $res = $expolygon->medial_axis(scale 1, scale 0.25);
+ is scalar(@$res), 1, 'medial axis of a (bit too narrow) french cross is two lines';
+ ok unscale($res->[0]->length) >= (1.4) - epsilon, 'medial axis has reasonable length';
+ # TODO: check if min width is < 0.3 and max width is > 0.6 (min($res->[0]->width.front, $res->[0]->width.back) # problem: can't have access to width
+
+}
+
+{
+ my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new_scale(
[100, 100],
[120, 100],
[112, 200],
diff --git a/version.inc b/version.inc
index 3cdadcbb6..c24762003 100644
--- a/version.inc
+++ b/version.inc
@@ -1,7 +1,7 @@
# Included by CMakeLists, edited by the build script
# (the version numbers are generated by the build script from the git current label)
-set(SLIC3R_FORK_NAME "Slic3r Prusa Edition")
+set(SLIC3R_FORK_NAME "Slic3r++")
set(SLIC3R_VERSION "1.42.0-alpha2")
set(SLIC3R_BUILD "${SLIC3R_VERSION}+UNKNOWN")
set(SLIC3R_BUILD_ID "${SLIC3R_BUILD_ID}")