From b5d96e4ed6f5f56770d7c47f0359acbd623171a5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 25 Feb 2018 22:41:28 +0100 Subject: [PATCH 01/18] Update localization guide --- doc/Localization_manual.txt | 91 +++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/doc/Localization_manual.txt b/doc/Localization_manual.txt index f31d2c7f69..33fcc1c083 100644 --- a/doc/Localization_manual.txt +++ b/doc/Localization_manual.txt @@ -1,44 +1,75 @@ -From the begining you need to have GNUgettext and PoEdit. -GNUgettext package contains a set of tools to extract strings from the source code and -to create the Catalog to translation. -PoEdit provide good interface for the translators. +# Localization and translation guide + +The purpose of this guide is to describe how to contribute to the Slic3rPE translations. We use GNUgettext for extracting string resources from the project and PoEdit for editing translations. Those are possible to download here: - GNUgettext - https://sourceforge.net/directory/os:windows/?q=gnu+gettext - PoEdit - https://poedit.net/ +- https://sourceforge.net/directory/os:windows/?q=gnu+gettext GNUgettext package contains a set of tools to extract strings from the source code and to create the translation Catalog. +- https://poedit.net PoEdit provides good interface for the translators. -When GNUgettext and poEdit are downloaded and installationed, next step is -to add path to gettext/bin directory to your PATH variable. -You can use gettext from cmdline now. +After GNUgettext is installed it is recommended to add the path to gettext/bin to PATH variable. + +Full manual for GNUgettext you can see here: http://www.gnu.org/software/gettext/manual/gettext.html -In Slic3rPE we have one macro (L) used to markup strings to localizations. +### Scenario 1. How do I add a translation or fix the existing translation +1. Get PO-file from corresponding folder here: +https://github.com/prusa3d/Slic3r/tree/master/resources/localization +2. Open this file in PoEdit as "Edit a translation" +3. Apply your corrections to translation +4. Push changed Slic3rPE.po and Slic3rPE.mo (will create automatically after saving of Slic3r.po in PoEdit) back to to the enter folder. -So, to create Catalog to translation there are next steps: - 1. create list of files with this macro (list.txt) +### Scenario 2. How do I add a new language support +1. Get file Slic3rPE.pot here : +https://github.com/prusa3d/Slic3r/tree/master/resources/localization +2. Open it in PoEdit for "Create new translation" +3. Select Translation Language (for example French). +4. As a result you will have fr.po - the file contaning translation to French. +Notice. When the transtation is complete you need to: + - Rename the file to Slic3rPE.po + - Click "Save file" button. Slic3rPE.mo will be created immediatly + - Both Slic3rPE.po and Slic3rPE.mo have to be saved here: +https://github.com/prusa3d/Slic3r/tree/master/resources/localization/fr +( name of folder "fr" means "French" - the translation language). - 2. create template file(*.POT) with command: - xgettext --keyword=L --from-code=UTF-8 --debug -o Slic3rPE.pot -f list.txt - Use flag --from-code=UTF-8 to specify that the source strings are in UTF-8 encoding - Use flag --debug to correctly extract formated strings(used %d, %s etc.) +### Scenario 3. How do I add a new text resource when implementing a feature to Slic3rPE +Each string resource in Slic3rPE available for translation needs to be explicitly marked using L() macro like this: +```C++ +auto msg = L("This message to be localized") +``` +To get translated text use one of needed macro/function (`_(s)`, `_CHB(s)` or `L_str(s)` ). +If you add new file resourse, add it to list of files contaned macro `L()` - 3.1 if you start to create PO-file for your projest just open this POT-file in PoEdit. - When you select translation language after first opening of POT-files, - PO-file will be created immediatly. +### Scenario 4. How do I use GNUgettext to localize my own application taking Slic3rPE as an example - 3.2 if you already have PO-file created before, you have to merge old PO-file with - strings from creaded POT-file. You can do that with command: - msgmerge -N -o new.po old.po new.pot - Use option -N to not using fuzzy matching when an exact match is not found. +1. For conviniance create list of files with this macro `L(s)`. We have +https://github.com/prusa3d/Slic3r/tree/master/resources/localization/list.txt. - 3.3 if you already have PO-file created before and new PO-file created from new sourse files - which is not related with first one, you have to concatenate old PO-file with - strings from new PO-file. You can do that with command: - msgcat -o new.po old.po +2. Create template file(*.POT) with GNUgettext command: + ``` + xgettext --keyword=L --from-code=UTF-8 --debug -o Slic3rPE.pot -f list.txt + ``` - 4. create an English translation catalog with command: - msgen -o new.po old.po - Notice, in this Catalog it will be totally same strings for initial text and translated. + Use flag `--from-code=UTF-8` to specify that the source strings are in UTF-8 encoding + Use flag `--debug` to correctly extract formated strings(used %d, %s etc.) + +3. Create PO- and MO-files for your project as described above. + +4. To merge old PO-file with strings from creaded new POT-file use command: + ``` + msgmerge -N -o new.po old.po new.pot + ``` + Use option `-N` to not using fuzzy matching when an exact match is not found. + +5. To concatenate old PO-file with strings from new PO-file use command: + ``` + msgcat -o new.po old.po + ``` + +6. Create an English translation catalog with command: + ``` + msgen -o new.po old.po + ``` + Notice, in this Catalog it will be totally same strings for initial text and translated. When you have Catalog to translation open POT or PO file in PoEdit and start to translation. It's very important to keep attention to every gaps and punctuation. Especially with From 4c90e2bbc6a7fd9023c0fc2e2d85b0a51ba95af5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 25 Feb 2018 22:45:31 +0100 Subject: [PATCH 02/18] Rename localization guide to emphasize markdown format --- doc/{Localization_manual.txt => Localization_guide.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/{Localization_manual.txt => Localization_guide.md} (100%) diff --git a/doc/Localization_manual.txt b/doc/Localization_guide.md similarity index 100% rename from doc/Localization_manual.txt rename to doc/Localization_guide.md From bcc68ca45062503cdf0e758ef57306b55b75d004 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 26 Feb 2018 08:31:07 +0100 Subject: [PATCH 03/18] Added Slic3rPE.pot and list.txt to localization. --- resources/localization/Slic3rPE.pot | 3775 +++++++++++++++++++++++++++ resources/localization/list.txt | 14 + 2 files changed, 3789 insertions(+) create mode 100644 resources/localization/Slic3rPE.pot create mode 100644 resources/localization/list.txt diff --git a/resources/localization/Slic3rPE.pot b/resources/localization/Slic3rPE.pot new file mode 100644 index 0000000000..c61e7b2050 --- /dev/null +++ b/resources/localization/Slic3rPE.pot @@ -0,0 +1,3775 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-23 13:46+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:39 +msgid "Shape" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:46 +msgid "Rectangular" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:51 +msgid "Size in X and Y of the rectangular plate." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:57 +msgid "Origin" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:62 +msgid "Circular" +msgstr "" + +#: 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:779 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:799 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:858 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:876 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:894 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1042 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1050 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1092 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1101 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1111 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1119 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1127 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1213 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1419 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1489 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1525 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1702 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1709 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1716 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1725 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1735 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1745 +msgid "mm" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:66 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:431 +msgid "Diameter" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:71 +msgid "Custom" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:75 +msgid "Load shape from STL..." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:120 +msgid "Settings" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:298 +msgid "Choose a file to import bed shape from (STL/OBJ/AMF/PRUSA):" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:315 +msgid "Error! " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:324 +msgid "The selected file contains no geometry." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp:328 +msgid "" +"The selected file contains several disjoint areas. This is not supported." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.hpp:42 +msgid "Bed Shape" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:224 +msgid "Array of language names and identifiers should have the same size." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:235 +msgid "Select the language" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:235 +msgid "Language" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:300 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:170 +msgid "Default" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:325 +msgid "Change Application Language" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:332 +msgid "Application will be restarted" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:332 +msgid "Attention!" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:485 +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:471 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1300 +msgid "Error" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:490 +msgid "Notice" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:495 +msgid "GLUquadricObjPtr | Attempt to free unreferenced scalar" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp:497 +msgid "Warning" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:50 +msgid "Save current " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:51 +msgid "Delete this preset" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:314 +msgid "Layers and perimeters" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:315 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:775 +msgid "Layer height" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:319 +msgid "Vertical shells" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:330 +msgid "Horizontal shells" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:331 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1312 +msgid "Solid layers" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:336 +msgid "Quality (slower slicing)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:343 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:357 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:450 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:453 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:833 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1115 +#: 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:734 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1731 +msgid "Advanced" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:347 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:348 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:667 +#: 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:679 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:689 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:707 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:725 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:744 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1261 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1278 +msgid "Infill" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:353 +msgid "Reducing printing time" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:365 +msgid "Skirt and brim" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:366 +msgid "Skirt" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:372 +msgid "Brim" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:375 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:376 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:191 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1028 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1378 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1385 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1397 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1407 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1415 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1430 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1451 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1462 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1478 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1487 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1496 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1507 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1523 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1531 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1532 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1541 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1549 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1563 +msgid "Support material" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:381 +msgid "Raft" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:385 +msgid "Options for support material and raft" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:399 +#: 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:633 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:745 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:977 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1199 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1249 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1300 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1623 +msgid "Speed" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:400 +msgid "Speed for print moves" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:412 +msgid "Speed for non-print moves" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:415 +msgid "Modifiers" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:418 +msgid "Acceleration control (advanced)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:425 +msgid "Autospeed (advanced)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:431 +msgid "Multiple Extruders" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:432 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:968 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:308 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:700 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:956 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1270 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1443 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1469 +msgid "Extruders" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:439 +msgid "Ooze prevention" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:443 +msgid "Wipe tower" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:454 +msgid "Extrusion width" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:464 +msgid "Overlap" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:467 +msgid "Flow" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:470 +msgid "Other" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:477 +msgid "Output options" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:478 +msgid "Sequential printing" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:480 +msgid "Extruder clearance (mm)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:489 +msgid "Output file" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:495 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:999 +msgid "Post-processing scripts" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:501 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:502 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:861 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:862 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1158 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1159 +msgid "Notes" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:508 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:869 +msgid "Dependencies" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:509 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:870 +msgid "Profile dependencies" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:510 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:871 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1667 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:143 +msgid "Compatible printers" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:534 +#, possible-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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:541 +msgid "Spiral Vase" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:561 +msgid "" +"The Wipe Tower currently supports only:\n" +"- first layer height 0.2mm\n" +"- layer height from 0.15mm to 0.35mm\n" +"\n" +"Shall I adjust those settings in order to enable the Wipe Tower?" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:565 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:586 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:603 +msgid "Wipe Tower" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:582 +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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:600 +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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:618 +msgid "" +"Supports work better, if the following feature is enabled:\n" +"- Detect bridging perimeters\n" +"\n" +"Shall I adjust those settings for supports?" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:621 +msgid "Support Generator" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:665 +msgid "The " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:665 +#, possible-c-format +msgid "" +" infill pattern is not supposed to work at 100% density.\n" +"\n" +"Shall I switch to rectilinear fill pattern?" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:788 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:789 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:368 +msgid "Filament" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:796 +msgid "Temperature " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:797 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1234 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:307 +msgid "Extruder" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:802 +msgid "Bed" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:807 +msgid "Cooling" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:808 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:920 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1693 +msgid "Enable" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:819 +msgid "Fan settings" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:820 +msgid "Fan speed" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:828 +msgid "Cooling thresholds" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:834 +msgid "Filament properties" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:838 +msgid "Print speed override" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:848 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1121 +msgid "Custom G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:849 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1122 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1340 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1355 +msgid "Start G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:855 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1128 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:217 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:227 +msgid "End G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:939 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:11 +msgid "General" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:940 +msgid "Size and coordinates" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:942 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:34 +msgid "Bed shape" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:944 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1636 +msgid " Set " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:964 +msgid "Capabilities" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:969 +msgid "Number of extruders of the printer." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:991 +msgid "USB/Serial connection" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:992 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1191 +msgid "Serial port" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:997 +msgid "Rescan serial ports" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1006 +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1074 +msgid "Test" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1019 +msgid "Connection to printer works correctly." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1019 +msgid "Success!" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1022 +msgid "Connection failed." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1034 +msgid "OctoPrint upload" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1037 +msgid " Browse " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1049 +msgid "Button BROWSE was clicked!" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1084 +msgid "Button TEST was clicked!" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1112 +msgid "Firmware" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1134 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:48 +msgid "Before layer change G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1140 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:764 +msgid "After layer change G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1146 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1600 +msgid "Tool change G-code" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1152 +msgid "Between objects G-code (for sequential printing)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1188 +msgid "Extruder " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1194 +msgid "Layer height limits" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1199 +msgid "Position (for multi-extruder printers)" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1202 +msgid "Retraction" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1205 +msgid "Only lift Z" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1218 +msgid "" +"Retraction when tool is disabled (advanced settings for multi-extruder " +"setups)" +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:2116 +msgid "Preview" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1312 +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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1314 +msgid "Firmware Retraction" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1469 +msgid "Default " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1469 +msgid " preset" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1470 +msgid " preset\n" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1488 +msgid "" +"\n" +"\n" +"is not compatible with printer\n" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1488 +msgid "" +"\n" +"\n" +"and it has the following unsaved changes:" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1489 +msgid "" +"\n" +"\n" +"has the following unsaved changes:" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1491 +msgid "" +"\n" +"\n" +"Discard changes and continue anyway?" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1492 +msgid "Unsaved Changes" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1560 +msgid "The supplied name is empty. It can't be saved." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1580 +msgid "remove" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1580 +msgid "delete" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1581 +msgid "Are you sure you want to " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1581 +msgid " the selected preset?" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1582 +msgid "Remove" +msgstr "" + +#: 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:2012 +msgid "Delete" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1583 +msgid " Preset" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1635 +msgid "All" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1666 +msgid "Select the printers this profile is compatible with." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1750 +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:515 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1636 +msgid "Save " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1750 +msgid " as:" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1784 +msgid "" +"The supplied name is not valid; the following characters are not allowed:" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp:1787 +msgid "The supplied name is not available." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:182 +msgid "Print Settings" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:202 +msgid "Filament Settings" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:228 +msgid "Printer Settings" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp:248 +msgid "Save preset" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Field.cpp:43 +msgid "default" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:26 +#, possible-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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:30 +#, possible-c-format +msgid "" +"\n" +"If estimated layer time is greater, but still below ~%ds, fan will run at a " +"proportionally decreasing speed between %d%% and %d%%." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:34 +msgid "" +"\n" +"During the other layers, fan " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:36 +msgid "Fan " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:41 +#, possible-c-format +msgid "will always run at %d%% " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:44 +#, possible-c-format +msgid "except for the first %d layers" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:48 +msgid "except for the first layer" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:50 +msgid "will be turned off." +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:151 +msgid "external perimeters" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:160 +msgid "perimeters" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:169 +msgid "infill" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:179 +msgid "solid infill" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:187 +msgid "top solid infill" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:198 +msgid "support" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:208 +msgid "support interface" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214 +msgid "First layer volumetric" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214 +msgid "Bridging volumetric" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:214 +msgid "Volumetric" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:215 +msgid " flow rate is maximized " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:218 +msgid "by the print profile maximum" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:219 +msgid "when printing " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:220 +msgid " with a volumetric rate " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:224 +#, possible-c-format +msgid "%3.2f mm³/s" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:226 +#, possible-c-format +msgid " at filament speed %3.2f mm/s." +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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:262 +#, possible-c-format +msgid "Recommended object thin wall thickness for layer height %.2f and " +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp:269 +#, possible-c-format +msgid "%d lines: %.2lf mm" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.hpp:17 +msgid "Preferences" +msgstr "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:27 +msgid "Remember output directory" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:35 +msgid "Auto-center parts" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:43 +msgid "Background processing" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:51 +msgid "Disable USB/serial connection" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:59 +msgid "Suppress \" - default - \" presets" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:67 +msgid "Show incompatible print and filament presets" +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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:75 +msgid "Use legacy OpenGL 1.1 rendering" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp:101 +msgid "You need to restart Slic3r to make the changes effective." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:26 +msgid "Avoid crossing perimeters" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:38 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1570 +msgid "Other layers" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:42 +msgid "Bed temperature" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:59 +msgid "Between objects G-code" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:68 +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:371 +msgid "Bottom" +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:602 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:760 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:776 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:939 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:987 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1150 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1581 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1637 +msgid "Layers and Perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:70 +msgid "Number of solid layers to generate on bottom surfaces." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:72 +msgid "Bottom solid layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:77 +msgid "Bridge" +msgstr "" + +#: 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 "" + +#: 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:574 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:682 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:950 +msgid "mm/s²" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:86 +msgid "Bridging angle" +msgstr "" + +#: 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 "" + +#: 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:1168 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1179 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1399 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1555 +msgid "°" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:97 +msgid "Bridges fan speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:98 +msgid "This fan speed is enforced during all bridges and overhangs." +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:787 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:848 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1058 +msgid "%" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:106 +msgid "Bridge flow ratio" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:117 +msgid "Bridges" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:119 +msgid "Speed for printing bridges." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:120 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:636 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:747 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:809 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:866 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:979 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1135 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1144 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1534 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1647 +msgid "mm/s" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:127 +msgid "Brim width" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:135 +msgid "Clip multi-part objects" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:147 +msgid "Compatible printers condition" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:154 +msgid "Complete individual objects" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:163 +msgid "Enable auto cooling" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:180 +msgid "Disable fan for the first" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:183 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:692 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1031 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1222 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1283 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1435 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1480 +msgid "layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:190 +msgid "Don't support bridges" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:192 +msgid "" +"Experimental option for preventing support material from being generated " +"under bridged areas." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:198 +msgid "Distance between copies" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:199 +msgid "Distance used for the auto-arrange feature of the plater." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:207 +msgid "Elephant foot compensation" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:238 +msgid "Ensure vertical shell thickness" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:246 +msgid "Top/bottom fill pattern" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:267 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:277 +msgid "External perimeters" +msgstr "" + +#: 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:590 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:708 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:965 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1290 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1452 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1612 +msgid "Extrusion Width" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:272 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:595 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:713 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:970 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1294 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1456 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1617 +msgid "mm or % (leave 0 for default)" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:282 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:617 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1253 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1304 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1499 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1629 +msgid "mm/s or %" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:289 +msgid "External perimeters first" +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:297 +msgid "Extra perimeters if needed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:299 +#, possible-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 "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:320 +msgid "Height" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:331 +msgid "Radius" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:342 +msgid "Extruder Color" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:350 +msgid "Extruder offset" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:360 +msgid "Extrusion axis" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:367 +msgid "Extrusion multiplier" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:376 +msgid "Default extrusion width" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:382 +msgid "mm or % (leave 0 for auto)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:387 +msgid "Keep fan always on" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:394 +msgid "Enable fan if layer print time is below" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:397 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1240 +msgid "approximate seconds" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:405 +msgid "Color" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:412 +msgid "Filament notes" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:413 +msgid "You can put your notes regarding the filament here." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:421 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:815 +msgid "Max volumetric speed" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:425 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:818 +msgid "mm³/s" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:440 +msgid "Density" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:444 +msgid "g/cm³" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:450 +msgid "Filament type" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:451 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1000 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:470 +msgid "Soluble material" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:471 +msgid "Soluble material is most likely used for a soluble support." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:476 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:450 +msgid "Cost" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:477 +msgid "" +"Enter your filament cost per kg here. This is only for statistical " +"information." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:478 +msgid "money/kg" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:487 +msgid "Fill angle" +msgstr "" + +#: 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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:501 +msgid "Fill density" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:503 +#, possible-c-format +msgid "Density of internal infill, expressed in the range 0% - 100%." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:539 +msgid "Fill pattern" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:541 +msgid "Fill pattern for general low-density infill." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:571 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:580 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:589 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:623 +msgid "First layer" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:572 +msgid "" +"This is the acceleration your printer will use for first layer. Set zero to " +"disable acceleration control for first layer." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:581 +msgid "" +"Heated build plate temperature for the first layer. Set this to zero to " +"disable bed temperature control commands in the output." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:591 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:601 +msgid "First layer height" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:603 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:607 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:738 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1388 +msgid "mm or %" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:613 +msgid "First layer speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:614 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:624 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:632 +msgid "Gap fill" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:634 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:642 +msgid "Verbose G-code" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:643 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:650 +msgid "G-code flavor" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:651 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:680 +msgid "" +"This is the acceleration your printer will use for infill. Set zero to " +"disable acceleration control for infill." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:688 +msgid "Combine infill every" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:690 +msgid "" +"This feature allows to combine infill and speed up your print by extruding " +"thicker infill layers while preserving thin perimeters, thus accuracy." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:694 +msgid "Combine infill every n layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:699 +msgid "Infill extruder" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:701 +msgid "The extruder to use when printing infill." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:709 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:718 +msgid "Infill before perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:719 +msgid "" +"This option will switch the print order of perimeters and infill, making the " +"latter first." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:724 +msgid "Only infill where needed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:726 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:733 +msgid "Infill/perimeters overlap" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:735 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:746 +msgid "Speed for printing the internal fill. Set to zero for auto." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:755 +msgid "Interface shells" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:756 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:765 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:777 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:785 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:794 +msgid "Max" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:786 +msgid "This setting represents the maximum speed of your fan." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:795 +#, possible-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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:805 +msgid "Max print speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:806 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:816 +msgid "" +"This experimental setting is used to set the maximum volumetric speed your " +"extruder supports." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:824 +msgid "Max volumetric slope positive" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:825 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:836 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:829 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:840 +msgid "mm³/s²" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:835 +msgid "Max volumetric slope negative" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:846 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:855 +msgid "Min" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:847 +msgid "This setting represents the minimum PWM your fan needs to work." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:856 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:864 +msgid "Min print speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:865 +msgid "Slic3r will not scale speed down below this speed." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:872 +msgid "Minimum extrusion length" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:873 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:882 +msgid "Configuration notes" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:883 +msgid "" +"You can put here your personal notes. This text will be added to the G-code " +"header comments." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:892 +msgid "Nozzle diameter" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:893 +msgid "" +"This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:899 +msgid "API Key" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:900 +msgid "" +"Slic3r can upload G-code files to OctoPrint. This field should contain the " +"API Key required for authentication." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:906 +msgid "Host or IP" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:907 +msgid "" +"Slic3r can upload G-code files to OctoPrint. This field should contain the " +"hostname or IP address of the OctoPrint instance." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:913 +msgid "Only retract when crossing perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:914 +msgid "" +"Disables retraction when the travel path does not exceed the upper layer's " +"perimeters (and thus any ooze will be probably invisible)." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:921 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:928 +msgid "Output filename format" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:929 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:938 +msgid "Detect bridging perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:940 +msgid "" +"Experimental option to adjust flow for overhangs (bridge flow will be used), " +"to apply bridge speed to them and enable fan." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:946 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:964 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:976 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:986 +msgid "Perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:947 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:955 +msgid "Perimeter extruder" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:957 +msgid "" +"The extruder to use when printing perimeters and brim. First extruder is 1." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:966 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:978 +msgid "" +"Speed for perimeters (contours, aka vertical shells). Set to zero for auto." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:988 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:992 +msgid "(minimum)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1012 +msgid "Printer notes" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1013 +msgid "You can put your notes regarding the printer here." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1027 +msgid "Raft layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1029 +msgid "" +"The object will be raised by this number of layers, and support material " +"will be generated under it." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1037 +msgid "Resolution" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1038 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1048 +msgid "Minimum travel after retraction" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1049 +msgid "" +"Retraction is not triggered when travel moves are shorter than this length." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1055 +msgid "Retract amount before wipe" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1056 +msgid "" +"With bowden extruders, it may be wise to do some amount of quick retract " +"before doing the wipe movement." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1063 +msgid "Retract on layer change" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1064 +msgid "This flag enforces a retraction whenever a Z move is done." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1069 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1078 +msgid "Length" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1070 +msgid "Retraction Length" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1071 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1073 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1083 +msgid "mm (zero to disable)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1079 +msgid "Retraction Length (Toolchange)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1080 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1088 +msgid "Lift Z" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1089 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1097 +msgid "Above Z" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1098 +msgid "Only lift Z above" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1099 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1106 +msgid "Below Z" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1107 +msgid "Only lift Z below" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1108 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1116 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1124 +msgid "Extra length on restart" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1117 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1125 +msgid "" +"When the retraction is compensated after changing tool, the extruder will " +"push this additional amount of filament." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1132 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1133 +msgid "Retraction Speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1134 +msgid "The speed for retractions (it only applies to the extruder motor)." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1140 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1141 +msgid "Deretraction Speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1142 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1149 +msgid "Seam position" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1151 +msgid "Position of perimeters starting points." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1167 +msgid "Direction" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1169 +msgid "Preferred direction of the seam" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1170 +msgid "Seam preferred direction" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1178 +msgid "Jitter" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1180 +msgid "Seam preferred direction jitter" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1181 +msgid "Preferred direction of the seam - jitter" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1192 +msgid "USB/serial port for printer connection." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1200 +msgid "Serial port speed" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1201 +msgid "Speed (baud) of USB/serial port for printer connection." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1210 +msgid "Distance from object" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1211 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1219 +msgid "Skirt height" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1220 +msgid "" +"Height of skirt expressed in layers. Set this to a tall value to use skirt " +"as a shield against drafts." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1227 +msgid "Loops (minimum)" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1228 +msgid "Skirt Loops" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1229 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1237 +msgid "Slow down if layer print time is below" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1238 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1248 +msgid "Small perimeters" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1250 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1260 +msgid "Solid infill threshold area" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1262 +msgid "" +"Force solid infill for regions having a smaller area than the specified " +"threshold." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1263 +msgid "mm²" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1269 +msgid "Solid infill extruder" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1271 +msgid "The extruder to use when printing solid infill." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1277 +msgid "Solid infill every" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1279 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1289 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1299 +msgid "Solid infill" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1291 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1301 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1313 +msgid "Number of solid layers to generate on top and bottom surfaces." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1320 +msgid "Spiral vase" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1321 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1330 +msgid "Temperature variation" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1331 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1341 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1356 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1371 +msgid "Single Extruder Multi Material" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1372 +msgid "The printer multiplexes filaments into a single hot end." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1377 +msgid "Generate support material" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1379 +msgid "Enable support material generation." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1384 +msgid "XY separation between an object and its support" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1386 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1396 +msgid "Pattern angle" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1398 +msgid "" +"Use this setting to rotate the support material pattern on the horizontal " +"plane." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1406 +msgid "Support on build plate only" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1408 +msgid "" +"Only create support if it lies on a build plate. Don't create support on a " +"print." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1414 +msgid "Contact Z distance" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1416 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1429 +msgid "Enforce support for the first" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1431 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1437 +msgid "Enforce support for the first n layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1442 +msgid "Support material/raft/skirt extruder" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1444 +msgid "" +"The extruder to use when printing support material, raft and skirt (1+, 0 to " +"use the current extruder to minimize tool changes)." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1453 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1461 +msgid "Interface loops" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1463 +msgid "" +"Cover the top contact layer of the supports with loops. Disabled by default." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1468 +msgid "Support material/raft interface extruder" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1470 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1477 +msgid "Interface layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1479 +msgid "" +"Number of interface layers to insert between the object(s) and support " +"material." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1486 +msgid "Interface pattern spacing" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1488 +msgid "Spacing between interface lines. Set zero to get a solid interface." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1495 +msgid "Support material interface" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1497 +msgid "" +"Speed for printing support material interface layers. If expressed as " +"percentage (for example 50%) it will be calculated over support material " +"speed." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1506 +msgid "Pattern" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1508 +msgid "Pattern used to generate support material." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1522 +msgid "Pattern spacing" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1524 +msgid "Spacing between support material lines." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1533 +msgid "Speed for printing support material." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1540 +msgid "Synchronize with object layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1542 +msgid "" +"Synchronize support layers with the object print layers. This is useful with " +"multi-material printers, where the extruder switch is expensive." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1548 +msgid "Overhang threshold" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1550 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1562 +msgid "With sheath around the support" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1564 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1571 +msgid "" +"Extruder temperature for layers after the first one. Set this to zero to " +"disable temperature control commands in the output." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1574 +msgid "Temperature" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1580 +msgid "Detect thin walls" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1582 +msgid "" +"Detect single-width walls (parts where two extrusions don't fit and we need " +"to collapse them into a single trace)." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1588 +msgid "Threads" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1589 +msgid "" +"Threads are used to parallelize long-running tasks. Optimal threads number " +"is slightly above the number of available cores/processors." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1601 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1611 +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1622 +msgid "Top solid infill" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1613 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1624 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1636 +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:370 +msgid "Top" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1638 +msgid "Number of solid layers to generate on top surfaces." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1640 +msgid "Top solid layers" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1645 +msgid "Travel" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1646 +msgid "Speed for travel moves (jumps between distant extrusion points)." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1654 +msgid "Use firmware retraction" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1655 +msgid "" +"This experimental setting uses G10 and G11 commands to have the firmware " +"handle the retraction. This is only supported in recent Marlin." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1661 +msgid "Use relative E distances" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1662 +msgid "" +"If your firmware requires relative E values, check this, otherwise leave it " +"unchecked. Most firmwares use absolute values." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1668 +msgid "Use volumetric E" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1669 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1679 +msgid "Enable variable layer height feature" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1680 +msgid "" +"Some printers or printer setups may have difficulties printing with a " +"variable layer height. Enabled by default." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1686 +msgid "Wipe while retracting" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1687 +msgid "" +"This flag will move the nozzle while retracting to minimize the possible " +"blob on leaky extruders." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1694 +msgid "" +"Multi material printers may need to prime or purge extruders on tool " +"changes. Extrude the excess material into the wipe tower." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1700 +msgid "Position X" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1701 +msgid "X coordinate of the left front corner of a wipe tower" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1707 +msgid "Position Y" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1708 +msgid "Y coordinate of the left front corner of a wipe tower" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1714 +msgid "Width" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1715 +msgid "Width of a wipe tower" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1721 +msgid "Per color change depth" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1722 +msgid "" +"Depth of a wipe color per color change. For N colors, there will be maximum " +"(N-1) tool switches performed, therefore the total depth of the wipe tower " +"will be (N-1) times this value." +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1730 +msgid "XY Size Compensation" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1732 +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 "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1740 +msgid "Z offset" +msgstr "" + +#: C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp:1741 +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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:66 +msgid "Version " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:66 +msgid "" +" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:118 +msgid "Plater" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:120 +msgid "Controller" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:192 +msgid "No Bonjour device found" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:192 +msgid "Device Browser" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:211 +msgid "Connection to OctoPrint works correctly." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:214 +msgid "I wasn't able to connect to OctoPrint (" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:215 +msgid "). Check hostname and OctoPrint version (at least 1.1.0 is required)." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:251 +msgid "Open STL/OBJ/AMF…\tCtrl+O" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:251 +msgid "Open a model" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:254 +msgid "&Load Config…\tCtrl+L" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:254 +msgid "Load exported configuration file" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:257 +msgid "&Export Config…\tCtrl+E" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:257 +msgid "Export current configuration to file" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:260 +msgid "&Load Config Bundle…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:260 +msgid "Load presets from a bundle" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:263 +msgid "&Export Config Bundle…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:263 +msgid "Export all presets to file" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:268 +msgid "Q&uick Slice…\tCtrl+U" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:268 +msgid "Slice a file into a G-code" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:274 +msgid "Quick Slice and Save &As…\tCtrl+Alt+U" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:274 +msgid "Slice a file into a G-code, save as" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:280 +msgid "&Repeat Last Quick Slice\tCtrl+Shift+U" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:280 +msgid "Repeat last quick slice" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:287 +msgid "Slice to SV&G…\tCtrl+G" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:287 +msgid "Slice file to a multi-layer SVG" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:291 +msgid "(&Re)Slice Now\tCtrl+S" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:291 +msgid "Start new slicing process" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:294 +msgid "Repair STL file…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:294 +msgid "Automatically repair an STL file" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:299 +msgid "Preferences…\tCtrl+," +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:299 +msgid "Application preferences" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:305 +msgid "&Quit" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:305 +msgid "Quit Slic3r" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:315 +msgid "Export G-code..." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:315 +msgid "Export current plate as G-code" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:318 +msgid "Export plate as STL..." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:318 +msgid "Export current plate as STL" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:321 +msgid "Export plate as AMF..." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:321 +msgid "Export current plate as AMF" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:324 +msgid "Export plate as 3MF..." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:324 +msgid "Export current plate as 3MF" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:337 +msgid "Select &Plater Tab\tCtrl+1" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:337 +msgid "Show the plater" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:343 +msgid "Select &Controller Tab\tCtrl+T" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:343 +msgid "Show the printer controller" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:351 +msgid "Select P&rint Settings Tab\tCtrl+2" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:351 +msgid "Show the print settings" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:354 +msgid "Select &Filament Settings Tab\tCtrl+3" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:354 +msgid "Show the filament settings" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:357 +msgid "Select Print&er Settings Tab\tCtrl+4" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:357 +msgid "Show the printer settings" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:369 +msgid "Iso" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:369 +msgid "Iso View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:370 +msgid "Top View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:371 +msgid "Bottom View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:372 +msgid "Front" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:372 +msgid "Front View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:373 +msgid "Rear" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:373 +msgid "Rear View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:374 +msgid "Left" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:374 +msgid "Left View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:375 +msgid "Right" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:375 +msgid "Right View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:381 +msgid "&Configuration " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:381 +msgid "Run Configuration " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:386 +msgid "Prusa 3D Drivers" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:386 +msgid "Open the Prusa3D drivers download page in your browser" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:389 +msgid "Prusa Edition Releases" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:389 +msgid "Open the Prusa Edition releases page in your browser" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:396 +msgid "Slic3r &Website" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:396 +msgid "Open the Slic3r website in your browser" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:399 +msgid "Slic3r &Manual" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:399 +msgid "Open the Slic3r manual in your browser" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:403 +msgid "System Info" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:403 +msgid "Show system information" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:406 +msgid "Report an Issue" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:406 +msgid "Report an issue on the Slic3r Prusa Edition" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:409 +msgid "&About Slic3r" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:409 +msgid "Show about dialog" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:419 +msgid "&File" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:420 +msgid "&Plater" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:421 +msgid "&Object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:422 +msgid "&Window" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:423 +msgid "&View" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:427 +msgid "&Help" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:458 +msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:470 +msgid "No previously sliced file." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:475 +msgid "Previously sliced file (" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:475 +msgid ") not found." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:476 +msgid "File Not Found" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:515 +msgid "SVG" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:515 +msgid "G-code" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:515 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1636 +msgid " file as:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:529 +msgid "Slicing…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:529 +msgid "Processing " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:549 +msgid " was successfully sliced." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:551 +msgid "Slicing Done!" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:567 +msgid "Select the STL file to repair:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:581 +msgid "Save OBJ file (less prone to coordinate errors than STL) as:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:595 +msgid "Your file was repaired." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:595 +msgid "Repair" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:606 +msgid "Save configuration as:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:624 +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:668 +msgid "Select configuration to load:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:647 +msgid "Save presets bundle as:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:688 +#, possible-perl-format +msgid "%d presets successfully imported." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:750 +msgid "You have unsaved changes " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:750 +msgid ". Discard changes and continue anyway?" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:751 +msgid "Unsaved Presets" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:104 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2115 +msgid "3D" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:138 +msgid "2D" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:157 +msgid "Layers" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:177 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:195 +msgid "Add…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:179 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:197 +msgid "Delete All" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:180 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:198 +msgid "Arrange" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:182 +msgid "More" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:183 +msgid "Fewer" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:185 +msgid "45° ccw" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:186 +msgid "45° cw" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:187 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:203 +msgid "Scale…" +msgstr "" + +#: 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:2090 +msgid "Split" +msgstr "" + +#: 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:2093 +msgid "Cut…" +msgstr "" + +#: 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:2097 +msgid "Settings…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:192 +msgid "Layer Editing" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:207 +msgid "Layer editing" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:220 +msgid "Name" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:221 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:900 +msgid "Copies" +msgstr "" + +#: 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:2059 +msgid "Scale" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:236 +msgid "Export G-code…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:237 +msgid "Slice now" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:238 +msgid "Print…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:239 +msgid "Send to printer" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:240 +msgid "Export STL…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:367 +msgid "Print settings" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:369 +msgid "Printer" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:398 +msgid "Info" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:409 +msgid "Volume" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:410 +msgid "Facets" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:411 +msgid "Materials" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:412 +msgid "Manifold" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:438 +msgid "Sliced Info" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:447 +msgid "Used Filament (m)" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:448 +msgid "Used Filament (mm³)" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:449 +msgid "Used Filament (g)" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:451 +msgid "Estimated printing time" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:629 +msgid "Loading…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:629 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:643 +msgid "Processing input file\n" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:663 +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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:666 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:683 +msgid "Multi-part object detected" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:680 +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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:692 +msgid "Loaded " +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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:745 +msgid "Object too large?" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:900 +msgid "Enter the number of copies of the selected object:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:927 +msgid "" +"\n" +"Non-positive value." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:928 +msgid "" +"\n" +"Not a numeric value." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:929 +msgid "Slic3r Error" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:950 +msgid "Enter the rotation angle:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:950 +msgid "Rotate around " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:950 +msgid "Invalid rotation angle entered" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1030 +#, possible-perl-format +msgid "Enter the new size for the selected object (print bed: %smm):" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1031 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1035 +msgid "Scale along " +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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1035 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1061 +#, possible-perl-format +msgid "Enter the scale % for the selected object:" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1056 +msgid "Enter the new max size for the selected object:" +msgstr "" + +#: 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 "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1121 +msgid "" +"The selected object couldn't be split because it contains only one part." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1286 +msgid "Slicing cancelled" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1300 +msgid "Another export job is currently running." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1445 +msgid "File added to print queue" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1448 +msgid "Sending G-code file to the OctoPrint server..." +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1451 +msgid "G-code file exported to " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1454 +msgid "Export failed" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1524 +msgid "G-code file successfully uploaded to the OctoPrint server" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1526 +msgid "Error while uploading to the OctoPrint server: " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1539 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1581 +msgid "STL file exported to " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1592 +msgid "AMF file exported to " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1596 +msgid "Error exporting AMF file " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1608 +msgid "3MF file exported to " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1612 +msgid "Error exporting 3MF file " +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1949 +#, possible-perl-format +msgid "%d (%d shells)" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1951 +#, possible-perl-format +msgid "Auto-repaired (%d errors)" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1956 +#, possible-perl-format +msgid "" +"%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d " +"facets reversed, %d backwards edges" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:1961 +msgid "Yes" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2012 +msgid "Remove the selected object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2015 +msgid "Increase copies" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2015 +msgid "Place one more copy of the selected object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2018 +msgid "Decrease copies" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2018 +msgid "Remove one copy of the selected object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2021 +msgid "Set number of copies…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2021 +msgid "Change the number of copies of the selected object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2025 +msgid "Rotate 45° clockwise" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2025 +msgid "Rotate the selected object by 45° clockwise" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2028 +msgid "Rotate 45° counter-clockwise" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2028 +msgid "Rotate the selected object by 45° counter-clockwise" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2033 +msgid "Rotate" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2033 +msgid "Rotate the selected object by an arbitrary angle" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2035 +msgid "Around X axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2035 +msgid "Rotate the selected object by an arbitrary angle around X axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2038 +msgid "Around Y axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2038 +msgid "Rotate the selected object by an arbitrary angle around Y axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2041 +msgid "Around Z axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2041 +msgid "Rotate the selected object by an arbitrary angle around Z axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2046 +msgid "Mirror" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2046 +msgid "Mirror the selected object" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2048 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2064 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2080 +msgid "Along X axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2048 +msgid "Mirror the selected object along the X axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2051 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2067 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2083 +msgid "Along Y axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2051 +msgid "Mirror the selected object along the Y axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2054 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2070 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2086 +msgid "Along Z axis…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2054 +msgid "Mirror the selected object along the Z axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2059 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2075 +msgid "Scale the selected object along a single axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2061 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2077 +msgid "Uniformly…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2061 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2077 +msgid "Scale the selected object along the XYZ axes" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2064 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2080 +msgid "Scale the selected object along the X axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2067 +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2083 +msgid "Scale the selected object along the Y axis" +msgstr "" + +#: 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 Z axis" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2075 +msgid "Scale to size" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2090 +msgid "Split the selected object into individual parts" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2093 +msgid "Open the 3D cutting tool" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2097 +msgid "Open the object editor dialog" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2101 +msgid "Reload from Disk" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2101 +msgid "Reload the selected file from Disk" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2104 +msgid "Export object as STL…" +msgstr "" + +#: c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm:2104 +msgid "Export this single object as STL file" +msgstr "" diff --git a/resources/localization/list.txt b/resources/localization/list.txt new file mode 100644 index 0000000000..5afe50a2fd --- /dev/null +++ b/resources/localization/list.txt @@ -0,0 +1,14 @@ +c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.hpp +c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp +c:\src\Slic3r\xs\src\slic3r\GUI\Field.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\OptionsGroup.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\2DBed.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp +c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.hpp +c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp +C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp +c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm +c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm \ No newline at end of file From 0ec68eb35b0c863aece86fee98807cb299d69124 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 28 Feb 2018 11:41:04 +0100 Subject: [PATCH 04/18] Fix for issue #661 (ExPolygons generation) --- xs/src/libslic3r/TriangleMesh.cpp | 67 ++++++++++++++++++------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 1cdfb091dc..ffbe507ef2 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -1186,40 +1186,46 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic loops correctly in some edge cases when original model had overlapping facets */ - std::vector area; - std::vector sorted_area; // vector of indices - for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) { - area.push_back(loop->area()); - sorted_area.push_back(loop - loops.begin()); - } - - // outer first - std::sort(sorted_area.begin(), sorted_area.end(), - [&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); }); + /* The following lines are commented out because they can generate wrong polygons, + see for example issue #661 */ - // we don't perform a safety offset now because it might reverse cw loops - Polygons p_slices; - for (std::vector::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) { - /* we rely on the already computed area to determine the winding order - of the loops, since the Orientation() function provided by Clipper - would do the same, thus repeating the calculation */ - Polygons::const_iterator loop = loops.begin() + *loop_idx; - if (area[*loop_idx] > +EPSILON) - p_slices.push_back(*loop); - else if (area[*loop_idx] < -EPSILON) - //FIXME This is arbitrary and possibly very slow. - // If the hole is inside a polygon, then there is no need to diff. - // If the hole intersects a polygon boundary, then diff it, but then - // there is no guarantee of an ordering of the loops. - // Maybe we can test for the intersection before running the expensive diff algorithm? - p_slices = diff(p_slices, *loop); - } + //std::vector area; + //std::vector sorted_area; // vector of indices + //for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) { + // area.push_back(loop->area()); + // sorted_area.push_back(loop - loops.begin()); + //} + // + //// outer first + //std::sort(sorted_area.begin(), sorted_area.end(), + // [&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); }); + + //// we don't perform a safety offset now because it might reverse cw loops + //Polygons p_slices; + //for (std::vector::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) { + // /* we rely on the already computed area to determine the winding order + // of the loops, since the Orientation() function provided by Clipper + // would do the same, thus repeating the calculation */ + // Polygons::const_iterator loop = loops.begin() + *loop_idx; + // if (area[*loop_idx] > +EPSILON) + // p_slices.push_back(*loop); + // else if (area[*loop_idx] < -EPSILON) + // //FIXME This is arbitrary and possibly very slow. + // // If the hole is inside a polygon, then there is no need to diff. + // // If the hole intersects a polygon boundary, then diff it, but then + // // there is no guarantee of an ordering of the loops. + // // Maybe we can test for the intersection before running the expensive diff algorithm? + // p_slices = diff(p_slices, *loop); + //} // perform a safety offset to merge very close facets (TODO: find test case for this) double safety_offset = scale_(0.0499); //FIXME see https://github.com/prusa3d/Slic3r/issues/520 // double safety_offset = scale_(0.0001); - ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset); + + /* The following line is commented out because it can generate wrong polygons, + see for example issue #661 */ + //ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset); #ifdef SLIC3R_TRIANGLEMESH_DEBUG size_t holes_count = 0; @@ -1230,7 +1236,10 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic #endif // append to the supplied collection - expolygons_append(*slices, ex_slices); + /* Fix for issue #661 { */ + expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset)); + //expolygons_append(*slices, ex_slices); + /* } */ } void TriangleMeshSlicer::make_expolygons(std::vector &lines, ExPolygons* slices) const From 2a378f65907ed523aa125de0073ed3b632f4047f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 2 Mar 2018 13:41:37 +0100 Subject: [PATCH 05/18] Fixed problem with changing extruders color --- xs/src/slic3r/GUI/GUI.cpp | 8 ++--- xs/src/slic3r/GUI/Tab.cpp | 61 +++++++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index b0d3f7629a..d962471131 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -407,7 +407,7 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b } case coPercents: case coFloats:{ - double& val = config.opt_float(opt_key, 0); + double& val = config.opt_float(opt_key, opt_index); val = boost::any_cast(value); break; } @@ -422,7 +422,7 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b } else{ ConfigOptionStrings* vec_new = new ConfigOptionStrings{ boost::any_cast(value) }; - config.option(opt_key)->set_at(vec_new, opt_index, opt_index); + config.option(opt_key)->set_at(vec_new, opt_index, 0); } } break; @@ -431,14 +431,14 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b break; case coBools:{ ConfigOptionBools* vec_new = new ConfigOptionBools{ boost::any_cast(value) }; - config.option(opt_key)->set_at(vec_new, opt_index, opt_index); + config.option(opt_key)->set_at(vec_new, opt_index, 0); break;} case coInt: config.set_key_value(opt_key, new ConfigOptionInt(boost::any_cast(value))); break; case coInts:{ ConfigOptionInts* vec_new = new ConfigOptionInts{ boost::any_cast(value) }; - config.option(opt_key)->set_at(vec_new, opt_index, opt_index); + config.option(opt_key)->set_at(vec_new, opt_index, 0); } break; case coEnum:{ diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 00c749ce33..785a6c1659 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -153,6 +153,7 @@ void Tab::load_config(DynamicPrintConfig config) { bool modified = 0; boost::any value; + int opt_index = 0; for(auto opt_key : m_config->diff(config)) { switch ( config.def()->get(opt_key)->type ){ case coFloatOrPercent: @@ -167,29 +168,65 @@ void Tab::load_config(DynamicPrintConfig config) case coString: value = config.opt_string(opt_key); break; - case coPercents: - value = config.option(opt_key)->values.at(0); + case coPercents:{ + for (int i = 0; i < config.option(opt_key)->values.size(); i++) + if (config.option(opt_key)->values[i] != + m_config->option(opt_key)->values[i]){ + value = config.option(opt_key)->values[i]; + opt_index = i; + break; + } + } break; - case coFloats: - value = config.opt_float(opt_key, 0); + case coFloats:{ + for (int i = 0; i < config.option(opt_key)->values.size(); i++) + if (config.option(opt_key)->values[i] != + m_config->option(opt_key)->values[i]){ + value = config.option(opt_key)->values[i]; + opt_index = i; + break; + } + } break; - case coStrings: + case coStrings:{ if (config.option(opt_key)->values.empty()) value = ""; - else - value = config.opt_string(opt_key, static_cast(0)); + else{ + for (int i = 0; i < config.option(opt_key)->values.size(); i++) + if (config.option(opt_key)->values[i] != + m_config->option(opt_key)->values[i]){ + value = config.option(opt_key)->values[i]; + opt_index = i; + break; + } + } + } break; case coBool: value = config.opt_bool(opt_key); break; - case coBools: - value = config.opt_bool(opt_key, 0); + case coBools:{ + for (int i = 0; i < config.option(opt_key)->values.size(); i++) + if (config.option(opt_key)->values[i] != + m_config->option(opt_key)->values[i]){ + value = config.option(opt_key)->values[i]; + opt_index = i; + break; + } + } break; case coInt: value = config.opt_int(opt_key); break; - case coInts: - value = config.opt_int(opt_key, 0); + case coInts:{ + for (int i = 0; i < config.option(opt_key)->values.size(); i++) + if (config.option(opt_key)->values[i] != + m_config->option(opt_key)->values[i]){ + value = config.option(opt_key)->values[i]; + opt_index = i; + break; + } + } break; case coEnum:{ if (opt_key.compare("external_fill_pattern") == 0 || @@ -210,7 +247,7 @@ void Tab::load_config(DynamicPrintConfig config) default: break; } - change_opt_value(*m_config, opt_key, value); + change_opt_value(*m_config, opt_key, value, opt_index); modified = 1; } if (modified) { From 777bcf58655bb3238fedaf2d572c6f3638c61c97 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 2 Mar 2018 18:14:19 +0100 Subject: [PATCH 06/18] Enabled Boost_DEBUG in CMake to get some debug info when something goes wrong. --- xs/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index caabeab6b0..403d59182e 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -475,6 +475,7 @@ if(SLIC3R_STATIC) # Use boost libraries linked statically to the C++ runtime. # set(Boost_USE_STATIC_RUNTIME ON) endif() +set(Boost_DEBUG ON) find_package(Boost REQUIRED COMPONENTS system filesystem thread log locale regex) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) From ed7c02d578ae329dcd8327222a99ea09a93e102a Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 2 Mar 2018 23:11:57 +0100 Subject: [PATCH 07/18] Disabled the CMake BOOST debugging. --- xs/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 403d59182e..35d1fc7de9 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -475,7 +475,7 @@ if(SLIC3R_STATIC) # Use boost libraries linked statically to the C++ runtime. # set(Boost_USE_STATIC_RUNTIME ON) endif() -set(Boost_DEBUG ON) +#set(Boost_DEBUG ON) find_package(Boost REQUIRED COMPONENTS system filesystem thread log locale regex) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) From f750abb9db5c4d5105adb31343f4932f9076db7b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 4 Mar 2018 15:21:01 +0100 Subject: [PATCH 08/18] Refactor load_config() function --- xs/src/slic3r/GUI/Tab.cpp | 72 +++++++++++++-------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 785a6c1659..d93f09b02b 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -147,6 +147,18 @@ void Tab::update_tab_ui() m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets); } +template +boost::any get_new_value(const DynamicPrintConfig &config_new, const DynamicPrintConfig &config_old, std::string opt_key, int &index) +{ + for (int i = 0; i < config_new.option(opt_key)->values.size(); i++) + if (config_new.option(opt_key)->values[i] != + config_old.option(opt_key)->values[i]){ + index = i; + break; + } + return config_new.option(opt_key)->values[index]; +} + // Load a provied DynamicConfig into the tab, modifying the active preset. // This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view. void Tab::load_config(DynamicPrintConfig config) @@ -168,65 +180,27 @@ void Tab::load_config(DynamicPrintConfig config) case coString: value = config.opt_string(opt_key); break; - case coPercents:{ - for (int i = 0; i < config.option(opt_key)->values.size(); i++) - if (config.option(opt_key)->values[i] != - m_config->option(opt_key)->values[i]){ - value = config.option(opt_key)->values[i]; - opt_index = i; - break; - } - } + case coPercents: + value = get_new_value(config, *m_config, opt_key, opt_index); break; - case coFloats:{ - for (int i = 0; i < config.option(opt_key)->values.size(); i++) - if (config.option(opt_key)->values[i] != - m_config->option(opt_key)->values[i]){ - value = config.option(opt_key)->values[i]; - opt_index = i; - break; - } - } + case coFloats: + value = get_new_value(config, *m_config, opt_key, opt_index); break; - case coStrings:{ - if (config.option(opt_key)->values.empty()) - value = ""; - else{ - for (int i = 0; i < config.option(opt_key)->values.size(); i++) - if (config.option(opt_key)->values[i] != - m_config->option(opt_key)->values[i]){ - value = config.option(opt_key)->values[i]; - opt_index = i; - break; - } - } - } + case coStrings: + value = config.option(opt_key)->values.empty() ? "" : + get_new_value(config, *m_config, opt_key, opt_index); break; case coBool: value = config.opt_bool(opt_key); break; - case coBools:{ - for (int i = 0; i < config.option(opt_key)->values.size(); i++) - if (config.option(opt_key)->values[i] != - m_config->option(opt_key)->values[i]){ - value = config.option(opt_key)->values[i]; - opt_index = i; - break; - } - } + case coBools: + value = get_new_value(config, *m_config, opt_key, opt_index); break; case coInt: value = config.opt_int(opt_key); break; - case coInts:{ - for (int i = 0; i < config.option(opt_key)->values.size(); i++) - if (config.option(opt_key)->values[i] != - m_config->option(opt_key)->values[i]){ - value = config.option(opt_key)->values[i]; - opt_index = i; - break; - } - } + case coInts: + value = get_new_value(config, *m_config, opt_key, opt_index); break; case coEnum:{ if (opt_key.compare("external_fill_pattern") == 0 || From 802579ad209f9b2a64f43dc8aa0e96d0a21672ad Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 5 Mar 2018 10:53:18 +0100 Subject: [PATCH 09/18] Fixed crash while exporting to .amf and .gcode files (#753) - (improves previous fix: https://github.com/prusa3d/Slic3r/commit/d4f1ed0036183153464df7b5eef66cf60c7c6433) --- xs/src/libslic3r/GCode.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 28c03ba2c8..8ad479532b 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1402,18 +1402,13 @@ void GCode::apply_print_config(const PrintConfig &print_config) void GCode::append_full_config(const Print& print, std::string& str) { - char buff[4096]; - const StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config }; for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) { const StaticPrintConfig *cfg = configs[i]; for (const std::string &key : cfg->keys()) { if (key != "compatible_printers") - { - sprintf(buff, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); - str += buff; - } + str += "; " + key + " = " + cfg->serialize(key) + "\n"; } } } From 14929e9d156351221b6da192710437bb50409f29 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Wed, 7 Feb 2018 11:37:15 +0100 Subject: [PATCH 10/18] Http client via libcurl --- cmake/modules/FindCURL.cmake | 59 ++++++++ xs/CMakeLists.txt | 7 + xs/src/slic3r/Utils/Http.cpp | 261 +++++++++++++++++++++++++++++++++++ xs/src/slic3r/Utils/Http.hpp | 53 +++++++ 4 files changed, 380 insertions(+) create mode 100644 cmake/modules/FindCURL.cmake create mode 100644 xs/src/slic3r/Utils/Http.cpp create mode 100644 xs/src/slic3r/Utils/Http.hpp diff --git a/cmake/modules/FindCURL.cmake b/cmake/modules/FindCURL.cmake new file mode 100644 index 0000000000..b8724858c8 --- /dev/null +++ b/cmake/modules/FindCURL.cmake @@ -0,0 +1,59 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindCURL +# -------- +# +# Find curl +# +# Find the native CURL headers and libraries. +# +# :: +# +# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc. +# CURL_LIBRARIES - List of libraries when using curl. +# CURL_FOUND - True if curl found. +# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8) + +# Look for the header file. +find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) +mark_as_advanced(CURL_INCLUDE_DIR) + +# Look for the library (sorted from most current/relevant entry to least). +find_library(CURL_LIBRARY NAMES + curl + # Windows MSVC Makefile: + libcurl_a + # Windows MSVC prebuilts: + curllib + libcurl_imp + curllib_static + # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip): + libcurl +) +mark_as_advanced(CURL_LIBRARY) + +if(CURL_INCLUDE_DIR) + foreach(_curl_version_header curlver.h curl.h) + if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}") + file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}") + unset(curl_version_str) + break() + endif() + endforeach() +endif() + +find_package_handle_standard_args(CURL + REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR + VERSION_VAR CURL_VERSION_STRING) + +if(CURL_FOUND) + set(CURL_LIBRARIES ${CURL_LIBRARY}) + set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) + + message(STATUS " Curl libraries: = ${CURL_LIBRARIES}") + message(STATUS " Curl include dirs: = ${CURL_INCLUDE_DIRS}") +endif() diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index caabeab6b0..d2f252030d 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -199,6 +199,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/2DBed.hpp ${LIBDIR}/slic3r/GUI/wxExtensions.cpp ${LIBDIR}/slic3r/GUI/wxExtensions.hpp + ${LIBDIR}/slic3r/Utils/Http.cpp + ${LIBDIR}/slic3r/Utils/Http.hpp ) add_library(admesh STATIC @@ -522,6 +524,11 @@ if (SLIC3R_PRUSACONTROL) target_link_libraries(XS ${wxWidgets_LIBRARIES}) endif() +find_package(CURL REQUIRED) +include_directories(${CURL_INCLUDE_DIRS}) +target_link_libraries(XS ${CURL_LIBRARIES}) + + ## OPTIONAL packages # Find eigen3 or use bundled version diff --git a/xs/src/slic3r/Utils/Http.cpp b/xs/src/slic3r/Utils/Http.cpp new file mode 100644 index 0000000000..45a350a596 --- /dev/null +++ b/xs/src/slic3r/Utils/Http.cpp @@ -0,0 +1,261 @@ +#include "Http.hpp" + +#include +#include +#include +#include +#include +#include + +#include + +#include "../../libslic3r/libslic3r.h" + + +namespace Slic3r { + + +// Private + +class CurlGlobalInit +{ + static const CurlGlobalInit instance; + + CurlGlobalInit() { ::curl_global_init(CURL_GLOBAL_DEFAULT); } + ~CurlGlobalInit() { ::curl_global_cleanup(); } +}; + +struct Http::priv +{ + enum { + DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024, + }; + + ::CURL *curl; + ::curl_httppost *form; + ::curl_httppost *form_end; + ::curl_slist *headerlist; + std::string buffer; + size_t limit; + + std::thread io_thread; + Http::CompleteFn completefn; + Http::ErrorFn errorfn; + + priv(const std::string &url); + ~priv(); + + static size_t writecb(void *data, size_t size, size_t nmemb, void *userp); + std::string body_size_error(); + void http_perform(); +}; + +Http::priv::priv(const std::string &url) : + curl(::curl_easy_init()), + form(nullptr), + form_end(nullptr), + headerlist(nullptr) +{ + if (curl == nullptr) { + throw std::runtime_error(std::string("Could not construct Curl object")); + } + + ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // curl makes a copy internally + ::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_FORK_NAME "/" SLIC3R_VERSION); +} + +Http::priv::~priv() +{ + ::curl_easy_cleanup(curl); + ::curl_formfree(form); + ::curl_slist_free_all(headerlist); +} + +size_t Http::priv::writecb(void *data, size_t size, size_t nmemb, void *userp) +{ + auto self = static_cast(userp); + const char *cdata = static_cast(data); + const size_t realsize = size * nmemb; + + const size_t limit = self->limit > 0 ? self->limit : DEFAULT_SIZE_LIMIT; + if (self->buffer.size() + realsize > limit) { + // This makes curl_easy_perform return CURLE_WRITE_ERROR + return 0; + } + + self->buffer.append(cdata, realsize); + + return realsize; +} + +std::string Http::priv::body_size_error() +{ + return (boost::format("HTTP body data size exceeded limit (%1% bytes)") % limit).str(); +} + +void Http::priv::http_perform() +{ + ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast(this)); + +#ifndef NDEBUG + ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); +#endif + + if (headerlist != nullptr) { + ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); + } + + if (form != nullptr) { + ::curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); + } + + CURLcode res = ::curl_easy_perform(curl); + long http_status = 0; + ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status); + + if (res != CURLE_OK) { + std::string error; + if (res == CURLE_WRITE_ERROR) { + error = std::move(body_size_error()); + } else { + error = ::curl_easy_strerror(res); + }; + + if (errorfn) { + errorfn(std::move(buffer), std::move(error), http_status); + } + } else { + if (completefn) { + completefn(std::move(buffer), http_status); + } + } +} + +Http::Http(const std::string &url) : p(new priv(url)) {} + + +// Public + +Http::Http(Http &&other) : p(std::move(other.p)) {} + +Http::~Http() +{ + if (p && p->io_thread.joinable()) { + p->io_thread.detach(); + } +} + + +Http& Http::size_limit(size_t sizeLimit) +{ + if (p) { p->limit = sizeLimit; } + return *this; +} + +Http& Http::header(std::string name, const std::string &value) +{ + if (!p) { return * this; } + + if (name.size() > 0) { + name.append(": ").append(value); + } else { + name.push_back(':'); + } + p->headerlist = curl_slist_append(p->headerlist, name.c_str()); + return *this; +} + +Http& Http::remove_header(std::string name) +{ + if (p) { + name.push_back(':'); + p->headerlist = curl_slist_append(p->headerlist, name.c_str()); + } + + return *this; +} + +Http& Http::ca_file(const std::string &name) +{ + if (p) { + ::curl_easy_setopt(p->curl, CURLOPT_CAINFO, name.c_str()); + } + + return *this; +} + +Http& Http::form_add(const std::string &name, const std::string &contents) +{ + if (p) { + ::curl_formadd(&p->form, &p->form_end, + CURLFORM_COPYNAME, name.c_str(), + CURLFORM_COPYCONTENTS, contents.c_str(), + CURLFORM_END + ); + } + + return *this; +} + +Http& Http::form_add_file(const std::string &name, const std::string &filename) +{ + if (p) { + ::curl_formadd(&p->form, &p->form_end, + CURLFORM_COPYNAME, name.c_str(), + CURLFORM_FILE, filename.c_str(), + CURLFORM_CONTENTTYPE, "application/octet-stream", + CURLFORM_END + ); + } + + return *this; +} + +Http& Http::on_complete(CompleteFn fn) +{ + if (p) { p->completefn = std::move(fn); } + return *this; +} + +Http& Http::on_error(ErrorFn fn) +{ + if (p) { p->errorfn = std::move(fn); } + return *this; +} + +Http::Ptr Http::perform() +{ + auto self = std::make_shared(std::move(*this)); + + if (self->p) { + auto io_thread = std::thread([self](){ + self->p->http_perform(); + }); + self->p->io_thread = std::move(io_thread); + } + + return self; +} + +void Http::perform_sync() +{ + if (p) { p->http_perform(); } +} + +Http Http::get(std::string url) +{ + return std::move(Http{std::move(url)}); +} + +Http Http::post(std::string url) +{ + Http http{std::move(url)}; + curl_easy_setopt(http.p->curl, CURLOPT_POST, 1L); + return http; +} + + +} diff --git a/xs/src/slic3r/Utils/Http.hpp b/xs/src/slic3r/Utils/Http.hpp new file mode 100644 index 0000000000..c591e17c5b --- /dev/null +++ b/xs/src/slic3r/Utils/Http.hpp @@ -0,0 +1,53 @@ +#ifndef slic3r_Http_hpp_ +#define slic3r_Http_hpp_ + +#include +#include +#include + + +namespace Slic3r { + + +/// Represetns a Http request +class Http : public std::enable_shared_from_this { +private: + struct priv; +public: + typedef std::shared_ptr Ptr; + typedef std::function CompleteFn; + typedef std::function ErrorFn; + + Http(Http &&other); + + static Http get(std::string url); + static Http post(std::string url); + ~Http(); + + Http(const Http &) = delete; + Http& operator=(const Http &) = delete; + Http& operator=(Http &&) = delete; + + Http& size_limit(size_t sizeLimit); + Http& header(std::string name, const std::string &value); + Http& remove_header(std::string name); + Http& ca_file(const std::string &filename); + Http& form_add(const std::string &name, const std::string &contents); + Http& form_add_file(const std::string &name, const std::string &filename); + + Http& on_complete(CompleteFn fn); + Http& on_error(ErrorFn fn); + + Ptr perform(); + void perform_sync(); + +private: + Http(const std::string &url); + + std::unique_ptr p; +}; + + +} + +#endif From 751e86cd4de3e768e2a1f095ca396ca1b5a3c607 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Fri, 23 Feb 2018 16:48:11 +0100 Subject: [PATCH 11/18] libcurl linking and cmake usage improvements --- CMakeLists.txt | 15 +++++++++++++++ cmake/msvc/slic3r.wperl64d.props | 9 +++++++++ cmake/msvc/xs.wperl64d.props | 11 +++++++++++ xs/CMakeLists.txt | 11 +++++++++++ xs/src/xsinit.h | 9 +++++++++ 5 files changed, 55 insertions(+) create mode 100644 cmake/msvc/slic3r.wperl64d.props create mode 100644 cmake/msvc/xs.wperl64d.props diff --git a/CMakeLists.txt b/CMakeLists.txt index 43d7dee70d..b5f7cdec2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,21 @@ message("PATH: $ENV{PATH}") message("PERL5LIB: $ENV{PERL5LIB}") find_package(Perl REQUIRED) +# CMAKE_PREFIX_PATH is used to point CMake to the remaining dependencies (Boost, TBB, ...) +# We pick it from environment if it is not defined in another way +if(NOT DEFINED CMAKE_PREFIX_PATH) + if(DEFINED ENV{CMAKE_PREFIX_PATH}) + set(CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") + endif() +endif() + +if (MSVC) + # By default the startup project in MSVC is the 'ALL_BUILD' cmake-created project, + # but we want 'slic3r' as the startup one because debugging run command is associated with it. + # (Unfortunatelly it cannot be associated with ALL_BUILD using CMake.) + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT slic3r) +endif () + add_subdirectory(xs) enable_testing () diff --git a/cmake/msvc/slic3r.wperl64d.props b/cmake/msvc/slic3r.wperl64d.props new file mode 100644 index 0000000000..68dac2085b --- /dev/null +++ b/cmake/msvc/slic3r.wperl64d.props @@ -0,0 +1,9 @@ + + + + C:\wperl64d\bin\perl.exe + slic3r.pl + WindowsLocalDebugger + ..\.. + + diff --git a/cmake/msvc/xs.wperl64d.props b/cmake/msvc/xs.wperl64d.props new file mode 100644 index 0000000000..101923581e --- /dev/null +++ b/cmake/msvc/xs.wperl64d.props @@ -0,0 +1,11 @@ + + + + + + + $(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);c:\wperl64d\bin\; + + + + diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index d2f252030d..e4e0e1c6cf 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -603,6 +603,17 @@ elseif (NOT MSVC) target_link_libraries(slic3r -lstdc++) endif () +if (MSVC) + # Here we associate some additional properties with the MSVC projects to enable compilation and debugging out of the box. + # It seems a props file needs to be copied to the same dir as the proj file, otherwise MSVC doesn't load it up. + # For copying, the configure_file() function seems to work much better than the file() function. + configure_file("${PROJECT_SOURCE_DIR}/cmake/msvc/xs.wperl64d.props" ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + set_target_properties(XS PROPERTIES VS_USER_PROPS "xs.wperl64d.props") + configure_file("${PROJECT_SOURCE_DIR}/cmake/msvc/slic3r.wperl64d.props" ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + set_target_properties(slic3r PROPERTIES VS_USER_PROPS "slic3r.wperl64d.props") +endif () + + # Installation install(TARGETS XS DESTINATION lib/slic3r-prusa3d/auto/Slic3r/XS) install(FILES lib/Slic3r/XS.pm DESTINATION lib/slic3r-prusa3d/Slic3r) diff --git a/xs/src/xsinit.h b/xs/src/xsinit.h index 49981b74b3..96c4b74d74 100644 --- a/xs/src/xsinit.h +++ b/xs/src/xsinit.h @@ -59,6 +59,15 @@ extern "C" { #undef seek #undef send #undef write + #undef open + #undef close + #undef seekdir + #undef setbuf + #undef fread + #undef fseek + #undef fputc + #undef fwrite + #undef fclose #endif /* _MSC_VER */ } #endif From f67d70941eba392badbfc08cf38c69acfd8ef065 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 1 Mar 2018 16:14:36 +0100 Subject: [PATCH 12/18] Doc: Add dependency build scripts and building how-tos --- doc/How to build - UNIX.md | 2 + doc/How to build - Windows.md | 86 +++++++++++++ doc/deps-build/unix-static/Makefile | 132 +++++++++++++++++++ doc/deps-build/windows/slic3r-makedeps.ps1 | 141 +++++++++++++++++++++ 4 files changed, 361 insertions(+) create mode 100644 doc/How to build - UNIX.md create mode 100644 doc/How to build - Windows.md create mode 100644 doc/deps-build/unix-static/Makefile create mode 100644 doc/deps-build/windows/slic3r-makedeps.ps1 diff --git a/doc/How to build - UNIX.md b/doc/How to build - UNIX.md new file mode 100644 index 0000000000..77ce54419d --- /dev/null +++ b/doc/How to build - UNIX.md @@ -0,0 +1,2 @@ +# Building Slic3r PE on Linux/UNIX + diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md new file mode 100644 index 0000000000..8209954bd3 --- /dev/null +++ b/doc/How to build - Windows.md @@ -0,0 +1,86 @@ +# Building Slic3r PE on Microsoft Windows + +The currently supported way of building Slic3r PE on Windows is with MS Visual Studio 2013 +using our Perl binary distribution (compiled from official Perl sources). +You can use the free [Visual Studio 2013 Community Edition](https://www.visualstudio.com/vs/older-downloads/). + +Other setups (such as mingw + Strawberry Perl) _may_ work, but we cannot guarantee this will work +and cannot provide guidance. + + +### Geting the dependencies + +First, download and upnack our Perl + wxWidgets binary distribution: + + - 32 bit, release mode: [wperl32-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl32-5.24.0-2018-03-02.7z) + - 64 bit, release mode: [wperl64-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl64-5.24.0-2018-03-02.7z) + - 64 bit, release mode + debug symbols: [wperl64d-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl64d-5.24.0-2018-03-02.7z) + +It is recommended to unpack this package into `C:\`. + +Apart from wxWidgets and Perl, you will also need additional dependencies: + + - Boost + - Intel TBB + - libcurl + +We have prepared a binary package of the listed libraries: + + - 32 bit: [slic3r-destdir-32.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=slic3r-destdir-32.7z) + - 64 bit: [slic3r-destdir-64.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=slic3r-destdir-64.7z) + +It is recommended you unpack this package into `C:\local\` as the environment +setup script expects it there. + +Alternatively you can also compile the additional dependencies yourself. +There is a [powershell script](./deps-build/windows/slic3r-makedeps.ps1) which automates this process. + +### Building Slic3r PE + +Once the dependencies are set up in their respective locations, +go to the `wperl*` directory extracted earlier and launch the `cmdline.lnk` file +which opens a command line prompt with appropriate environment variables set up. + +In this command line, `cd` into the directory with Slic3r sources +and use these commands to build the Slic3r from the command line: + + perl Build.PL + perl Build.PL --gui + mkdir build + cd build + cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release + nmake + ctest --verbose # TODO: ??? + cd .. + perl slic3r.pl + +The above commands use `nmake` Makefiles. +You may also build Slic3r PE with other build tools: + + +### Building with Visual Studio + +To build, lanuch and/or debug Slic3r PE with Visual Studio (64 bits), replace the `cmake` command with: + + cmake .. -G "Visual Studio 12 Win64" -DCMAKE_CONFIGURATION_TYPES=Release;RelWithDebInfo || exit /b + +For the 32-bit variant, use: + + cmake .. -G "Visual Studio 12" -DCMAKE_CONFIGURATION_TYPES=Release;RelWithDebInfo || exit /b + +After `cmake` has finished, go to the `Slic3r\build` directory and open the `Slic3r.sln` solution file. +This should open Visual Studio and load all the Slic3r solution containing all the projects. +Make sure you use Visual Studio 2013 to open the solution. + +You can then use the usual Visual Studio controls to build Slic3r. +If you want to run or debug Slic3r from within Visual Studio, make sure the `slic3r` project is activated. +There are multiple projects in the Slic3r solution, but only the `slic3r` project is configured with the right +commands to run Slic3r. + + +### Building with ninja + +To use [Ninja](TODO), replace the `cmake` and `nmake` commands with: + + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release + ninja diff --git a/doc/deps-build/unix-static/Makefile b/doc/deps-build/unix-static/Makefile new file mode 100644 index 0000000000..e7588b9949 --- /dev/null +++ b/doc/deps-build/unix-static/Makefile @@ -0,0 +1,132 @@ + +# +# This makefile downloads, configures and builds Slic3r PE dependencies for Unix. +# (That is, all dependencies except perl + wxWidgets.) +# The libraries are installed in DESTDIR, which you can customize like so: +# +# DESTDIR=foo/bar make +# +# The default DESTDIR is ~/slic3r-destdir +# If the DESTDIR doesn't exits, the makefile tries to create it +# +# To pass the DESTDIR path along to cmake, set the use CMAKE_PREFIX_PATH variable +# and set it to $DESTDIR/usr/local +# +# You can also customize the NPROC variable in the same way to configure the number +# of cores the build process uses. By default this is set to what the `nproc` command says. +# + + +DESTDIR ?= $(HOME)/slic3r-destdir +NPROC ?= $(shell nproc) + + +BOOST = boost_1_66_0 +TBB_SHA = a0dc9bf76d0120f917b641ed095360448cabc85b +TBB = tbb-$(TBB_SHA) +OPENSSL = openssl-OpenSSL_1_1_0g +CURL = curl-7.58.0 + +.PHONY: all destdir boost libcurl libopenssl libtbb + +all: destdir boost libtbb libcurl + @echo + @echo "All done!" + @echo + +destdir: + mkdir -p $(DESTDIR) + + + +boost: $(BOOST).tar.gz + tar -zxvf $(BOOST).tar.gz + cd $(BOOST) && ./bootstrap.sh --with-libraries=system,filesystem,thread,log,locale,regex --prefix=$(DESTDIR)/usr/local + cd $(BOOST) && ./b2 \ + -j $(NPROC) \ + link=static \ + variant=release \ + threading=multi \ + boost.locale.icu=off \ + cxxflags=-fPIC cflags=-fPIC \ + install + +$(BOOST).tar.gz: + curl -L -o $@ https://dl.bintray.com/boostorg/release/1.66.0/source/$@ + + + +libtbb: $(TBB).tar.gz + tar -zxvf $(TBB).tar.gz + mkdir -p $(TBB)/mybuild + cd $(TBB)/mybuild && cmake .. -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON + $(MAKE) -C $(TBB)/mybuild -j$(NPROC) + $(MAKE) -C $(TBB)/mybuild install DESTDIR=$(DESTDIR) + +$(TBB).tar.gz: + curl -L -o $@ https://github.com/wjakob/tbb/archive/$(TBB_SHA).tar.gz + + + +libopenssl: $(OPENSSL).tar.gz + tar -zxvf $(OPENSSL).tar.gz + cd $(OPENSSL) && ./config --openssldir=/etc/ssl shared no-ssl3-method no-dynamic-engine '-Wa,--noexecstack' + make -C $(OPENSSL) depend + make -C $(OPENSSL) -j$(NPROC) + make -C $(OPENSSL) install DESTDIR=$(DESTDIR) + +$(OPENSSL).tar.gz: + curl -L -o $@ 'https://github.com/openssl/openssl/archive/OpenSSL_1_1_0g.tar.gz' + + + +libcurl: libopenssl $(CURL).tar.gz + tar -zxvf $(CURL).tar.gz +# XXX: disable shared? +# Setting PKG_CONFIG_PATH should make libcurl find our previously built openssl + cd $(CURL) && PKG_CONFIG_PATH=$(DESTDIR)/usr/local/lib/pkgconfig ./configure \ + --enable-static \ + --enable-shared \ + --with-pic \ + --enable-ipv6 \ + --enable-versioned-symbols \ + --enable-threaded-resolver \ + --with-random=/dev/urandom \ + --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt \ + --disable-ldap \ + --disable-ldaps \ + --disable-manual \ + --disable-rtsp \ + --disable-dict \ + --disable-telnet \ + --disable-pop3 \ + --disable-imap \ + --disable-smb \ + --disable-smtp \ + --disable-gopher \ + --disable-crypto-auth \ + --without-gssapi \ + --without-libpsl \ + --without-libidn2 \ + --without-gnutls \ + --without-polarssl \ + --without-mbedtls \ + --without-cyassl \ + --without-nss \ + --without-axtls \ + --without-brotli \ + --without-libmetalink \ + --without-libssh \ + --without-libssh2 \ + --without-librtmp \ + --without-nghttp2 \ + --without-zsh-functions-dir + $(MAKE) -C $(CURL) -j$(NPROC) + $(MAKE) -C $(CURL) install DESTDIR=$(DESTDIR) + +$(CURL).tar.gz: + curl -L -o $@ https://curl.haxx.se/download/$@ + + +clean: + rm -rf $(BOOST) $(BOOST).tar.gz $(TBB) $(TBB).tar.gz $(OPENSSL) $(OPENSSL).tar.gz $(CURL) $(CURL).tar.gz diff --git a/doc/deps-build/windows/slic3r-makedeps.ps1 b/doc/deps-build/windows/slic3r-makedeps.ps1 new file mode 100644 index 0000000000..8b39cae301 --- /dev/null +++ b/doc/deps-build/windows/slic3r-makedeps.ps1 @@ -0,0 +1,141 @@ +#!powershell +# +# This script downloads, configures and builds Slic3r PE dependencies for Unix. +# (That is, all dependencies except perl + wxWidgets.) +# +# To use this script, launch the Visual Studio command line, +# `cd` into the directory containing this script and use this command: +# +# powershell .\slic3r-makedeps.ps1 +# +# The dependencies will be downloaded and unpacked into the current dir. +# This script WILL NOT try to guess the build architecture (64 vs 32 bits), +# it will by default build the 64-bit variant. To build the 32-bit variant, use: +# +# powershell .\slic3r-makedeps.ps1 -b32 +# +# Built libraries are installed into $destdir, +# which by default is C:\local\slic3r-destdir-$bits +# You can customize the $destdir using: +# +# powershell .\slic3r-makedeps.ps1 -destdir C:\foo\bar +# +# To pass the $destdir path along to cmake, set the use CMAKE_PREFIX_PATH variable +# and set it to $destdir\usr\local +# +# Script requirements: PowerShell 3.0, .NET 4.5 +# + + +param( + [switch]$b32 = $false, + [string]$destdir = "" +) + +if ($destdir -eq "") { + $destdir = "C:\local\slic3r-destdir-" + ('32', '64')[!$b32] +} + +$BOOST = 'boost_1_63_0' +$CURL = 'curl-7.28.0' +$TBB_SHA = 'a0dc9bf76d0120f917b641ed095360448cabc85b' +$TBB = "tbb-$TBB_SHA" + + +try +{ + + +# Set up various settings and utilities: +[Environment]::CurrentDirectory = Get-Location +$NPROC = (Get-WmiObject -class Win32_processor).NumberOfLogicalProcessors +Add-Type -A System.IO.Compression.FileSystem +# This fxies SSL/TLS errors, credit goes to Ansible; see their `win_get_url.ps1` file +$security_protcols = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::SystemDefault +if ([Net.SecurityProtocolType].GetMember('Tls11').Count -gt 0) { + $security_protcols = $security_protcols -bor [Net.SecurityProtocolType]::Tls11 +} +if ([Net.SecurityProtocolType].GetMember('Tls12').Count -gt 0) { + $security_protcols = $security_protcols -bor [Net.SecurityProtocolType]::Tls12 +} +[Net.ServicePointManager]::SecurityProtocol = $security_protcols +$webclient = New-Object System.Net.WebClient + + +# Ensure DESTDIR exists: +mkdir $destdir -ea 0 +mkdir "$destdir\usr\local" -ea 0 + + +# Download sources: +echo 'Downloading sources ...' +if (!(Test-Path "$BOOST.zip")) { $webclient.DownloadFile("https://dl.bintray.com/boostorg/release/1.63.0/source/$BOOST.zip", "$BOOST.zip") } +if (!(Test-Path "$TBB.zip")) { $webclient.DownloadFile("https://github.com/wjakob/tbb/archive/$TBB_SHA.zip", "$TBB.zip") } +if (!(Test-Path "$CURL.zip")) { $webclient.DownloadFile("https://curl.haxx.se/download/$CURL.zip", ".\$CURL.zip") } + + +# Unpack sources: +echo 'Unpacking ...' +if (!(Test-Path $BOOST)) { [IO.Compression.ZipFile]::ExtractToDirectory("$BOOST.zip", '.') } +if (!(Test-Path $TBB)) { [IO.Compression.ZipFile]::ExtractToDirectory("$TBB.zip", '.') } +if (!(Test-Path $CURL)) { [IO.Compression.ZipFile]::ExtractToDirectory("$CURL.zip", '.') } + + +# Build libraries: +echo 'Building ...' + +# Build boost +pushd "$BOOST" +.\bootstrap +$adr_mode = ('32', '64')[!$b32] +.\b2 ` + -j "$NPROC" ` + --with-system ` + --with-filesystem ` + --with-thread ` + --with-log ` + --with-locale ` + --with-regex ` + "--prefix=$destdir/usr/local" ` + "address-model=$adr_mode" ` + toolset=msvc-12.0 ` + link=static ` + variant=release ` + threading=multi ` + boost.locale.icu=off ` + install +popd + +# Build TBB +pushd "$TBB" +mkdir 'mybuild' -ea 0 +cd 'mybuild' +$generator = ('Visual Studio 12', 'Visual Studio 12 Win64')[!$b32] +cmake .. ` + -G "$generator" ` + -DCMAKE_CONFIGURATION_TYPES=Release ` + -DTBB_BUILD_SHARED=OFF ` + -DTBB_BUILD_TESTS=OFF "-DCMAKE_INSTALL_PREFIX:PATH=$destdir\usr\local" +msbuild /P:Configuration=Release INSTALL.vcxproj +popd + +# Build libcurl: +pushd "$CURL\winbuild" +$machine = ("x86", "x64")[!$b32] +nmake /f Makefile.vc mode=static VC=12 GEN_PDB=yes DEBUG=no "MACHINE=$machine" +Copy-Item -R -Force ..\builds\libcurl-*-winssl\include\* "$destdir\usr\local\include\" +Copy-Item -R -Force ..\builds\libcurl-*-winssl\lib\* "$destdir\usr\local\lib\" +popd + + +echo "" +echo "All done!" +echo "" + + +} +catch [Exception] +{ + # This prints errors in a verbose manner + echo $_.Exception|format-list -force +} From b897209e0d10d1c96767cc0f2709a1eaa7a7046c Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 2 Mar 2018 21:16:00 +0100 Subject: [PATCH 13/18] Removed -DCURL_STATIC on OSX, added dynamic linking of OpenSSL on Linux, even if libcurl is linked statically. --- xs/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index e4e0e1c6cf..a294dc11e1 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -528,6 +528,15 @@ find_package(CURL REQUIRED) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries(XS ${CURL_LIBRARIES}) +if (SLIC3R_STATIC AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + # As of now, our build system produces a statically linked libcurl, + # which links the OpenSSL library dynamically. + find_package(OpenSSL REQUIRED) + message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") + message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") + include_directories(${OPENSSL_INCLUDE_DIR}) + target_link_libraries(XS ${OPENSSL_LIBRARIES}) +endif() ## OPTIONAL packages From 79ee7c9a36b4901804e87ecb17dd6821a23ba258 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 5 Mar 2018 18:32:09 +0100 Subject: [PATCH 14/18] Fix #608 Credit: Dylan "smellyfis" Thies --- xs/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index a294dc11e1..06456d6077 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -624,5 +624,5 @@ endif () # Installation -install(TARGETS XS DESTINATION lib/slic3r-prusa3d/auto/Slic3r/XS) -install(FILES lib/Slic3r/XS.pm DESTINATION lib/slic3r-prusa3d/Slic3r) +install(TARGETS XS DESTINATION ${PERL_VENDORARCH}/auto/Slic3r/XS) +install(FILES lib/Slic3r/XS.pm DESTINATION ${PERL_VENDORLIB}/Slic3r) From 7cfc5204c85c68e07ca351ac810a7f14a8e65eaf Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Wed, 7 Feb 2018 11:37:15 +0100 Subject: [PATCH 15/18] WIP: OctoPrint --- lib/Slic3r/GUI/MainFrame.pm | 12 +++- lib/Slic3r/GUI/Plater.pm | 48 ++------------ xs/CMakeLists.txt | 3 + xs/src/libslic3r/PrintConfig.cpp | 11 +++- xs/src/libslic3r/PrintConfig.hpp | 2 + xs/src/perlglue.cpp | 1 + xs/src/slic3r/GUI/GUI.cpp | 16 ++++- xs/src/slic3r/GUI/GUI.hpp | 3 + xs/src/slic3r/GUI/Preset.cpp | 2 +- xs/src/slic3r/Utils/OctoPrint.cpp | 105 ++++++++++++++++++++++++++++++ xs/src/slic3r/Utils/OctoPrint.hpp | 35 ++++++++++ xs/xsp/Utils_OctoPrint.xsp | 14 ++++ xs/xsp/my.map | 4 ++ 13 files changed, 210 insertions(+), 46 deletions(-) create mode 100644 xs/src/slic3r/Utils/OctoPrint.cpp create mode 100644 xs/src/slic3r/Utils/OctoPrint.hpp create mode 100644 xs/xsp/Utils_OctoPrint.xsp diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 572bdac329..034cc2dd51 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -409,7 +409,15 @@ sub _init_menubar { wxTheApp->about; }); } - + + my $hokusMenu = Wx::Menu->new; # XXX: tmp + { + $self->_append_menu_item($hokusMenu, "Pokus", "Pokus", sub { + # Slic3r::Http::download(); + Slic3r::OctoPrint::send_gcode("10.0.0.46", "70E4CFD0E0D7423CB6B1CF055DBAEFA5", "/home/vojta/prog/tisk/jesterka/jesterka.gcode"); + }); + } + # menubar # assign menubar to frame after appending items, otherwise special items # will not be handled correctly @@ -424,6 +432,8 @@ sub _init_menubar { # (Select application language from the list of installed languages) Slic3r::GUI::add_debug_menu($menubar, $self->{lang_ch_event}); $menubar->Append($helpMenu, L("&Help")); + $menubar->Append($hokusMenu, "Hoku&s"); + # Add an optional debug menu. In production code, the add_debug_menu() call should do nothing. $self->SetMenuBar($menubar); } } diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 5cedfbb08f..d48e31462e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -52,7 +52,7 @@ sub new { my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $self->{config} = Slic3r::Config::new_from_defaults_keys([qw( bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width variable_layer_height - serial_port serial_speed octoprint_host octoprint_apikey + serial_port serial_speed octoprint_host octoprint_apikey octoprint_cafile nozzle_diameter single_extruder_multi_material wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe extruder_colour filament_colour )]); @@ -1458,8 +1458,13 @@ sub on_export_completed { wxTheApp->notify($message); $self->do_print if $do_print; + # Send $self->{send_gcode_file} to OctoPrint. - $self->send_gcode if $send_gcode; + if ($send_gcode) { + my $op = Slic3r::OctoPrint->new($self->{config}); + $op->send_gcode($self->GetId(), $PROGRESS_BAR_EVENT, $ERROR_EVENT, $self->{send_gcode_file}); + } + $self->{print_file} = undef; $self->{send_gcode_file} = undef; $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); @@ -1488,45 +1493,6 @@ sub do_print { my $filament_names = wxTheApp->{preset_bundle}->filament_presets; $filament_stats = { map { $filament_names->[$_] => $filament_stats->{$_} } keys %$filament_stats }; $printer_panel->load_print_job($self->{print_file}, $filament_stats); - - $self->GetFrame->select_tab(1); -} - -# Send $self->{send_gcode_file} to OctoPrint. -#FIXME Currently this call blocks the UI. Make it asynchronous. -sub send_gcode { - my ($self) = @_; - - $self->statusbar->StartBusy; - - my $ua = LWP::UserAgent->new; - $ua->timeout(180); - - my $res = $ua->post( - "http://" . $self->{config}->octoprint_host . "/api/files/local", - Content_Type => 'form-data', - 'X-Api-Key' => $self->{config}->octoprint_apikey, - Content => [ - file => [ - # On Windows, the path has to be encoded in local code page for perl to be able to open it. - Slic3r::encode_path($self->{send_gcode_file}), - # Remove the UTF-8 flag from the perl string, so the LWP::UserAgent can insert - # the UTF-8 encoded string into the request as a byte stream. - Slic3r::path_to_filename_raw($self->{send_gcode_file}) - ], - print => $self->{send_gcode_file_print} ? 1 : 0, - ], - ); - - $self->statusbar->StopBusy; - - if ($res->is_success) { - $self->statusbar->SetStatusText(L("G-code file successfully uploaded to the OctoPrint server")); - } else { - my $message = L("Error while uploading to the OctoPrint server: ") . $res->status_line; - Slic3r::GUI::show_error($self, $message); - $self->statusbar->SetStatusText($message); - } } sub export_stl { diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 06456d6077..b73f8336db 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -201,6 +201,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/wxExtensions.hpp ${LIBDIR}/slic3r/Utils/Http.cpp ${LIBDIR}/slic3r/Utils/Http.hpp + ${LIBDIR}/slic3r/Utils/OctoPrint.cpp + ${LIBDIR}/slic3r/Utils/OctoPrint.hpp ) add_library(admesh STATIC @@ -340,6 +342,7 @@ set(XS_XSP_FILES ${XSP_DIR}/Surface.xsp ${XSP_DIR}/SurfaceCollection.xsp ${XSP_DIR}/TriangleMesh.xsp + ${XSP_DIR}/Utils_OctoPrint.xsp ${XSP_DIR}/XS.xsp ) foreach (file ${XS_XSP_FILES}) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 4077668f82..2b95ffa842 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -904,10 +904,17 @@ PrintConfigDef::PrintConfigDef() def->cli = "octoprint-apikey=s"; def->default_value = new ConfigOptionString(""); + def = this->add("octoprint_cafile", coString); + def->label = "HTTPS CA file"; + def->tooltip = "Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. " + "If left blank, the default OS CA certificate repository is used."; + def->cli = "octoprint-cafile=s"; + def->default_value = new ConfigOptionString(""); + def = this->add("octoprint_host", coString); - def->label = L("Host or IP"); + def->label = L("Hostname, IP or URL"); def->tooltip = L("Slic3r can upload G-code files to OctoPrint. This field should contain " - "the hostname or IP address of the OctoPrint instance."); + "the hostname, IP address or URL of the OctoPrint instance."); def->cli = "octoprint-host=s"; def->default_value = new ConfigOptionString(""); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 7d2fb01456..c589d917ab 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -684,6 +684,7 @@ class HostConfig : public StaticPrintConfig public: ConfigOptionString octoprint_host; ConfigOptionString octoprint_apikey; + ConfigOptionString octoprint_cafile; ConfigOptionString serial_port; ConfigOptionInt serial_speed; @@ -692,6 +693,7 @@ protected: { OPT_PTR(octoprint_host); OPT_PTR(octoprint_apikey); + OPT_PTR(octoprint_cafile); OPT_PTR(serial_port); OPT_PTR(serial_speed); } diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp index cb2ef73681..d7c9a590a0 100644 --- a/xs/src/perlglue.cpp +++ b/xs/src/perlglue.cpp @@ -64,6 +64,7 @@ REGISTER_CLASS(PresetCollection, "GUI::PresetCollection"); REGISTER_CLASS(PresetBundle, "GUI::PresetBundle"); REGISTER_CLASS(PresetHints, "GUI::PresetHints"); REGISTER_CLASS(TabIface, "GUI::Tab"); +REGISTER_CLASS(OctoPrint, "OctoPrint"); SV* ConfigBase__as_hash(ConfigBase* THIS) { diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index b0d3f7629a..f053d7b164 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -5,9 +5,9 @@ #include #include #include - #include #include +#include #if __APPLE__ #import @@ -570,4 +570,18 @@ wxString from_u8(std::string str) return wxString::FromUTF8(str.c_str()); } +wxWindow *get_widget_by_id(int id) +{ + if (g_wxMainFrame == nullptr) { + throw std::runtime_error("Main frame not set"); + } + + wxWindow *window = g_wxMainFrame->FindWindow(id); + if (window == nullptr) { + throw std::runtime_error((boost::format("Could not find widget by ID: %1%") % id).str()); + } + + return window; +} + } } diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 3e519b6914..e913a94507 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -6,6 +6,7 @@ #include "Config.hpp" class wxApp; +class wxWindow; class wxFrame; class wxWindow; class wxMenuBar; @@ -118,6 +119,8 @@ wxString L_str(std::string str); // Return wxString from std::string in UTF8 wxString from_u8(std::string str); +wxWindow *get_widget_by_id(int id); + } } diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index c28c989fb4..52717e1fc4 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -224,7 +224,7 @@ const std::vector& Preset::printer_options() if (s_opts.empty()) { s_opts = { "bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed", - "octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", + "octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "between_objects_gcode", "printer_notes" }; diff --git a/xs/src/slic3r/Utils/OctoPrint.cpp b/xs/src/slic3r/Utils/OctoPrint.cpp new file mode 100644 index 0000000000..019a4e2380 --- /dev/null +++ b/xs/src/slic3r/Utils/OctoPrint.cpp @@ -0,0 +1,105 @@ +#include "OctoPrint.hpp" + +#include +#include + +#include +#include + +#include "libslic3r/PrintConfig.hpp" +#include "slic3r/GUI/GUI.hpp" +#include "Http.hpp" + + +namespace Slic3r { + + +OctoPrint::OctoPrint(DynamicPrintConfig *config) : + host(config->opt_string("octoprint_host")), + apikey(config->opt_string("octoprint_apikey")), + cafile(config->opt_string("octoprint_cafile")) +{} + +std::string OctoPrint::test() const +{ + // Since the request is performed synchronously here, + // it is ok to refer to `res` from within the closure + std::string res; + + auto http = Http::get(std::move(make_url("api/version"))); + set_auth(http); + http.on_error([&](std::string, std::string error, unsigned status) { + res = format_error(error, status); + }) + .perform_sync(); + + return res; +} + +void OctoPrint::send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print) const +{ + auto http = Http::post(std::move(make_url("api/files/local"))); + set_auth(http); + http.form_add("print", print ? "true" : "false") + .form_add_file("file", filename) + .on_complete([=](std::string body, unsigned status) { + wxWindow *window = GUI::get_widget_by_id(windowId); + wxCommandEvent* evt = new wxCommandEvent(completeEvt); + evt->SetString("G-code file successfully uploaded to the OctoPrint server"); + evt->SetInt(100); + wxQueueEvent(window, evt); + }) + .on_error([=](std::string body, std::string error, unsigned status) { + wxWindow *window = GUI::get_widget_by_id(windowId); + + wxCommandEvent* evt_complete = new wxCommandEvent(completeEvt); + evt_complete->SetInt(100); + wxQueueEvent(window, evt_complete); + + wxCommandEvent* evt_error = new wxCommandEvent(errorEvt); + evt_error->SetString(wxString::Format("Error while uploading to the OctoPrint server: %s", format_error(error, status))); + wxQueueEvent(window, evt_error); + }) + .perform(); +} + +void OctoPrint::set_auth(Http &http) const +{ + http.header("X-Api-Key", apikey); + + if (! cafile.empty()) { + http.ca_file(cafile); + } +} + +std::string OctoPrint::make_url(const std::string &path) const +{ + if (host.find("http://") == 0 || host.find("https://") == 0) { + if (host.back() == '/') { + return std::move((boost::format("%1%%2%") % host % path).str()); + } else { + return std::move((boost::format("%1%/%2%") % host % path).str()); + } + } else { + return std::move((boost::format("http://%1%/%2%") % host % path).str()); + } +} + +std::string OctoPrint::format_error(std::string error, unsigned status) +{ + if (status != 0) { + std::string res{"HTTP "}; + res.append(std::to_string(status)); + + if (status == 401) { + res.append(": Invalid API key"); + } + + return std::move(res); + } else { + return std::move(error); + } +} + + +} diff --git a/xs/src/slic3r/Utils/OctoPrint.hpp b/xs/src/slic3r/Utils/OctoPrint.hpp new file mode 100644 index 0000000000..c5ed70ab56 --- /dev/null +++ b/xs/src/slic3r/Utils/OctoPrint.hpp @@ -0,0 +1,35 @@ +#ifndef slic3r_OctoPrint_hpp_ +#define slic3r_OctoPrint_hpp_ + +#include + +#include "Http.hpp" + +namespace Slic3r { + + +class DynamicPrintConfig; +class Http; + +class OctoPrint +{ +public: + OctoPrint(DynamicPrintConfig *config); + + std::string test() const; + // XXX: style + void send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print = false) const; +private: + std::string host; + std::string apikey; + std::string cafile; + + void set_auth(Http &http) const; + std::string make_url(const std::string &path) const; + static std::string format_error(std::string error, unsigned status); +}; + + +} + +#endif diff --git a/xs/xsp/Utils_OctoPrint.xsp b/xs/xsp/Utils_OctoPrint.xsp new file mode 100644 index 0000000000..062af4e0c1 --- /dev/null +++ b/xs/xsp/Utils_OctoPrint.xsp @@ -0,0 +1,14 @@ +%module{Slic3r::XS}; + +%{ +#include +#include "slic3r/Utils/OctoPrint.hpp" +%} + +%name{Slic3r::OctoPrint} class OctoPrint { + OctoPrint(DynamicPrintConfig *config); + ~OctoPrint(); + + std::string test() const; + void send_gcode(int windowId, int completeEvt, int errorEvt, std::string filename, bool print = false) const; +}; diff --git a/xs/xsp/my.map b/xs/xsp/my.map index e54601632e..87a8d8d866 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -236,6 +236,10 @@ Ref O_OBJECT_SLIC3R_T TabIface* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T +OctoPrint* O_OBJECT_SLIC3R +Ref O_OBJECT_SLIC3R_T +Clone O_OBJECT_SLIC3R_T + Axis T_UV ExtrusionLoopRole T_UV ExtrusionRole T_UV From fc05eb898de57bfbd845b5a32261b8702cbf0083 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 20 Feb 2018 15:37:26 +0100 Subject: [PATCH 16/18] WIP: Bonjour --- lib/Slic3r/GUI/MainFrame.pm | 3 +- xs/CMakeLists.txt | 2 + xs/src/slic3r/Utils/Bonjour.cpp | 602 ++++++++++++++++++++++++++++++ xs/src/slic3r/Utils/Bonjour.hpp | 39 ++ xs/src/slic3r/Utils/OctoPrint.cpp | 114 +++--- xs/src/slic3r/Utils/OctoPrint.hpp | 20 +- 6 files changed, 711 insertions(+), 69 deletions(-) create mode 100644 xs/src/slic3r/Utils/Bonjour.cpp create mode 100644 xs/src/slic3r/Utils/Bonjour.hpp diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 034cc2dd51..ee5ec7cb5d 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -413,8 +413,7 @@ sub _init_menubar { my $hokusMenu = Wx::Menu->new; # XXX: tmp { $self->_append_menu_item($hokusMenu, "Pokus", "Pokus", sub { - # Slic3r::Http::download(); - Slic3r::OctoPrint::send_gcode("10.0.0.46", "70E4CFD0E0D7423CB6B1CF055DBAEFA5", "/home/vojta/prog/tisk/jesterka/jesterka.gcode"); + Slic3r::Http::pokus(); }); } diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index b73f8336db..d8ef51caa7 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -203,6 +203,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/Utils/Http.hpp ${LIBDIR}/slic3r/Utils/OctoPrint.cpp ${LIBDIR}/slic3r/Utils/OctoPrint.hpp + ${LIBDIR}/slic3r/Utils/Bonjour.cpp + ${LIBDIR}/slic3r/Utils/Bonjour.hpp ) add_library(admesh STATIC diff --git a/xs/src/slic3r/Utils/Bonjour.cpp b/xs/src/slic3r/Utils/Bonjour.cpp new file mode 100644 index 0000000000..d7fb30e646 --- /dev/null +++ b/xs/src/slic3r/Utils/Bonjour.cpp @@ -0,0 +1,602 @@ +#include "Bonjour.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::optional; +using boost::system::error_code; +namespace endian = boost::endian; +namespace asio = boost::asio; +using boost::asio::ip::udp; + + +// TODO: Fuzzing test + +namespace Slic3r { + + +// Miniman implementation of a MDNS client +// This implementation is extremely simple, only the bits that are useful +// for very basic MDNS discovery are present. + +struct DnsName: public std::string +{ + enum + { + MAX_RECURSION = 10, // Keep this low + }; + + static optional decode(const std::vector &buffer, ptrdiff_t &offset, unsigned depth = 0) + { + // We trust that the offset passed is bounds-checked properly, + // including that there is at least one byte beyond that offset. + // Any further arithmetic has to be bounds-checked here though. + + // Check for recursion depth to prevent parsing names that are nested too deeply + // or end up cyclic: + if (depth >= MAX_RECURSION) { + return boost::none; + } + + DnsName res; + const ptrdiff_t bsize = buffer.size(); + + while (true) { + const char* ptr = buffer.data() + offset; + char len = *ptr; + if (len & 0xc0) { + // This is a recursive label + ptrdiff_t pointer = (len & 0x3f) << 8 | ptr[1]; + const auto nested = decode(buffer, pointer, depth + 1); + if (!nested) { + return boost::none; + } else { + if (res.size() > 0) { + res.push_back('.'); + } + res.append(*nested); + offset += 2; + return std::move(res); + } + } else if (len == 0) { + // This is a name terminator + offset++; + break; + } else { + // This is a regular label + len &= 0x3f; + if (len + offset + 1 >= bsize) { + return boost::none; + } + + res.reserve(len); + if (res.size() > 0) { + res.push_back('.'); + } + + ptr++; + for (const auto end = ptr + len; ptr < end; ptr++) { + char c = *ptr; + if (c >= 0x20 && c <= 0x7f) { + res.push_back(c); + } else { + return boost::none; + } + } + + offset += len + 1; + } + } + + if (res.size() > 0) { + return std::move(res); + } else { + return boost::none; + } + } +}; + +struct DnsHeader +{ + uint16_t id; + uint16_t flags; + uint16_t qdcount; + uint16_t ancount; + uint16_t nscount; + uint16_t arcount; + + enum + { + SIZE = 12, + }; + + static DnsHeader decode(const std::vector &buffer) { + DnsHeader res; + const uint16_t *data_16 = reinterpret_cast(buffer.data()); + res.id = endian::big_to_native(data_16[0]); + res.flags = endian::big_to_native(data_16[1]); + res.qdcount = endian::big_to_native(data_16[2]); + res.ancount = endian::big_to_native(data_16[3]); + res.nscount = endian::big_to_native(data_16[4]); + res.arcount = endian::big_to_native(data_16[5]); + return res; + } + + uint32_t rrcount() const { + return ancount + nscount + arcount; + } +}; + +struct DnsQuestion +{ + enum + { + MIN_SIZE = 5, + }; + + DnsName name; + uint16_t type; + uint16_t qclass; + + DnsQuestion() : + type(0), + qclass(0) + {} + + static optional decode(const std::vector &buffer, ptrdiff_t &offset) + { + auto qname = DnsName::decode(buffer, offset); + if (!qname) { + return boost::none; + } + + DnsQuestion res; + res.name = std::move(*qname); + const uint16_t *data_16 = reinterpret_cast(buffer.data() + offset); + res.type = endian::big_to_native(data_16[0]); + res.qclass = endian::big_to_native(data_16[1]); + + offset += 4; + return std::move(res); + } +}; + +struct DnsResource +{ + DnsName name; + uint16_t type; + uint16_t rclass; + uint32_t ttl; + std::vector data; + + DnsResource() : + type(0), + rclass(0), + ttl(0) + {} + + static optional decode(const std::vector &buffer, ptrdiff_t &offset, ptrdiff_t &dataoffset) + { + auto rname = DnsName::decode(buffer, offset); + if (!rname) { + return boost::none; + } + + const ptrdiff_t bsize = buffer.size(); + + if (offset + 10 >= bsize) { + return boost::none; + } + + DnsResource res; + res.name = std::move(*rname); + const uint16_t *data_16 = reinterpret_cast(buffer.data() + offset); + res.type = endian::big_to_native(data_16[0]); + res.rclass = endian::big_to_native(data_16[1]); + res.ttl = endian::big_to_native(*reinterpret_cast(data_16 + 2)); + uint16_t rdlength = endian::big_to_native(data_16[4]); + + offset += 10; + if (offset + rdlength > bsize) { + return boost::none; + } + + dataoffset = offset; + res.data = std::move(std::vector(buffer.begin() + offset, buffer.begin() + offset + rdlength)); + offset += rdlength; + + return std::move(res); + } +}; + +struct DnsRR_A +{ + enum { TAG = 0x1 }; + + asio::ip::address_v4 ip; + + static void decode(optional &result, const DnsResource &rr) + { + if (rr.data.size() == 4) { + DnsRR_A res; + const uint32_t ip = endian::big_to_native(*reinterpret_cast(rr.data.data())); + res.ip = asio::ip::address_v4(ip); + result = std::move(res); + } + } +}; + +struct DnsRR_AAAA +{ + enum { TAG = 0x1c }; + + asio::ip::address_v6 ip; + + static void decode(optional &result, const DnsResource &rr) + { + if (rr.data.size() == 16) { + DnsRR_AAAA res; + std::array ip; + std::copy_n(rr.data.begin(), 16, ip.begin()); + res.ip = asio::ip::address_v6(ip); + result = std::move(res); + } + } +}; + +struct DnsRR_SRV +{ + enum + { + TAG = 0x21, + MIN_SIZE = 8, + }; + + uint16_t priority; + uint16_t weight; + uint16_t port; + std::string name; + std::string service; + DnsName hostname; + + static void decode(std::vector &results, const std::vector &buffer, const DnsResource &rr, ptrdiff_t dataoffset) + { + if (rr.data.size() < MIN_SIZE) { + return; + } + + DnsRR_SRV res; + + { + const auto dot_pos = rr.name.find_first_of('.'); + if (dot_pos > 0 && dot_pos < rr.name.size() - 1) { + res.name = rr.name.substr(0, dot_pos); + res.service = rr.name.substr(dot_pos + 1); + } else { + return; + } + } + + const uint16_t *data_16 = reinterpret_cast(rr.data.data()); + res.priority = endian::big_to_native(data_16[0]); + res.weight = endian::big_to_native(data_16[1]); + res.port = endian::big_to_native(data_16[2]); + + ptrdiff_t offset = dataoffset + 6; + auto hostname = DnsName::decode(buffer, offset); + + if (hostname) { + res.hostname = std::move(*hostname); + results.emplace_back(std::move(res)); + } + } +}; + +struct DnsMessage +{ + enum + { + MAX_SIZE = 4096, + MAX_ANS = 30, + }; + + DnsHeader header; + optional question; + std::vector answers; + + optional rr_a; + optional rr_aaaa; + std::vector rr_srv; + + static optional decode(const std::vector &buffer, optional id_wanted = boost::none) + { + const auto size = buffer.size(); + if (size < DnsHeader::SIZE + DnsQuestion::MIN_SIZE || size > MAX_SIZE) { + return boost::none; + } + + DnsMessage res; + res.header = DnsHeader::decode(buffer); + + if (id_wanted && *id_wanted != res.header.id) { + return boost::none; + } + + if (res.header.qdcount > 1 || res.header.ancount > MAX_ANS) { + return boost::none; + } + + ptrdiff_t offset = DnsHeader::SIZE; + if (res.header.qdcount == 1) { + res.question = DnsQuestion::decode(buffer, offset); + } + + for (unsigned i = 0; i < res.header.rrcount(); i++) { + ptrdiff_t dataoffset = 0; + auto rr = DnsResource::decode(buffer, offset, dataoffset); + if (!rr) { + return boost::none; + } else { + res.parse_rr(buffer, *rr, dataoffset); + res.answers.push_back(std::move(*rr)); + } + } + + return std::move(res); + } +private: + void parse_rr(const std::vector &buffer, const DnsResource &rr, ptrdiff_t dataoffset) + { + switch (rr.type) { + case DnsRR_A::TAG: DnsRR_A::decode(this->rr_a, rr); break; + case DnsRR_AAAA::TAG: DnsRR_AAAA::decode(this->rr_aaaa, rr); break; + case DnsRR_SRV::TAG: DnsRR_SRV::decode(this->rr_srv, buffer, rr, dataoffset); break; + } + } +}; + + +struct BonjourRequest +{ + static const asio::ip::address_v4 MCAST_IP4; + static const uint16_t MCAST_PORT; + + static const char rq_template[]; + + uint16_t id; + std::vector data; + + static optional make(const std::string &service, const std::string &protocol); + +private: + BonjourRequest(uint16_t id, std::vector &&data) : + id(id), + data(std::move(data)) + {} +}; + +const asio::ip::address_v4 BonjourRequest::MCAST_IP4{0xe00000fb}; +const uint16_t BonjourRequest::MCAST_PORT = 5353; + +const char BonjourRequest::rq_template[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, + 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, + 0x00, 0x01, +}; + +optional BonjourRequest::make(const std::string &service, const std::string &protocol) +{ + if (service.size() > 15 || protocol.size() > 15) { + return boost::none; + } + + std::random_device dev; + std::uniform_int_distribution dist; + uint16_t id = dist(dev); + uint16_t id_big = endian::native_to_big(id); + const char *id_char = reinterpret_cast(&id_big); + + std::vector data; + data.reserve(service.size() + 18); + + // Add the transaction ID + data.push_back(id_char[0]); + data.push_back(id_char[1]); + + // Add metadata + static const char rq_meta[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + std::copy(rq_meta, rq_meta + sizeof(rq_meta), std::back_inserter(data)); + + // Add PTR query name + data.push_back(service.size() + 1); + data.push_back('_'); + data.insert(data.end(), service.begin(), service.end()); + data.push_back(protocol.size() + 1); + data.push_back('_'); + data.insert(data.end(), protocol.begin(), protocol.end()); + + // Add the rest of PTR record + static const char ptr_tail[] = { + 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, + }; + std::copy(ptr_tail, ptr_tail + sizeof(ptr_tail), std::back_inserter(data)); + + return BonjourRequest(id, std::move(data)); +} + + +// API - private part + +struct Bonjour::priv +{ + const std::string service; + const std::string protocol; + const std::string service_dn; + unsigned timeout; + uint16_t rq_id; + + std::vector buffer; + std::thread io_thread; + Bonjour::ReplyFn replyfn; + Bonjour::CompleteFn completefn; + + priv(std::string service, std::string protocol); + + void udp_receive(const error_code &error, size_t bytes); + void lookup_perform(); +}; + +Bonjour::priv::priv(std::string service, std::string protocol) : + service(std::move(service)), + protocol(std::move(protocol)), + service_dn((boost::format("_%1%._%2%.local") % this->service % this->protocol).str()), + timeout(10), + rq_id(0) +{ + buffer.resize(DnsMessage::MAX_SIZE); +} + +void Bonjour::priv::udp_receive(const error_code &error, size_t bytes) +{ + if (error || bytes == 0 || !replyfn) { + return; + } + + buffer.resize(bytes); + const auto dns_msg = DnsMessage::decode(buffer, rq_id); + if (dns_msg) { + std::string ip; + if (dns_msg->rr_a) { ip = dns_msg->rr_a->ip.to_string(); } + else if (dns_msg->rr_aaaa) { ip = dns_msg->rr_aaaa->ip.to_string(); } + + for (const auto &srv : dns_msg->rr_srv) { + if (srv.service == service_dn) { + replyfn(std::move(ip), std::move(srv.hostname), std::move(srv.name)); + } + } + } +} + +void Bonjour::priv::lookup_perform() +{ + const auto brq = BonjourRequest::make(service, protocol); + if (!brq) { + return; + } + + auto self = this; + rq_id = brq->id; + + try { + boost::asio::io_service io_service; + udp::socket socket(io_service); + socket.open(udp::v4()); + socket.set_option(udp::socket::reuse_address(true)); + udp::endpoint mcast(BonjourRequest::MCAST_IP4, BonjourRequest::MCAST_PORT); + socket.send_to(asio::buffer(brq->data), mcast); + + bool timeout = false; + asio::deadline_timer timer(io_service); + timer.expires_from_now(boost::posix_time::seconds(10)); + timer.async_wait([=, &timeout](const error_code &error) { + timeout = true; + if (self->completefn) { + self->completefn(); + } + }); + + const auto recv_handler = [=](const error_code &error, size_t bytes) { + self->udp_receive(error, bytes); + }; + socket.async_receive(asio::buffer(buffer, buffer.size()), recv_handler); + + while (io_service.run_one()) { + if (timeout) { + socket.cancel(); + } else { + buffer.resize(DnsMessage::MAX_SIZE); + socket.async_receive(asio::buffer(buffer, buffer.size()), recv_handler); + } + } + } catch (std::exception& e) { + } +} + + +// API - public part + +Bonjour::Bonjour(std::string service, std::string protocol) : + p(new priv(std::move(service), std::move(protocol))) +{} + +Bonjour::Bonjour(Bonjour &&other) : p(std::move(other.p)) {} + +Bonjour::~Bonjour() +{ + if (p && p->io_thread.joinable()) { + p->io_thread.detach(); + } +} + +Bonjour& Bonjour::set_timeout(unsigned timeout) +{ + if (p) { p->timeout = timeout; } + return *this; +} + +Bonjour& Bonjour::on_reply(ReplyFn fn) +{ + if (p) { p->replyfn = std::move(fn); } + return *this; +} + +Bonjour& Bonjour::on_complete(CompleteFn fn) +{ + if (p) { p->completefn = std::move(fn); } + return *this; +} + +Bonjour::Ptr Bonjour::lookup() +{ + auto self = std::make_shared(std::move(*this)); + + if (self->p) { + auto io_thread = std::thread([self](){ + self->p->lookup_perform(); + }); + self->p->io_thread = std::move(io_thread); + } + + return self; +} + + +void Bonjour::pokus() // XXX +{ + // auto bonjour = Bonjour("http") + // .set_timeout(15) + // .on_reply([](std::string ip, std::string host, std::string service_name) { + // std::cerr << "MDNS: " << ip << " = " << host << " : " << service_name << std::endl; + // }) + // .on_complete([](){ + // std::cerr << "MDNS lookup complete" << std::endl; + // }) + // .lookup(); +} + + +} diff --git a/xs/src/slic3r/Utils/Bonjour.hpp b/xs/src/slic3r/Utils/Bonjour.hpp new file mode 100644 index 0000000000..039db3370a --- /dev/null +++ b/xs/src/slic3r/Utils/Bonjour.hpp @@ -0,0 +1,39 @@ +#ifndef slic3r_Bonjour_hpp_ +#define slic3r_Bonjour_hpp_ + +#include +#include +#include + + +namespace Slic3r { + + +/// Bonjour lookup +class Bonjour : public std::enable_shared_from_this { +private: + struct priv; +public: + typedef std::shared_ptr Ptr; + typedef std::function ReplyFn; + typedef std::function CompleteFn; + + Bonjour(std::string service, std::string protocol = "tcp"); + Bonjour(Bonjour &&other); + ~Bonjour(); + + Bonjour& set_timeout(unsigned timeout); + Bonjour& on_reply(ReplyFn fn); + Bonjour& on_complete(CompleteFn fn); + + Ptr lookup(); + + static void pokus(); // XXX: remove +private: + std::unique_ptr p; +}; + + +} + +#endif diff --git a/xs/src/slic3r/Utils/OctoPrint.cpp b/xs/src/slic3r/Utils/OctoPrint.cpp index 019a4e2380..58530833ba 100644 --- a/xs/src/slic3r/Utils/OctoPrint.cpp +++ b/xs/src/slic3r/Utils/OctoPrint.cpp @@ -15,90 +15,90 @@ namespace Slic3r { OctoPrint::OctoPrint(DynamicPrintConfig *config) : - host(config->opt_string("octoprint_host")), - apikey(config->opt_string("octoprint_apikey")), - cafile(config->opt_string("octoprint_cafile")) + host(config->opt_string("octoprint_host")), + apikey(config->opt_string("octoprint_apikey")), + cafile(config->opt_string("octoprint_cafile")) {} std::string OctoPrint::test() const { - // Since the request is performed synchronously here, - // it is ok to refer to `res` from within the closure - std::string res; + // Since the request is performed synchronously here, + // it is ok to refer to `res` from within the closure + std::string res; - auto http = Http::get(std::move(make_url("api/version"))); - set_auth(http); - http.on_error([&](std::string, std::string error, unsigned status) { - res = format_error(error, status); - }) - .perform_sync(); + auto http = Http::get(std::move(make_url("api/version"))); + set_auth(http); + http.on_error([&](std::string, std::string error, unsigned status) { + res = format_error(error, status); + }) + .perform_sync(); - return res; + return res; } void OctoPrint::send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print) const { - auto http = Http::post(std::move(make_url("api/files/local"))); - set_auth(http); - http.form_add("print", print ? "true" : "false") - .form_add_file("file", filename) - .on_complete([=](std::string body, unsigned status) { - wxWindow *window = GUI::get_widget_by_id(windowId); - wxCommandEvent* evt = new wxCommandEvent(completeEvt); - evt->SetString("G-code file successfully uploaded to the OctoPrint server"); - evt->SetInt(100); - wxQueueEvent(window, evt); - }) - .on_error([=](std::string body, std::string error, unsigned status) { - wxWindow *window = GUI::get_widget_by_id(windowId); + auto http = Http::post(std::move(make_url("api/files/local"))); + set_auth(http); + http.form_add("print", print ? "true" : "false") + .form_add_file("file", filename) + .on_complete([=](std::string body, unsigned status) { + wxWindow *window = GUI::get_widget_by_id(windowId); + wxCommandEvent* evt = new wxCommandEvent(completeEvt); + evt->SetString("G-code file successfully uploaded to the OctoPrint server"); + evt->SetInt(100); + wxQueueEvent(window, evt); + }) + .on_error([=](std::string body, std::string error, unsigned status) { + wxWindow *window = GUI::get_widget_by_id(windowId); - wxCommandEvent* evt_complete = new wxCommandEvent(completeEvt); - evt_complete->SetInt(100); - wxQueueEvent(window, evt_complete); + wxCommandEvent* evt_complete = new wxCommandEvent(completeEvt); + evt_complete->SetInt(100); + wxQueueEvent(window, evt_complete); - wxCommandEvent* evt_error = new wxCommandEvent(errorEvt); - evt_error->SetString(wxString::Format("Error while uploading to the OctoPrint server: %s", format_error(error, status))); - wxQueueEvent(window, evt_error); - }) - .perform(); + wxCommandEvent* evt_error = new wxCommandEvent(errorEvt); + evt_error->SetString(wxString::Format("Error while uploading to the OctoPrint server: %s", format_error(error, status))); + wxQueueEvent(window, evt_error); + }) + .perform(); } void OctoPrint::set_auth(Http &http) const { - http.header("X-Api-Key", apikey); + http.header("X-Api-Key", apikey); - if (! cafile.empty()) { - http.ca_file(cafile); - } + if (! cafile.empty()) { + http.ca_file(cafile); + } } std::string OctoPrint::make_url(const std::string &path) const { - if (host.find("http://") == 0 || host.find("https://") == 0) { - if (host.back() == '/') { - return std::move((boost::format("%1%%2%") % host % path).str()); - } else { - return std::move((boost::format("%1%/%2%") % host % path).str()); - } - } else { - return std::move((boost::format("http://%1%/%2%") % host % path).str()); - } + if (host.find("http://") == 0 || host.find("https://") == 0) { + if (host.back() == '/') { + return std::move((boost::format("%1%%2%") % host % path).str()); + } else { + return std::move((boost::format("%1%/%2%") % host % path).str()); + } + } else { + return std::move((boost::format("http://%1%/%2%") % host % path).str()); + } } std::string OctoPrint::format_error(std::string error, unsigned status) { - if (status != 0) { - std::string res{"HTTP "}; - res.append(std::to_string(status)); + if (status != 0) { + std::string res{"HTTP "}; + res.append(std::to_string(status)); - if (status == 401) { - res.append(": Invalid API key"); - } + if (status == 401) { + res.append(": Invalid API key"); + } - return std::move(res); - } else { - return std::move(error); - } + return std::move(res); + } else { + return std::move(error); + } } diff --git a/xs/src/slic3r/Utils/OctoPrint.hpp b/xs/src/slic3r/Utils/OctoPrint.hpp index c5ed70ab56..1d70a087d0 100644 --- a/xs/src/slic3r/Utils/OctoPrint.hpp +++ b/xs/src/slic3r/Utils/OctoPrint.hpp @@ -14,19 +14,19 @@ class Http; class OctoPrint { public: - OctoPrint(DynamicPrintConfig *config); + OctoPrint(DynamicPrintConfig *config); - std::string test() const; - // XXX: style - void send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print = false) const; + std::string test() const; + // XXX: style + void send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print = false) const; private: - std::string host; - std::string apikey; - std::string cafile; + std::string host; + std::string apikey; + std::string cafile; - void set_auth(Http &http) const; - std::string make_url(const std::string &path) const; - static std::string format_error(std::string error, unsigned status); + void set_auth(Http &http) const; + std::string make_url(const std::string &path) const; + static std::string format_error(std::string error, unsigned status); }; From ca0f6131a18ea7fa089fb4eea979c9b3f87703a0 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Fri, 2 Mar 2018 15:05:17 +0100 Subject: [PATCH 17/18] WIP: Bonjour: TXT + improvements --- xs/src/slic3r/Utils/Bonjour.cpp | 240 +++++++++++++++++++++--------- xs/src/slic3r/Utils/Bonjour.hpp | 21 ++- xs/src/slic3r/Utils/OctoPrint.hpp | 2 +- 3 files changed, 191 insertions(+), 72 deletions(-) diff --git a/xs/src/slic3r/Utils/Bonjour.cpp b/xs/src/slic3r/Utils/Bonjour.cpp index d7fb30e646..6107e2c604 100644 --- a/xs/src/slic3r/Utils/Bonjour.cpp +++ b/xs/src/slic3r/Utils/Bonjour.cpp @@ -1,5 +1,6 @@ #include "Bonjour.hpp" +#include // XXX #include #include #include @@ -22,12 +23,14 @@ namespace asio = boost::asio; using boost::asio::ip::udp; -// TODO: Fuzzing test +// TODO: Fuzzing test (done without TXT) +// FIXME: check char retype to unsigned + namespace Slic3r { -// Miniman implementation of a MDNS client +// Minimal implementation of a MDNS/DNS-SD client // This implementation is extremely simple, only the bits that are useful // for very basic MDNS discovery are present. @@ -38,11 +41,12 @@ struct DnsName: public std::string MAX_RECURSION = 10, // Keep this low }; - static optional decode(const std::vector &buffer, ptrdiff_t &offset, unsigned depth = 0) + static optional decode(const std::vector &buffer, size_t &offset, unsigned depth = 0) { - // We trust that the offset passed is bounds-checked properly, - // including that there is at least one byte beyond that offset. - // Any further arithmetic has to be bounds-checked here though. + // Check offset sanity: + if (offset + 1 >= buffer.size()) { + return boost::none; + } // Check for recursion depth to prevent parsing names that are nested too deeply // or end up cyclic: @@ -51,14 +55,15 @@ struct DnsName: public std::string } DnsName res; - const ptrdiff_t bsize = buffer.size(); + const size_t bsize = buffer.size(); while (true) { const char* ptr = buffer.data() + offset; - char len = *ptr; + unsigned len = static_cast(*ptr); if (len & 0xc0) { // This is a recursive label - ptrdiff_t pointer = (len & 0x3f) << 8 | ptr[1]; + unsigned len_2 = static_cast(ptr[1]); + size_t pointer = (len & 0x3f) << 8 | len_2; const auto nested = decode(buffer, pointer, depth + 1); if (!nested) { return boost::none; @@ -155,7 +160,7 @@ struct DnsQuestion qclass(0) {} - static optional decode(const std::vector &buffer, ptrdiff_t &offset) + static optional decode(const std::vector &buffer, size_t &offset) { auto qname = DnsName::decode(buffer, offset); if (!qname) { @@ -187,15 +192,18 @@ struct DnsResource ttl(0) {} - static optional decode(const std::vector &buffer, ptrdiff_t &offset, ptrdiff_t &dataoffset) + static optional decode(const std::vector &buffer, size_t &offset, size_t &dataoffset) { + const size_t bsize = buffer.size(); + if (offset + 1 >= bsize) { + return boost::none; + } + auto rname = DnsName::decode(buffer, offset); if (!rname) { return boost::none; } - const ptrdiff_t bsize = buffer.size(); - if (offset + 10 >= bsize) { return boost::none; } @@ -267,39 +275,98 @@ struct DnsRR_SRV uint16_t priority; uint16_t weight; uint16_t port; - std::string name; - std::string service; DnsName hostname; - static void decode(std::vector &results, const std::vector &buffer, const DnsResource &rr, ptrdiff_t dataoffset) + static optional decode(const std::vector &buffer, const DnsResource &rr, size_t dataoffset) { if (rr.data.size() < MIN_SIZE) { - return; + return boost::none; } DnsRR_SRV res; - { - const auto dot_pos = rr.name.find_first_of('.'); - if (dot_pos > 0 && dot_pos < rr.name.size() - 1) { - res.name = rr.name.substr(0, dot_pos); - res.service = rr.name.substr(dot_pos + 1); - } else { - return; - } - } - const uint16_t *data_16 = reinterpret_cast(rr.data.data()); res.priority = endian::big_to_native(data_16[0]); res.weight = endian::big_to_native(data_16[1]); res.port = endian::big_to_native(data_16[2]); - ptrdiff_t offset = dataoffset + 6; + size_t offset = dataoffset + 6; auto hostname = DnsName::decode(buffer, offset); if (hostname) { res.hostname = std::move(*hostname); - results.emplace_back(std::move(res)); + return std::move(res); + } else { + return boost::none; + } + } +}; + +struct DnsRR_TXT +{ + enum + { + TAG = 0x10, + }; + + std::vector values; + + static optional decode(const DnsResource &rr) + { + const size_t size = rr.data.size(); + if (size < 2) { + return boost::none; + } + + DnsRR_TXT res; + + for (auto it = rr.data.begin(); it != rr.data.end(); ) { + unsigned val_size = static_cast(*it); + if (val_size == 0 || it + val_size >= rr.data.end()) { + return boost::none; + } + ++it; + + std::string value(val_size, ' '); + std::copy(it, it + val_size, value.begin()); + res.values.push_back(std::move(value)); + + it += val_size; + } + + return std::move(res); + } +}; + +struct DnsSDPair +{ + optional srv; + optional txt; +}; + +struct DnsSDMap : public std::map +{ + void insert_srv(std::string &&name, DnsRR_SRV &&srv) + { + auto hit = this->find(name); + if (hit != this->end()) { + hit->second.srv = std::move(srv); + } else { + DnsSDPair pair; + pair.srv = std::move(srv); + this->insert(std::make_pair(std::move(name), std::move(pair))); + } + } + + void insert_txt(std::string &&name, DnsRR_TXT &&txt) + { + auto hit = this->find(name); + if (hit != this->end()) { + hit->second.txt = std::move(txt); + } else { + DnsSDPair pair; + pair.txt = std::move(txt); + this->insert(std::make_pair(std::move(name), std::move(pair))); } } }; @@ -314,12 +381,13 @@ struct DnsMessage DnsHeader header; optional question; - std::vector answers; optional rr_a; optional rr_aaaa; std::vector rr_srv; + DnsSDMap sdmap; + static optional decode(const std::vector &buffer, optional id_wanted = boost::none) { const auto size = buffer.size(); @@ -338,31 +406,39 @@ struct DnsMessage return boost::none; } - ptrdiff_t offset = DnsHeader::SIZE; + size_t offset = DnsHeader::SIZE; if (res.header.qdcount == 1) { res.question = DnsQuestion::decode(buffer, offset); } for (unsigned i = 0; i < res.header.rrcount(); i++) { - ptrdiff_t dataoffset = 0; + size_t dataoffset = 0; auto rr = DnsResource::decode(buffer, offset, dataoffset); if (!rr) { return boost::none; } else { - res.parse_rr(buffer, *rr, dataoffset); - res.answers.push_back(std::move(*rr)); + res.parse_rr(buffer, std::move(*rr), dataoffset); } } return std::move(res); } private: - void parse_rr(const std::vector &buffer, const DnsResource &rr, ptrdiff_t dataoffset) + void parse_rr(const std::vector &buffer, DnsResource &&rr, size_t dataoffset) { switch (rr.type) { case DnsRR_A::TAG: DnsRR_A::decode(this->rr_a, rr); break; case DnsRR_AAAA::TAG: DnsRR_AAAA::decode(this->rr_aaaa, rr); break; - case DnsRR_SRV::TAG: DnsRR_SRV::decode(this->rr_srv, buffer, rr, dataoffset); break; + case DnsRR_SRV::TAG: { + auto srv = DnsRR_SRV::decode(buffer, rr, dataoffset); + if (srv) { this->sdmap.insert_srv(std::move(rr.name), std::move(*srv)); } + break; + } + case DnsRR_TXT::TAG: { + auto txt = DnsRR_TXT::decode(rr); + if (txt) { this->sdmap.insert_txt(std::move(rr.name), std::move(*txt)); } + break; + } } } }; @@ -373,8 +449,6 @@ struct BonjourRequest static const asio::ip::address_v4 MCAST_IP4; static const uint16_t MCAST_PORT; - static const char rq_template[]; - uint16_t id; std::vector data; @@ -390,12 +464,6 @@ private: const asio::ip::address_v4 BonjourRequest::MCAST_IP4{0xe00000fb}; const uint16_t BonjourRequest::MCAST_PORT = 5353; -const char BonjourRequest::rq_template[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, - 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, - 0x00, 0x01, -}; - optional BonjourRequest::make(const std::string &service, const std::string &protocol) { if (service.size() > 15 || protocol.size() > 15) { @@ -416,7 +484,7 @@ optional BonjourRequest::make(const std::string &service, const data.push_back(id_char[1]); // Add metadata - static const char rq_meta[] = { + static const unsigned char rq_meta[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; std::copy(rq_meta, rq_meta + sizeof(rq_meta), std::back_inserter(data)); @@ -430,8 +498,8 @@ optional BonjourRequest::make(const std::string &service, const data.insert(data.end(), protocol.begin(), protocol.end()); // Add the rest of PTR record - static const char ptr_tail[] = { - 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, + static const unsigned char ptr_tail[] = { + 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0xff, }; std::copy(ptr_tail, ptr_tail + sizeof(ptr_tail), std::back_inserter(data)); @@ -456,7 +524,7 @@ struct Bonjour::priv priv(std::string service, std::string protocol); - void udp_receive(const error_code &error, size_t bytes); + void udp_receive(udp::endpoint from, size_t bytes); void lookup_perform(); }; @@ -470,23 +538,41 @@ Bonjour::priv::priv(std::string service, std::string protocol) : buffer.resize(DnsMessage::MAX_SIZE); } -void Bonjour::priv::udp_receive(const error_code &error, size_t bytes) +void Bonjour::priv::udp_receive(udp::endpoint from, size_t bytes) { - if (error || bytes == 0 || !replyfn) { + if (bytes == 0 || !replyfn) { return; } buffer.resize(bytes); const auto dns_msg = DnsMessage::decode(buffer, rq_id); if (dns_msg) { - std::string ip; - if (dns_msg->rr_a) { ip = dns_msg->rr_a->ip.to_string(); } - else if (dns_msg->rr_aaaa) { ip = dns_msg->rr_aaaa->ip.to_string(); } + asio::ip::address ip = from.address(); + if (dns_msg->rr_a) { ip = dns_msg->rr_a->ip; } + else if (dns_msg->rr_aaaa) { ip = dns_msg->rr_aaaa->ip; } - for (const auto &srv : dns_msg->rr_srv) { - if (srv.service == service_dn) { - replyfn(std::move(ip), std::move(srv.hostname), std::move(srv.name)); + for (const auto &sdpair : dns_msg->sdmap) { + if (! sdpair.second.srv) { + continue; } + + const auto &srv = *sdpair.second.srv; + BonjourReply reply(ip, sdpair.first, srv.hostname); + + if (sdpair.second.txt) { + static const std::string tag_path = "path="; + static const std::string tag_version = "version="; + + for (const auto &value : sdpair.second.txt->values) { + if (value.size() > tag_path.size() && value.compare(0, tag_path.size(), tag_path) == 0) { + reply.path = value.substr(tag_path.size()); + } else if (value.size() > tag_version.size() && value.compare(0, tag_version.size(), tag_version) == 0) { + reply.version = value.substr(tag_version.size()); + } + } + } + + replyfn(std::move(reply)); } } } @@ -519,17 +605,18 @@ void Bonjour::priv::lookup_perform() } }); - const auto recv_handler = [=](const error_code &error, size_t bytes) { - self->udp_receive(error, bytes); + udp::endpoint recv_from; + const auto recv_handler = [&](const error_code &error, size_t bytes) { + if (!error) { self->udp_receive(recv_from, bytes); } }; - socket.async_receive(asio::buffer(buffer, buffer.size()), recv_handler); + socket.async_receive_from(asio::buffer(buffer, buffer.size()), recv_from, recv_handler); while (io_service.run_one()) { if (timeout) { socket.cancel(); } else { buffer.resize(DnsMessage::MAX_SIZE); - socket.async_receive(asio::buffer(buffer, buffer.size()), recv_handler); + socket.async_receive_from(asio::buffer(buffer, buffer.size()), recv_from, recv_handler); } } } catch (std::exception& e) { @@ -539,6 +626,21 @@ void Bonjour::priv::lookup_perform() // API - public part +BonjourReply::BonjourReply(boost::asio::ip::address ip, std::string service_name, std::string hostname) : + ip(std::move(ip)), + service_name(std::move(service_name)), + hostname(std::move(hostname)), + path("/"), + version("Unknown") +{} + +std::ostream& operator<<(std::ostream &os, const BonjourReply &reply) +{ + os << "BonjourReply(" << reply.ip.to_string() << ", " << reply.service_name << ", " + << reply.hostname << ", " << reply.path << ", " << reply.version << ")"; + return os; +} + Bonjour::Bonjour(std::string service, std::string protocol) : p(new priv(std::move(service), std::move(protocol))) {} @@ -587,15 +689,15 @@ Bonjour::Ptr Bonjour::lookup() void Bonjour::pokus() // XXX { - // auto bonjour = Bonjour("http") - // .set_timeout(15) - // .on_reply([](std::string ip, std::string host, std::string service_name) { - // std::cerr << "MDNS: " << ip << " = " << host << " : " << service_name << std::endl; - // }) - // .on_complete([](){ - // std::cerr << "MDNS lookup complete" << std::endl; - // }) - // .lookup(); + auto bonjour = Bonjour("octoprint") + .set_timeout(15) + .on_reply([](BonjourReply &&reply) { + std::cerr << "BonjourReply: " << reply << std::endl; + }) + .on_complete([](){ + std::cerr << "MDNS lookup complete" << std::endl; + }) + .lookup(); } diff --git a/xs/src/slic3r/Utils/Bonjour.hpp b/xs/src/slic3r/Utils/Bonjour.hpp index 039db3370a..285625c04b 100644 --- a/xs/src/slic3r/Utils/Bonjour.hpp +++ b/xs/src/slic3r/Utils/Bonjour.hpp @@ -4,18 +4,35 @@ #include #include #include +// #include +#include namespace Slic3r { -/// Bonjour lookup +// TODO: reply data structure +struct BonjourReply +{ + boost::asio::ip::address ip; + std::string service_name; + std::string hostname; + std::string path; + std::string version; + + BonjourReply(boost::asio::ip::address ip, std::string service_name, std::string hostname); +}; + +std::ostream& operator<<(std::ostream &, const BonjourReply &); + + +/// Bonjour lookup performer class Bonjour : public std::enable_shared_from_this { private: struct priv; public: typedef std::shared_ptr Ptr; - typedef std::function ReplyFn; + typedef std::function ReplyFn; typedef std::function CompleteFn; Bonjour(std::string service, std::string protocol = "tcp"); diff --git a/xs/src/slic3r/Utils/OctoPrint.hpp b/xs/src/slic3r/Utils/OctoPrint.hpp index 1d70a087d0..eca3baa63a 100644 --- a/xs/src/slic3r/Utils/OctoPrint.hpp +++ b/xs/src/slic3r/Utils/OctoPrint.hpp @@ -3,7 +3,7 @@ #include -#include "Http.hpp" +// #include "Http.hpp" // XXX: ? namespace Slic3r { From e26ccfc2479ad373ab86d4c54d11c8e2194d19d8 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 6 Mar 2018 11:39:24 +0100 Subject: [PATCH 18/18] Fixed compilation on Windows, removed debugging menu and debugging output. --- lib/Slic3r/GUI/MainFrame.pm | 10 ---------- xs/CMakeLists.txt | 23 +++++++++++++++-------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index ee5ec7cb5d..442d0abc95 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -174,7 +174,6 @@ sub _init_tabpanel { EVT_COMMAND($self, -1, $BUTTON_BROWSE_EVENT, sub { my ($self, $event) = @_; my $msg = $event->GetString; - print "BUTTON_BROWSE_EVENT: ", $msg, "\n"; # look for devices my $entries; @@ -197,7 +196,6 @@ sub _init_tabpanel { EVT_COMMAND($self, -1, $BUTTON_TEST_EVENT, sub { my ($self, $event) = @_; my $msg = $event->GetString; - print "BUTTON_TEST_EVENT: ", $msg, "\n"; my $ua = LWP::UserAgent->new; $ua->timeout(10); @@ -410,13 +408,6 @@ sub _init_menubar { }); } - my $hokusMenu = Wx::Menu->new; # XXX: tmp - { - $self->_append_menu_item($hokusMenu, "Pokus", "Pokus", sub { - Slic3r::Http::pokus(); - }); - } - # menubar # assign menubar to frame after appending items, otherwise special items # will not be handled correctly @@ -431,7 +422,6 @@ sub _init_menubar { # (Select application language from the list of installed languages) Slic3r::GUI::add_debug_menu($menubar, $self->{lang_ch_event}); $menubar->Append($helpMenu, L("&Help")); - $menubar->Append($hokusMenu, "Hoku&s"); # Add an optional debug menu. In production code, the add_debug_menu() call should do nothing. $self->SetMenuBar($menubar); } diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index d8ef51caa7..5f57711470 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -533,14 +533,21 @@ find_package(CURL REQUIRED) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries(XS ${CURL_LIBRARIES}) -if (SLIC3R_STATIC AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - # As of now, our build system produces a statically linked libcurl, - # which links the OpenSSL library dynamically. - find_package(OpenSSL REQUIRED) - message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") - message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") - include_directories(${OPENSSL_INCLUDE_DIR}) - target_link_libraries(XS ${OPENSSL_LIBRARIES}) +if (SLIC3R_STATIC) + if (NOT APPLE) + # libcurl is always linked dynamically to the system libcurl on OSX. + # On other systems, libcurl is linked statically if SLIC3R_STATIC is set. + add_definitions(-DCURL_STATICLIB) + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # As of now, our build system produces a statically linked libcurl, + # which links the OpenSSL library dynamically. + find_package(OpenSSL REQUIRED) + message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") + message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") + include_directories(${OPENSSL_INCLUDE_DIR}) + target_link_libraries(XS ${OPENSSL_LIBRARIES}) + endif() endif() ## OPTIONAL packages