diff --git a/resources/localization/Slic3rPE.pot b/resources/localization/Slic3rPE.pot index e2f4a6ec2..b0852567f 100644 --- a/resources/localization/Slic3rPE.pot +++ b/resources/localization/Slic3rPE.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-09 19:23+0200\n" +"POT-Creation-Date: 2019-05-10 11:50+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -46,6 +46,33 @@ msgid "" "numerous others." msgstr "" +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:84 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:400 +msgid "Copying of the temporary G-code to the output G-code failed" +msgstr "" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:85 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:398 +msgid "Running post-processing scripts" +msgstr "" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:87 +msgid "G-code file exported to %1%" +msgstr "" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:91 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:109 +msgid "Slicing complete" +msgstr "" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:105 +msgid "Masked SLA file exported to %1%" +msgstr "" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:409 +msgid "Scheduling upload to `%1%`. See Window -> Print Host Upload Queue" +msgstr "" + #: src/slic3r/GUI/BedShapeDialog.cpp:60 msgid "Shape" msgstr "" @@ -225,6 +252,7 @@ msgid "slic3r version" msgstr "" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:46 src/slic3r/GUI/Preset.cpp:1274 +#: src/slic3r/GUI/Tab.hpp:315 msgid "print" msgstr "" @@ -233,6 +261,7 @@ msgid "filaments" msgstr "" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:48 src/slic3r/GUI/Preset.cpp:1278 +#: src/slic3r/GUI/Tab.hpp:366 msgid "printer" msgstr "" @@ -285,7 +314,7 @@ msgstr "" msgid "All standard" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:189 src/slic3r/GUI/Tab.cpp:2987 +#: src/slic3r/GUI/ConfigWizard.cpp:189 src/slic3r/GUI/Tab.cpp:3000 msgid "All" msgstr "" @@ -538,28 +567,28 @@ msgstr "" msgid "Configuration &Wizard" msgstr "" -#: src/slic3r/GUI/Field.cpp:93 +#: src/slic3r/GUI/Field.cpp:117 msgid "default value" msgstr "" -#: src/slic3r/GUI/Field.cpp:96 +#: src/slic3r/GUI/Field.cpp:120 msgid "parameter name" msgstr "" -#: src/slic3r/GUI/Field.cpp:124 +#: src/slic3r/GUI/Field.cpp:148 #, possible-c-format msgid "%s doesn't support percentage" msgstr "" -#: src/slic3r/GUI/Field.cpp:138 src/slic3r/GUI/Field.cpp:161 +#: src/slic3r/GUI/Field.cpp:162 src/slic3r/GUI/Field.cpp:185 msgid "Invalid numeric input." msgstr "" -#: src/slic3r/GUI/Field.cpp:143 +#: src/slic3r/GUI/Field.cpp:167 msgid "Input value is out of range" msgstr "" -#: src/slic3r/GUI/Field.cpp:169 +#: src/slic3r/GUI/Field.cpp:193 #, possible-c-format msgid "" "Do you mean %d%% instead of %d %s?\n" @@ -567,7 +596,7 @@ msgid "" "or NO if you are sure that %d %s is a correct value." msgstr "" -#: src/slic3r/GUI/Field.cpp:172 +#: src/slic3r/GUI/Field.cpp:196 msgid "Parameter validation" msgstr "" @@ -694,67 +723,71 @@ msgstr "" msgid "Cancelling..." msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:719 -msgid "Detected object outside print volume" -msgstr "" - #: src/slic3r/GUI/GLCanvas3D.cpp:720 -msgid "Detected toolpath outside print volume" +msgid "An object outside the print area was detected" msgstr "" #: src/slic3r/GUI/GLCanvas3D.cpp:721 -msgid "Some objects are not visible when editing supports" +msgid "A toolpath outside the print area was detected" +msgstr "" + +#: src/slic3r/GUI/GLCanvas3D.cpp:722 +msgid "SLA supports outside the print area were detected" msgstr "" #: src/slic3r/GUI/GLCanvas3D.cpp:723 -msgid "" -"Detected object outside print volume\n" -"Resolve a clash to continue slicing/export process correctly" +msgid "Some objects are not visible when editing supports" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3392 +#: src/slic3r/GUI/GLCanvas3D.cpp:725 +msgid "" +"An object outside the print area was detected\n" +"Resolve the current problem to continue slicing" +msgstr "" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3434 msgid "Add..." msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3402 src/slic3r/GUI/GUI_ObjectList.cpp:1269 -#: src/slic3r/GUI/Plater.cpp:2908 src/slic3r/GUI/Plater.cpp:2926 -#: src/slic3r/GUI/Tab.cpp:2938 +#: src/slic3r/GUI/GLCanvas3D.cpp:3444 src/slic3r/GUI/GUI_ObjectList.cpp:1269 +#: src/slic3r/GUI/Plater.cpp:2933 src/slic3r/GUI/Plater.cpp:2951 +#: src/slic3r/GUI/Tab.cpp:2951 msgid "Delete" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3413 src/slic3r/GUI/Plater.cpp:3316 +#: src/slic3r/GUI/GLCanvas3D.cpp:3455 src/slic3r/GUI/Plater.cpp:3341 msgid "Delete all" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3424 src/slic3r/GUI/KBShortcutsDialog.cpp:135 +#: src/slic3r/GUI/GLCanvas3D.cpp:3466 src/slic3r/GUI/KBShortcutsDialog.cpp:135 msgid "Arrange" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3438 src/slic3r/GUI/Tab.cpp:2879 +#: src/slic3r/GUI/GLCanvas3D.cpp:3480 src/slic3r/GUI/Tab.cpp:2892 msgid "Copy" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3449 +#: src/slic3r/GUI/GLCanvas3D.cpp:3491 msgid "Paste" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3463 +#: src/slic3r/GUI/GLCanvas3D.cpp:3505 msgid "Add instance" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3475 +#: src/slic3r/GUI/GLCanvas3D.cpp:3517 msgid "Remove instance" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3490 +#: src/slic3r/GUI/GLCanvas3D.cpp:3532 msgid "Split to objects" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3502 src/slic3r/GUI/GUI_ObjectList.cpp:1122 +#: src/slic3r/GUI/GLCanvas3D.cpp:3544 src/slic3r/GUI/GUI_ObjectList.cpp:1122 msgid "Split to parts" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3517 +#: src/slic3r/GUI/GLCanvas3D.cpp:3559 msgid "Layers editing" msgstr "" @@ -974,7 +1007,7 @@ msgstr "" msgid "Switch to editing mode" msgstr "" -#: src/slic3r/GUI/GUI.cpp:142 src/slic3r/GUI/Tab.cpp:2797 +#: src/slic3r/GUI/GUI.cpp:142 src/slic3r/GUI/Tab.cpp:2810 msgid "It's impossible to print multi-part object(s) with SLA technology." msgstr "" @@ -982,7 +1015,7 @@ msgstr "" msgid "Please check and fix your object list." msgstr "" -#: src/slic3r/GUI/GUI.cpp:144 src/slic3r/GUI/Tab.cpp:2799 +#: src/slic3r/GUI/GUI.cpp:144 src/slic3r/GUI/Tab.cpp:2812 msgid "Attention!" msgstr "" @@ -1067,7 +1100,7 @@ msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:539 src/slic3r/GUI/Tab.cpp:1027 #: src/slic3r/GUI/Tab.cpp:1042 src/slic3r/GUI/Tab.cpp:1140 #: src/slic3r/GUI/Tab.cpp:1143 src/slic3r/GUI/Tab.cpp:1516 -#: src/slic3r/GUI/Tab.cpp:1941 src/slic3r/GUI/Tab.cpp:3440 +#: src/slic3r/GUI/Tab.cpp:1941 src/slic3r/GUI/Tab.cpp:3453 #: src/slic3r/GUI/wxExtensions.cpp:2510 src/libslic3r/PrintConfig.cpp:73 #: src/libslic3r/PrintConfig.cpp:188 src/libslic3r/PrintConfig.cpp:351 #: src/libslic3r/PrintConfig.cpp:989 src/libslic3r/PrintConfig.cpp:2200 @@ -1134,10 +1167,10 @@ msgid "&Configuration" msgstr "" #: src/slic3r/GUI/GUI_App.cpp:801 -msgid "The following presets were modified: " +msgid "The following presets were modified" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:801 src/slic3r/GUI/Tab.cpp:2785 +#: src/slic3r/GUI/GUI_App.cpp:801 src/slic3r/GUI/Tab.cpp:2798 msgid "Discard changes and continue anyway?" msgstr "" @@ -1235,8 +1268,8 @@ msgid "Extrusion Width" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:87 src/slic3r/GUI/GUI_ObjectList.cpp:541 -#: src/slic3r/GUI/Plater.cpp:429 src/slic3r/GUI/Tab.cpp:3402 -#: src/slic3r/GUI/Tab.cpp:3403 src/libslic3r/PrintConfig.cpp:2388 +#: src/slic3r/GUI/Plater.cpp:429 src/slic3r/GUI/Tab.cpp:3415 +#: src/slic3r/GUI/Tab.cpp:3416 src/libslic3r/PrintConfig.cpp:2388 #: src/libslic3r/PrintConfig.cpp:2395 src/libslic3r/PrintConfig.cpp:2404 #: src/libslic3r/PrintConfig.cpp:2413 src/libslic3r/PrintConfig.cpp:2423 #: src/libslic3r/PrintConfig.cpp:2449 src/libslic3r/PrintConfig.cpp:2456 @@ -1248,7 +1281,7 @@ msgid "Supports" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:88 src/slic3r/GUI/GUI_ObjectList.cpp:542 -#: src/slic3r/GUI/Tab.cpp:3430 src/slic3r/GUI/Tab.cpp:3431 +#: src/slic3r/GUI/Tab.cpp:3443 src/slic3r/GUI/Tab.cpp:3444 #: src/libslic3r/PrintConfig.cpp:2541 src/libslic3r/PrintConfig.cpp:2548 #: src/libslic3r/PrintConfig.cpp:2562 src/libslic3r/PrintConfig.cpp:2572 #: src/libslic3r/PrintConfig.cpp:2585 src/libslic3r/PrintConfig.cpp:2594 @@ -1355,7 +1388,7 @@ msgstr "" msgid "Fix through the Netfabb" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1231 src/slic3r/GUI/Plater.cpp:2944 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1231 src/slic3r/GUI/Plater.cpp:2969 msgid "Export as STL" msgstr "" @@ -1383,7 +1416,7 @@ msgstr "" msgid "You can't delete the last intance from object." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1742 src/slic3r/GUI/Plater.cpp:2290 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1742 src/slic3r/GUI/Plater.cpp:2306 msgid "" "The selected object couldn't be split because it contains only one part." msgstr "" @@ -1460,13 +1493,13 @@ msgid "Renaming" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:2730 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2824 src/slic3r/GUI/Tab.cpp:3283 -#: src/slic3r/GUI/Tab.cpp:3287 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2824 src/slic3r/GUI/Tab.cpp:3296 +#: src/slic3r/GUI/Tab.cpp:3300 msgid "The supplied name is not valid;" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:2731 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2825 src/slic3r/GUI/Tab.cpp:3284 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2825 src/slic3r/GUI/Tab.cpp:3297 msgid "the following characters are not allowed:" msgstr "" @@ -1668,7 +1701,7 @@ msgid "Load Config from .ini/amf/3mf/gcode" msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:108 src/slic3r/GUI/Plater.cpp:740 -#: src/slic3r/GUI/Plater.cpp:3839 src/libslic3r/PrintConfig.cpp:2990 +#: src/slic3r/GUI/Plater.cpp:3864 src/libslic3r/PrintConfig.cpp:2990 msgid "Export G-code" msgstr "" @@ -2161,8 +2194,13 @@ msgid "Iso View" msgstr "" #. TRN To be shown in the main menu View->Top +#: src/slic3r/GUI/MainFrame.cpp:527 +msgctxt "Layers" +msgid "Top" +msgstr "" + #. TRN To be shown in Print Settings "Top solid layers" -#: src/slic3r/GUI/MainFrame.cpp:527 src/libslic3r/PrintConfig.cpp:2068 +#: src/libslic3r/PrintConfig.cpp:2068 msgid "Top" msgstr "" @@ -2171,8 +2209,13 @@ msgid "Top View" msgstr "" #. TRN To be shown in the main menu View->Bottom +#: src/slic3r/GUI/MainFrame.cpp:529 +msgid "Bottom" +msgstr "" + #. TRN To be shown in Print Settings "Bottom solid layers" -#: src/slic3r/GUI/MainFrame.cpp:529 src/libslic3r/PrintConfig.cpp:150 +#: src/libslic3r/PrintConfig.cpp:150 +msgctxt "Layers" msgid "Bottom" msgstr "" @@ -2306,7 +2349,7 @@ msgstr "" msgid "&Help" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:607 src/slic3r/GUI/Plater.cpp:3839 +#: src/slic3r/GUI/MainFrame.cpp:607 src/slic3r/GUI/Plater.cpp:3864 msgid "Export" msgstr "" @@ -2338,7 +2381,7 @@ msgstr "" msgid "File Not Found" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:686 src/slic3r/GUI/Tab.cpp:3244 +#: src/slic3r/GUI/MainFrame.cpp:686 src/slic3r/GUI/Tab.cpp:3257 msgid "Save " msgstr "" @@ -2358,9 +2401,9 @@ msgstr "" msgid "Save zip file as:" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:713 src/slic3r/GUI/Plater.cpp:2423 -#: src/slic3r/GUI/Plater.cpp:3633 src/slic3r/GUI/Tab.cpp:1160 -#: src/slic3r/GUI/Tab.cpp:3441 +#: src/slic3r/GUI/MainFrame.cpp:713 src/slic3r/GUI/Plater.cpp:2439 +#: src/slic3r/GUI/Plater.cpp:3658 src/slic3r/GUI/Tab.cpp:1160 +#: src/slic3r/GUI/Tab.cpp:3454 msgid "Slicing" msgstr "" @@ -2525,12 +2568,12 @@ msgstr "" msgid "Printer" msgstr "" -#: src/slic3r/GUI/Plater.cpp:738 src/slic3r/GUI/Plater.cpp:3840 +#: src/slic3r/GUI/Plater.cpp:738 src/slic3r/GUI/Plater.cpp:3865 msgid "Send to printer" msgstr "" -#: src/slic3r/GUI/Plater.cpp:741 src/slic3r/GUI/Plater.cpp:2423 -#: src/slic3r/GUI/Plater.cpp:3636 +#: src/slic3r/GUI/Plater.cpp:741 src/slic3r/GUI/Plater.cpp:2439 +#: src/slic3r/GUI/Plater.cpp:3661 msgid "Slice now" msgstr "" @@ -2587,286 +2630,286 @@ msgstr "" msgid "stealth mode" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1601 +#: src/slic3r/GUI/Plater.cpp:1604 msgid "Loading" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1611 +#: src/slic3r/GUI/Plater.cpp:1614 #, possible-c-format msgid "Processing input file %s\n" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1669 +#: src/slic3r/GUI/Plater.cpp:1672 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 "" -#: src/slic3r/GUI/Plater.cpp:1672 src/slic3r/GUI/Plater.cpp:1780 +#: src/slic3r/GUI/Plater.cpp:1675 src/slic3r/GUI/Plater.cpp:1783 msgid "Multi-part object detected" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1723 +#: src/slic3r/GUI/Plater.cpp:1726 msgid "" "This file cannot be loaded in a simple mode. Do you want to switch to an " "advanced mode?\n" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1724 +#: src/slic3r/GUI/Plater.cpp:1727 msgid "Detected advanced data" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1757 +#: src/slic3r/GUI/Plater.cpp:1760 #, possible-c-format msgid "" "You can't to add the object(s) from %s because of one or some of them " "is(are) multi-part" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1777 +#: src/slic3r/GUI/Plater.cpp:1780 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 "" -#: src/slic3r/GUI/Plater.cpp:1793 +#: src/slic3r/GUI/Plater.cpp:1796 msgid "Loaded" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1885 +#: src/slic3r/GUI/Plater.cpp:1894 msgid "" "Your object appears to be too large, so it was automatically scaled down to " "fit your print bed." msgstr "" -#: src/slic3r/GUI/Plater.cpp:1886 +#: src/slic3r/GUI/Plater.cpp:1895 msgid "Object too large?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1936 +#: src/slic3r/GUI/Plater.cpp:1945 msgid "Export STL file:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1943 +#: src/slic3r/GUI/Plater.cpp:1952 msgid "Export AMF file:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1949 +#: src/slic3r/GUI/Plater.cpp:1958 msgid "Save file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2114 +#: src/slic3r/GUI/Plater.cpp:2123 msgid "Arranging canceled" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2117 +#: src/slic3r/GUI/Plater.cpp:2126 msgid "Arranging" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2151 +#: src/slic3r/GUI/Plater.cpp:2163 msgid "Could not arrange model objects! Some geometries may be invalid." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2155 +#: src/slic3r/GUI/Plater.cpp:2170 msgid "Arranging done." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2196 +#: src/slic3r/GUI/Plater.cpp:2211 msgid "Orientation search canceled" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2201 +#: src/slic3r/GUI/Plater.cpp:2216 msgid "Searching for optimal orientation" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2262 +#: src/slic3r/GUI/Plater.cpp:2278 msgid "Orientation found." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2282 +#: src/slic3r/GUI/Plater.cpp:2298 msgid "" "The selected object can't be split because it contains more than one volume/" "material." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2408 +#: src/slic3r/GUI/Plater.cpp:2424 msgid "Invalid data" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2417 +#: src/slic3r/GUI/Plater.cpp:2433 msgid "Ready to slice" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2455 src/slic3r/GUI/PrintHostDialogs.cpp:231 +#: src/slic3r/GUI/Plater.cpp:2471 src/slic3r/GUI/PrintHostDialogs.cpp:231 msgid "Cancelling" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2472 +#: src/slic3r/GUI/Plater.cpp:2488 msgid "Another export job is currently running." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2733 +#: src/slic3r/GUI/Plater.cpp:2749 msgid "Export failed" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2738 src/slic3r/GUI/PrintHostDialogs.cpp:232 +#: src/slic3r/GUI/Plater.cpp:2754 src/slic3r/GUI/PrintHostDialogs.cpp:232 msgid "Cancelled" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2824 src/slic3r/GUI/Plater.cpp:2836 -#: src/slic3r/GUI/Plater.cpp:2914 +#: src/slic3r/GUI/Plater.cpp:2840 src/slic3r/GUI/Plater.cpp:2852 +#: src/slic3r/GUI/Plater.cpp:2939 msgid "Increase copies" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2908 src/slic3r/GUI/Plater.cpp:2926 +#: src/slic3r/GUI/Plater.cpp:2933 src/slic3r/GUI/Plater.cpp:2951 msgid "Remove the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2914 +#: src/slic3r/GUI/Plater.cpp:2939 msgid "Place one more copy of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2916 +#: src/slic3r/GUI/Plater.cpp:2941 msgid "Decrease copies" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2916 +#: src/slic3r/GUI/Plater.cpp:2941 msgid "Remove one copy of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2918 +#: src/slic3r/GUI/Plater.cpp:2943 msgid "Set number of copies" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2918 +#: src/slic3r/GUI/Plater.cpp:2943 msgid "Change the number of copies of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2941 +#: src/slic3r/GUI/Plater.cpp:2966 msgid "Reload from Disk" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2941 +#: src/slic3r/GUI/Plater.cpp:2966 msgid "Reload the selected file from Disk" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2944 +#: src/slic3r/GUI/Plater.cpp:2969 msgid "Export the selected object as STL file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2956 +#: src/slic3r/GUI/Plater.cpp:2981 msgid "Along X axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2956 +#: src/slic3r/GUI/Plater.cpp:2981 msgid "Mirror the selected object along the X axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2958 +#: src/slic3r/GUI/Plater.cpp:2983 msgid "Along Y axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2958 +#: src/slic3r/GUI/Plater.cpp:2983 msgid "Mirror the selected object along the Y axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2960 +#: src/slic3r/GUI/Plater.cpp:2985 msgid "Along Z axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2960 +#: src/slic3r/GUI/Plater.cpp:2985 msgid "Mirror the selected object along the Z axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2963 +#: src/slic3r/GUI/Plater.cpp:2988 msgid "Mirror" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2963 +#: src/slic3r/GUI/Plater.cpp:2988 msgid "Mirror the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2983 +#: src/slic3r/GUI/Plater.cpp:3008 msgid "To objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2983 src/slic3r/GUI/Plater.cpp:3005 +#: src/slic3r/GUI/Plater.cpp:3008 src/slic3r/GUI/Plater.cpp:3030 msgid "Split the selected object into individual objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2985 +#: src/slic3r/GUI/Plater.cpp:3010 msgid "To parts" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2985 src/slic3r/GUI/Plater.cpp:3025 +#: src/slic3r/GUI/Plater.cpp:3010 src/slic3r/GUI/Plater.cpp:3050 msgid "Split the selected object into individual sub-parts" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2988 src/slic3r/GUI/Plater.cpp:3005 -#: src/slic3r/GUI/Plater.cpp:3025 src/libslic3r/PrintConfig.cpp:3108 +#: src/slic3r/GUI/Plater.cpp:3013 src/slic3r/GUI/Plater.cpp:3030 +#: src/slic3r/GUI/Plater.cpp:3050 src/libslic3r/PrintConfig.cpp:3108 msgid "Split" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2988 +#: src/slic3r/GUI/Plater.cpp:3013 msgid "Split the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3011 +#: src/slic3r/GUI/Plater.cpp:3036 msgid "Optimize orientation" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3011 +#: src/slic3r/GUI/Plater.cpp:3036 msgid "Optimize the rotation of the object for better print results." msgstr "" -#: src/slic3r/GUI/Plater.cpp:3074 +#: src/slic3r/GUI/Plater.cpp:3099 msgid "3D editor view" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3085 src/slic3r/GUI/Tab.cpp:2289 +#: src/slic3r/GUI/Plater.cpp:3110 src/slic3r/GUI/Tab.cpp:2289 msgid "Preview" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3316 +#: src/slic3r/GUI/Plater.cpp:3341 msgid "All objects will be removed, continue ?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3451 +#: src/slic3r/GUI/Plater.cpp:3476 msgid "Save G-code file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3451 +#: src/slic3r/GUI/Plater.cpp:3476 msgid "Save SL1 file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3563 +#: src/slic3r/GUI/Plater.cpp:3588 #, possible-c-format msgid "STL file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3579 +#: src/slic3r/GUI/Plater.cpp:3604 #, possible-c-format msgid "AMF file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3582 +#: src/slic3r/GUI/Plater.cpp:3607 #, possible-c-format msgid "Error exporting AMF file %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3608 +#: src/slic3r/GUI/Plater.cpp:3633 #, possible-c-format msgid "3MF file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3611 +#: src/slic3r/GUI/Plater.cpp:3636 #, possible-c-format msgid "Error exporting 3MF file %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3840 +#: src/slic3r/GUI/Plater.cpp:3865 msgid "Send G-code" msgstr "" @@ -2982,7 +3025,7 @@ msgstr "" msgid "Add a new printer" msgstr "" -#: src/slic3r/GUI/Preset.cpp:1275 +#: src/slic3r/GUI/Preset.cpp:1275 src/slic3r/GUI/Tab.hpp:333 msgid "filament" msgstr "" @@ -3284,7 +3327,7 @@ msgstr "" msgid "default SLA print profile" msgstr "" -#: src/slic3r/GUI/Tab.cpp:998 src/slic3r/GUI/Tab.cpp:3396 +#: src/slic3r/GUI/Tab.cpp:998 src/slic3r/GUI/Tab.cpp:3409 msgid "Layers and perimeters" msgstr "" @@ -3368,7 +3411,7 @@ msgstr "" msgid "Other" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1169 src/slic3r/GUI/Tab.cpp:3444 +#: src/slic3r/GUI/Tab.cpp:1169 src/slic3r/GUI/Tab.cpp:3457 msgid "Output options" msgstr "" @@ -3380,7 +3423,7 @@ msgstr "" msgid "Extruder clearance (mm)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1181 src/slic3r/GUI/Tab.cpp:3445 +#: src/slic3r/GUI/Tab.cpp:1181 src/slic3r/GUI/Tab.cpp:3458 msgid "Output file" msgstr "" @@ -3392,19 +3435,19 @@ msgstr "" #: src/slic3r/GUI/Tab.cpp:1577 src/slic3r/GUI/Tab.cpp:1578 #: src/slic3r/GUI/Tab.cpp:1986 src/slic3r/GUI/Tab.cpp:1987 #: src/slic3r/GUI/Tab.cpp:2080 src/slic3r/GUI/Tab.cpp:2081 -#: src/slic3r/GUI/Tab.cpp:3333 src/slic3r/GUI/Tab.cpp:3334 +#: src/slic3r/GUI/Tab.cpp:3346 src/slic3r/GUI/Tab.cpp:3347 msgid "Notes" msgstr "" #: src/slic3r/GUI/Tab.cpp:1201 src/slic3r/GUI/Tab.cpp:1585 #: src/slic3r/GUI/Tab.cpp:1993 src/slic3r/GUI/Tab.cpp:2087 -#: src/slic3r/GUI/Tab.cpp:3341 src/slic3r/GUI/Tab.cpp:3450 +#: src/slic3r/GUI/Tab.cpp:3354 src/slic3r/GUI/Tab.cpp:3463 msgid "Dependencies" msgstr "" #: src/slic3r/GUI/Tab.cpp:1202 src/slic3r/GUI/Tab.cpp:1586 #: src/slic3r/GUI/Tab.cpp:1994 src/slic3r/GUI/Tab.cpp:2088 -#: src/slic3r/GUI/Tab.cpp:3342 src/slic3r/GUI/Tab.cpp:3451 +#: src/slic3r/GUI/Tab.cpp:3355 src/slic3r/GUI/Tab.cpp:3464 msgid "Profile dependencies" msgstr "" @@ -3576,7 +3619,7 @@ msgid "Size and coordinates" msgstr "" #: src/slic3r/GUI/Tab.cpp:1819 src/slic3r/GUI/Tab.cpp:2020 -#: src/slic3r/GUI/Tab.cpp:2989 +#: src/slic3r/GUI/Tab.cpp:3002 msgid " Set " msgstr "" @@ -3640,7 +3683,7 @@ msgstr "" msgid "Tilt time" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2060 src/slic3r/GUI/Tab.cpp:3315 +#: src/slic3r/GUI/Tab.cpp:2060 src/slic3r/GUI/Tab.cpp:3328 msgid "Corrections" msgstr "" @@ -3719,104 +3762,104 @@ msgid "" "setups)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2430 +#: src/slic3r/GUI/Tab.cpp:2443 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 "" -#: src/slic3r/GUI/Tab.cpp:2432 +#: src/slic3r/GUI/Tab.cpp:2445 msgid "Firmware Retraction" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2758 +#: src/slic3r/GUI/Tab.cpp:2771 #, possible-c-format msgid "Default preset (%s)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2759 +#: src/slic3r/GUI/Tab.cpp:2772 #, possible-c-format msgid "Preset (%s)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2776 +#: src/slic3r/GUI/Tab.cpp:2789 msgid "has the following unsaved changes:" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2779 +#: src/slic3r/GUI/Tab.cpp:2792 msgid "is not compatible with printer" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2780 +#: src/slic3r/GUI/Tab.cpp:2793 msgid "is not compatible with print profile" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2782 +#: src/slic3r/GUI/Tab.cpp:2795 msgid "and it has the following unsaved changes:" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2786 +#: src/slic3r/GUI/Tab.cpp:2799 msgid "Unsaved Changes" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2798 +#: src/slic3r/GUI/Tab.cpp:2811 msgid "Please check your object list before preset changing." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2901 +#: src/slic3r/GUI/Tab.cpp:2914 msgid "The supplied name is empty. It can't be saved." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2906 +#: src/slic3r/GUI/Tab.cpp:2919 msgid "Cannot overwrite a system profile." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2910 +#: src/slic3r/GUI/Tab.cpp:2923 msgid "Cannot overwrite an external profile." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2936 +#: src/slic3r/GUI/Tab.cpp:2949 msgid "remove" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2936 +#: src/slic3r/GUI/Tab.cpp:2949 msgid "delete" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2937 +#: src/slic3r/GUI/Tab.cpp:2950 msgid "Are you sure you want to " msgstr "" -#: src/slic3r/GUI/Tab.cpp:2937 +#: src/slic3r/GUI/Tab.cpp:2950 msgid " the selected preset?" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2938 +#: src/slic3r/GUI/Tab.cpp:2951 msgid "Remove" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2939 +#: src/slic3r/GUI/Tab.cpp:2952 msgid " Preset" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3065 +#: src/slic3r/GUI/Tab.cpp:3078 msgid "LOCKED LOCK" msgstr "" #. TRN Description for "LOCKED LOCK" -#: src/slic3r/GUI/Tab.cpp:3067 +#: src/slic3r/GUI/Tab.cpp:3080 msgid "" "indicates that the settings are the same as the system values for the " "current option group" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3069 +#: src/slic3r/GUI/Tab.cpp:3082 msgid "UNLOCKED LOCK" msgstr "" #. TRN Description for "UNLOCKED LOCK" -#: src/slic3r/GUI/Tab.cpp:3071 +#: src/slic3r/GUI/Tab.cpp:3084 msgid "" "indicates that some settings were changed and are not equal to the system " "values for the current option group.\n" @@ -3824,23 +3867,23 @@ msgid "" "to the system values." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3076 +#: src/slic3r/GUI/Tab.cpp:3089 msgid "WHITE BULLET" msgstr "" #. TRN Description for "WHITE BULLET" -#: src/slic3r/GUI/Tab.cpp:3078 +#: src/slic3r/GUI/Tab.cpp:3091 msgid "" "for the left button: \tindicates a non-system preset,\n" "for the right button: \tindicates that the settings hasn't been modified." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3081 +#: src/slic3r/GUI/Tab.cpp:3094 msgid "BACK ARROW" msgstr "" #. TRN Description for "BACK ARROW" -#: src/slic3r/GUI/Tab.cpp:3083 +#: src/slic3r/GUI/Tab.cpp:3096 msgid "" "indicates that the settings were changed and are not equal to the last saved " "preset for the current option group.\n" @@ -3848,30 +3891,30 @@ msgid "" "to the last saved preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3108 +#: src/slic3r/GUI/Tab.cpp:3121 msgid "" "LOCKED LOCK icon indicates that the settings are the same as the system " "values for the current option group" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3110 +#: src/slic3r/GUI/Tab.cpp:3123 msgid "" "UNLOCKED LOCK icon indicates that some settings were changed and are not " "equal to the system values for the current option group.\n" "Click to reset all settings for current option group to the system values." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3113 +#: src/slic3r/GUI/Tab.cpp:3126 msgid "WHITE BULLET icon indicates a non system preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3116 +#: src/slic3r/GUI/Tab.cpp:3129 msgid "" "WHITE BULLET icon indicates that the settings are the same as in the last " "saved preset for the current option group." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3118 +#: src/slic3r/GUI/Tab.cpp:3131 msgid "" "BACK ARROW icon indicates that the settings were changed and are not equal " "to the last saved preset for the current option group.\n" @@ -3879,84 +3922,84 @@ msgid "" "preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3124 +#: src/slic3r/GUI/Tab.cpp:3137 msgid "" "LOCKED LOCK icon indicates that the value is the same as the system value." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3125 +#: src/slic3r/GUI/Tab.cpp:3138 msgid "" "UNLOCKED LOCK icon indicates that the value was changed and is not equal to " "the system value.\n" "Click to reset current value to the system value." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3131 +#: src/slic3r/GUI/Tab.cpp:3144 msgid "" "WHITE BULLET icon indicates that the value is the same as in the last saved " "preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3132 +#: src/slic3r/GUI/Tab.cpp:3145 msgid "" "BACK ARROW icon indicates that the value was changed and is not equal to the " "last saved preset.\n" "Click to reset current value to the last saved preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3244 +#: src/slic3r/GUI/Tab.cpp:3257 msgid " as:" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3288 +#: src/slic3r/GUI/Tab.cpp:3301 msgid "the following postfix are not allowed:" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3292 +#: src/slic3r/GUI/Tab.cpp:3305 msgid "The supplied name is not available." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3305 +#: src/slic3r/GUI/Tab.cpp:3318 msgid "Material" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3307 src/slic3r/GUI/Tab.cpp:3398 +#: src/slic3r/GUI/Tab.cpp:3320 src/slic3r/GUI/Tab.cpp:3411 msgid "Layers" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3311 +#: src/slic3r/GUI/Tab.cpp:3324 msgid "Exposure" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3406 +#: src/slic3r/GUI/Tab.cpp:3419 msgid "Support head" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3411 +#: src/slic3r/GUI/Tab.cpp:3424 msgid "Support pillar" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3421 +#: src/slic3r/GUI/Tab.cpp:3434 msgid "Connection of the support sticks and junctions" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3426 +#: src/slic3r/GUI/Tab.cpp:3439 msgid "Automatic generation" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3488 +#: src/slic3r/GUI/Tab.cpp:3501 msgid "Head penetration should not be greater than the head width." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3489 +#: src/slic3r/GUI/Tab.cpp:3502 msgid "Invalid Head penetration" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3501 +#: src/slic3r/GUI/Tab.cpp:3514 msgid "Pinhead diameter should be smaller than the pillar diameter." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3502 +#: src/slic3r/GUI/Tab.cpp:3515 msgid "Invalid pinhead diameter" msgstr "" @@ -3976,6 +4019,14 @@ msgstr "" msgid "Material Settings" msgstr "" +#: src/slic3r/GUI/Tab.hpp:389 +msgid "sla_material" +msgstr "" + +#: src/slic3r/GUI/Tab.hpp:403 +msgid "sla_print" +msgstr "" + #: src/slic3r/GUI/Tab.hpp:415 msgid "Save preset" msgstr "" @@ -4803,6 +4854,7 @@ msgstr "" #: src/libslic3r/PrintConfig.cpp:1595 src/libslic3r/PrintConfig.cpp:1605 #: src/libslic3r/PrintConfig.cpp:1833 src/libslic3r/PrintConfig.cpp:1987 #: src/libslic3r/PrintConfig.cpp:2171 src/libslic3r/PrintConfig.cpp:2488 +#: src/libslic3r/PrintConfig.cpp:2597 msgid "°" msgstr "" @@ -7288,10 +7340,6 @@ msgid "" "straight walls." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2597 -msgid "degrees" -msgstr "" - #: src/libslic3r/PrintConfig.cpp:2957 msgid "Export OBJ" msgstr "" @@ -7545,6 +7593,22 @@ msgid "" "loaded instead of the default OpenGL driver." msgstr "" +#: src/libslic3r/PrintObject.cpp:110 +msgid "Processing triangulated mesh" +msgstr "" + +#: src/libslic3r/PrintObject.cpp:141 +msgid "Generating perimeters" +msgstr "" + +#: src/libslic3r/PrintObject.cpp:251 +msgid "Preparing infill" +msgstr "" + +#: src/libslic3r/PrintObject.cpp:391 +msgid "Generating support material" +msgstr "" + #: src/libslic3r/GCode/PreviewData.cpp:176 msgid "Mixed" msgstr "" diff --git a/resources/localization/list.txt b/resources/localization/list.txt index cf6ca4c84..fdffaf9d9 100644 --- a/resources/localization/list.txt +++ b/resources/localization/list.txt @@ -1,4 +1,5 @@ src/slic3r/GUI/AboutDialog.cpp +src/slic3r/GUI/BackgroundSlicingProcess.cpp src/slic3r/GUI/BedShapeDialog.cpp src/slic3r/GUI/BedShapeDialog.hpp src/slic3r/GUI/BonjourDialog.cpp @@ -47,4 +48,5 @@ src/libslic3r/Print.cpp src/libslic3r/SLAPrint.cpp src/libslic3r/PrintBase.cpp src/libslic3r/PrintConfig.cpp +src/libslic3r/PrintObject.cpp src/libslic3r/GCode/PreviewData.cpp diff --git a/src/libslic3r/ModelArrange.cpp b/src/libslic3r/ModelArrange.cpp index c821eef77..18a2d08c4 100644 --- a/src/libslic3r/ModelArrange.cpp +++ b/src/libslic3r/ModelArrange.cpp @@ -539,7 +539,7 @@ public: // 2D shape from top view. using ShapeData2D = std::vector<std::pair<Slic3r::ModelInstance*, Item>>; -ShapeData2D projectModelFromTop(const Slic3r::Model &model) { +ShapeData2D projectModelFromTop(const Slic3r::Model &model, const WipeTowerInfo& wti) { ShapeData2D ret; // Count all the items on the bin (all the object's instances) @@ -600,6 +600,28 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) { } } + // The wipe tower is a separate case (in case there is one), let's duplicate the code + if (wti.is_wipe_tower) { + Points pts; + pts.emplace_back(coord_t(scale_(0.)), coord_t(scale_(0.))); + pts.emplace_back(coord_t(scale_(wti.bb_size(0))), coord_t(scale_(0.))); + pts.emplace_back(coord_t(scale_(wti.bb_size(0))), coord_t(scale_(wti.bb_size(1)))); + pts.emplace_back(coord_t(scale_(-0.)), coord_t(scale_(wti.bb_size(1)))); + pts.emplace_back(coord_t(scale_(-0.)), coord_t(scale_(0.))); + Polygon p(std::move(pts)); + ClipperLib::Path clpath = Slic3rMultiPoint_to_ClipperPath(p); + ClipperLib::Polygon pn; + pn.Contour = clpath; + // Efficient conversion to item. + Item item(std::move(pn)); + item.rotation(wti.rotation), + item.translation({ + ClipperLib::cInt(wti.pos(0)/SCALING_FACTOR), + ClipperLib::cInt(wti.pos(1)/SCALING_FACTOR) + }); + ret.emplace_back(nullptr, item); + } + return ret; } @@ -608,7 +630,8 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) { void applyResult( IndexedPackGroup::value_type& group, Coord batch_offset, - ShapeData2D& shapemap) + ShapeData2D& shapemap, + WipeTowerInfo& wti) { for(auto& r : group) { auto idx = r.first; // get the original item index @@ -617,18 +640,25 @@ void applyResult( // Get the model instance from the shapemap using the index ModelInstance *inst_ptr = shapemap[idx].first; - // Get the transformation data from the item object and scale it - // appropriately - auto off = item.translation(); - Radians rot = item.rotation(); + // Get the transformation data from the item object and scale it + // appropriately + auto off = item.translation(); + Radians rot = item.rotation(); - Vec3d foff(off.X*SCALING_FACTOR + batch_offset, - off.Y*SCALING_FACTOR, - inst_ptr->get_offset()(Z)); + Vec3d foff(off.X*SCALING_FACTOR + batch_offset, + off.Y*SCALING_FACTOR, + inst_ptr ? inst_ptr->get_offset()(Z) : 0.); - // write the transformation data into the model instance - inst_ptr->set_rotation(Z, rot); - inst_ptr->set_offset(foff); + if (inst_ptr) { + // write the transformation data into the model instance + inst_ptr->set_rotation(Z, rot); + inst_ptr->set_offset(foff); + } + else { // this is the wipe tower - we will modify the struct with the info + // and leave it up to the called to actually move the wipe tower + wti.pos = Vec2d(foff(0), foff(1)); + wti.rotation = rot; + } } } @@ -714,6 +744,7 @@ BedShapeHint bedShape(const Polyline &bed) { // The final client function to arrange the Model. A progress indicator and // a stop predicate can be also be passed to control the process. bool arrange(Model &model, // The model with the geometries + WipeTowerInfo& wti, // Wipe tower info coord_t min_obj_distance, // Has to be in scaled (clipper) measure const Polyline &bed, // The bed geometry. BedShapeHint bedhint, // Hint about the bed geometry type. @@ -726,7 +757,7 @@ bool arrange(Model &model, // The model with the geometries bool ret = true; // Get the 2D projected shapes with their 3D model instance pointers - auto shapemap = arr::projectModelFromTop(model); + auto shapemap = arr::projectModelFromTop(model, wti); // Copy the references for the shapes only as the arranger expects a // sequence of objects convertible to Item or ClipperPolygon @@ -796,7 +827,7 @@ bool arrange(Model &model, // The model with the geometries if(result.empty() || stopcondition()) return false; if(first_bin_only) { - applyResult(result.front(), 0, shapemap); + applyResult(result.front(), 0, shapemap, wti); } else { const auto STRIDE_PADDING = 1.2; @@ -806,7 +837,7 @@ bool arrange(Model &model, // The model with the geometries Coord batch_offset = 0; for(auto& group : result) { - applyResult(group, batch_offset, shapemap); + applyResult(group, batch_offset, shapemap, wti); // Only the first pack group can be placed onto the print bed. The // other objects which could not fit will be placed next to the @@ -823,10 +854,11 @@ bool arrange(Model &model, // The model with the geometries void find_new_position(const Model &model, ModelInstancePtrs toadd, coord_t min_obj_distance, - const Polyline &bed) + const Polyline &bed, + WipeTowerInfo& wti) { // Get the 2D projected shapes with their 3D model instance pointers - auto shapemap = arr::projectModelFromTop(model); + auto shapemap = arr::projectModelFromTop(model, wti); // Copy the references for the shapes only as the arranger expects a // sequence of objects convertible to Item or ClipperPolygon diff --git a/src/libslic3r/ModelArrange.hpp b/src/libslic3r/ModelArrange.hpp index d76769081..b61443da0 100644 --- a/src/libslic3r/ModelArrange.hpp +++ b/src/libslic3r/ModelArrange.hpp @@ -40,6 +40,13 @@ struct BedShapeHint { BedShapeHint bedShape(const Polyline& bed); +struct WipeTowerInfo { + bool is_wipe_tower = false; + Vec2d pos; + Vec2d bb_size; + double rotation; +}; + /** * \brief Arranges the model objects on the screen. * @@ -66,7 +73,9 @@ BedShapeHint bedShape(const Polyline& bed); * packed. The unsigned argument is the number of items remaining to pack. * \param stopcondition A predicate returning true if abort is needed. */ -bool arrange(Model &model, coord_t min_obj_distance, +bool arrange(Model &model, + WipeTowerInfo& wipe_tower_info, + coord_t min_obj_distance, const Slic3r::Polyline& bed, BedShapeHint bedhint, bool first_bin_only, @@ -78,7 +87,8 @@ bool arrange(Model &model, coord_t min_obj_distance, void find_new_position(const Model& model, ModelInstancePtrs instances_to_add, coord_t min_obj_distance, - const Slic3r::Polyline& bed); + const Slic3r::Polyline& bed, + WipeTowerInfo& wti); } // arr } // Slic3r diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 7e312cb23..59480de1c 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -716,12 +716,12 @@ int GLVolumeCollection::load_wipe_tower_preview( brim_mesh.translate(-brim_width, -brim_width, 0.f); mesh.merge(brim_mesh); - mesh.rotate(rotation_angle, &origin_of_rotation); // rotates the box according to the config rotation setting - this->volumes.emplace_back(new GLVolume(color)); GLVolume &v = *this->volumes.back(); v.indexed_vertex_array.load_mesh(mesh, use_VBOs); v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); + v.set_volume_rotation(Vec3d(0., 0., (M_PI/180.) * rotation_angle)); + // finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry(). v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(use_VBOs); diff --git a/src/slic3r/GUI/ButtonsDescription.cpp b/src/slic3r/GUI/ButtonsDescription.cpp index f9ab9b89c..0610199f5 100644 --- a/src/slic3r/GUI/ButtonsDescription.cpp +++ b/src/slic3r/GUI/ButtonsDescription.cpp @@ -26,9 +26,9 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry { auto icon = new wxStaticBitmap(this, wxID_ANY, entry.bitmap->bmp()); grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL); - auto description = new wxStaticText(this, wxID_ANY, _utf8(entry.symbol)); + auto description = new wxStaticText(this, wxID_ANY, _(entry.symbol)); grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL); - description = new wxStaticText(this, wxID_ANY, _utf8(entry.explanation)); + description = new wxStaticText(this, wxID_ANY, _(entry.explanation)); grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); } diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index edc65aca0..9443f3658 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -15,7 +15,31 @@ namespace Slic3r { namespace GUI { wxString double_to_string(double const value, const int max_precision /*= 4*/) { - return wxNumberFormatter::ToString(value, max_precision, wxNumberFormatter::Style_NoTrailingZeroes); +// Style_NoTrailingZeroes does not work on OSX. It also does not work correctly with some locales on Windows. +// return wxNumberFormatter::ToString(value, max_precision, wxNumberFormatter::Style_NoTrailingZeroes); + + wxString s = wxNumberFormatter::ToString(value, max_precision, wxNumberFormatter::Style_None); + + // The following code comes from wxNumberFormatter::RemoveTrailingZeroes(wxString& s) + // with the exception that here one sets the decimal separator explicitely to dot. + // If number is in scientific format, trailing zeroes belong to the exponent and cannot be removed. + if (s.find_first_of("eE") == wxString::npos) { + const size_t posDecSep = s.find("."); + // No decimal point => removing trailing zeroes irrelevant for integer number. + if (posDecSep != wxString::npos) { + // Find the last character to keep. + size_t posLastNonZero = s.find_last_not_of("0"); + // If it's the decimal separator itself, don't keep it neither. + if (posLastNonZero == posDecSep) + -- posLastNonZero; + s.erase(posLastNonZero + 1); + // Remove sign from orphaned zero. + if (s.compare("-0") == 0) + s = "0"; + } + } + + return s; } void Field::PostInitialize() diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index deb55c986..36581369c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -16,6 +16,7 @@ #include "slic3r/GUI/GLShader.hpp" #include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/PresetBundle.hpp" +#include "slic3r/GUI/Tab.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" @@ -716,13 +717,13 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool std::string text; bool red_colored = false; switch (m_warnings.back()) { - case ObjectOutside : text = L("Detected object outside print volume"); break; - case ToolpathOutside : text = L("Detected toolpath outside print volume"); break; - case SlaSupportsOutside : text = L("Detected support outside print volume"); break; + case ObjectOutside : text = L("An object outside the print area was detected"); break; + case ToolpathOutside : text = L("A toolpath outside the print area was detected"); break; + case SlaSupportsOutside : text = L("SLA supports outside the print area were detected"); break; case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break; case ObjectClashed: { - text = L("Detected object outside print volume\n" - "Resolve a clash to continue slicing/export process correctly"); + text = L("An object outside the print area was detected\n" + "Resolve the current problem to continue slicing"); red_colored = true; break; } @@ -1202,6 +1203,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); @@ -2073,6 +2075,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } m_gizmos.update_data(*this); + m_gizmos.refresh_on_off_state(m_selection); // Update the toolbar if (update_object_list) @@ -3115,6 +3118,10 @@ void GLCanvas3D::do_rotate() for (const GLVolume* v : m_volumes.volumes) { int object_idx = v->object_idx(); + if (object_idx == 1000) { // the wipe tower + Vec3d offset = v->get_volume_offset(); + post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2)))); + } if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx)) continue; @@ -3311,6 +3318,38 @@ void GLCanvas3D::update_ui_from_settings() #endif } + + +arr::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const +{ + arr::WipeTowerInfo wti; + for (const GLVolume* vol : m_volumes.volumes) { + if (vol->is_wipe_tower) { + wti.is_wipe_tower = true; + wti.pos = Vec2d(m_config->opt_float("wipe_tower_x"), + m_config->opt_float("wipe_tower_y")); + wti.rotation = (M_PI/180.) * m_config->opt_float("wipe_tower_rotation_angle"); + const BoundingBoxf3& bb = vol->bounding_box; + wti.bb_size = Vec2d(bb.size()(0), bb.size()(1)); + break; + } + } + return wti; +} + + +void GLCanvas3D::arrange_wipe_tower(const arr::WipeTowerInfo& wti) const +{ + if (wti.is_wipe_tower) { + DynamicPrintConfig cfg; + cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = wti.pos(0); + cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = wti.pos(1); + cfg.opt<ConfigOptionFloat>("wipe_tower_rotation_angle", true)->value = (180./M_PI) * wti.rotation; + wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); + } +} + + Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) { float z0 = 0.0f; @@ -4314,6 +4353,7 @@ void GLCanvas3D::_render_selection_sidebar_hints() const m_shader.stop_using(); } + void GLCanvas3D::_update_volumes_hover_state() const { for (GLVolume* v : m_volumes.volumes) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 7edef2466..96b958cbf 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -4,6 +4,7 @@ #include <stddef.h> #include <memory> +#include "libslic3r/ModelArrange.hpp" #include "3DScene.hpp" #include "GLToolbar.hpp" #include "Event.hpp" @@ -116,6 +117,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); @@ -608,6 +610,9 @@ public: int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); } + arr::WipeTowerInfo get_wipe_tower_info() const; + void arrange_wipe_tower(const arr::WipeTowerInfo& wti) const; + // Returns the view ray line, in world coordinate, at the given mouse position. Linef3 mouse_ray(const Point& mouse_pos); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 79b24fe1a..04ea99505 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -798,7 +798,7 @@ bool GUI_App::check_unsaved_changes() return true; // Ask the user. wxMessageDialog dialog(mainframe, - _(L("The following presets were modified: ")) + dirty + "\n" + _(L("Discard changes and continue anyway?")), + _(L("The following presets were modified")) + ": " + dirty + "\n" + _(L("Discard changes and continue anyway?")), wxString(SLIC3R_APP_NAME) + " - " + _(L("Unsaved Presets")), wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT); return dialog.ShowModal() == wxID_YES; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index f5946aa56..c65dee4d8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -102,7 +102,7 @@ protected: m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1); } } - virtual bool on_is_activable(const Selection& selection) const { return !selection.is_wipe_tower(); } + virtual bool on_is_activable(const Selection& selection) const { return true; } virtual void on_enable_grabber(unsigned int id) { if ((0 <= id) && (id < 3)) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 64c8a73b0..7e978e2a3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -4,6 +4,7 @@ #include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" +#include "slic3r/GUI/PresetBundle.hpp" #include <GL/glew.h> #include <wx/glcanvas.h> @@ -264,8 +265,11 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) const Selection& selection = canvas.get_selection(); - bool enable_move_z = !selection.is_wipe_tower(); - enable_grabber(Move, 2, enable_move_z); + bool is_wipe_tower = selection.is_wipe_tower(); + enable_grabber(Move, 2, !is_wipe_tower); + enable_grabber(Rotate, 0, !is_wipe_tower); + enable_grabber(Rotate, 1, !is_wipe_tower); + bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); for (int i = 0; i < 6; ++i) { @@ -290,6 +294,14 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) set_flattening_data(nullptr); set_sla_support_data(nullptr, selection); } + else if (is_wipe_tower) + { + DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + set_scale(Vec3d::Ones()); + set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast<const ConfigOptionFloat*>(config.option("wipe_tower_rotation_angle"))->value)); + set_flattening_data(nullptr); + set_sla_support_data(nullptr, selection); + } else { set_scale(Vec3d::Ones()); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fa2c166d2..27f5795b2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1314,6 +1314,7 @@ struct Plater::priv void on_object_select(SimpleEvent&); void on_right_click(Vec2dEvent&); void on_wipetower_moved(Vec3dEvent&); + void on_wipetower_rotated(Vec3dEvent&); void on_update_geometry(Vec3dsEvent<2>&); void on_3dcanvas_mouse_dragging_finished(SimpleEvent&); @@ -1448,6 +1449,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); + view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event<bool> &evt) { this->sidebar->enable_buttons(evt.data); }); @@ -1455,6 +1457,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this); view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); }); + // 3DScene/Toolbar: view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); }); @@ -1877,7 +1880,13 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode Polyline bed; bed.points.reserve(bedpoints.size()); for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1))); - arr::find_new_position(model, new_instances, min_obj_distance, bed); + arr::WipeTowerInfo wti = view3D->get_canvas3d()->get_wipe_tower_info(); + + arr::find_new_position(model, new_instances, min_obj_distance, bed, wti); + + // it remains to move the wipe tower: + view3D->get_canvas3d()->arrange_wipe_tower(wti); + #endif /* AUTOPLACEMENT_ON_LOAD */ if (scaled_down) { @@ -2134,6 +2143,8 @@ void Plater::priv::arrange() statusfn(0, arrangestr); + arr::WipeTowerInfo wti = view3D->get_canvas3d()->get_wipe_tower_info(); + try { arr::BedShapeHint hint; @@ -2141,6 +2152,7 @@ void Plater::priv::arrange() hint.type = arr::BedShapeType::WHO_KNOWS; arr::arrange(model, + wti, min_obj_distance, bed, hint, @@ -2152,6 +2164,9 @@ void Plater::priv::arrange() "Some geometries may be invalid.")); } + // it remains to move the wipe tower: + view3D->get_canvas3d()->arrange_wipe_tower(wti); + statusfn(0, L("Arranging done.")); statusbar()->set_range(prev_range); statusbar()->set_cancel_callback(); // remove cancel button @@ -2254,7 +2269,8 @@ void Plater::priv::sla_optimize_rotation() { oi->set_rotation(rt); } - arr::find_new_position(model, o->instances, coord_t(mindist/SCALING_FACTOR), bed); + arr::WipeTowerInfo wti; // useless in SLA context + arr::find_new_position(model, o->instances, coord_t(mindist/SCALING_FACTOR), bed, wti); // Correct the z offset of the object which was corrupted be the rotation o->ensure_on_bed(); @@ -2862,6 +2878,15 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); } +void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt) +{ + DynamicPrintConfig cfg; + cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0); + cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1); + cfg.opt<ConfigOptionFloat>("wipe_tower_rotation_angle", true)->value = Geometry::rad2deg(evt.data(2)); + wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); +} + void Plater::priv::on_update_geometry(Vec3dsEvent<2>&) { // TODO diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index eaa00bf6f..ee47446cf 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -499,100 +499,111 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ // Only relative rotation values are allowed in the world coordinate system. assert(!transformation_type.world() || transformation_type.relative()); - int rot_axis_max = 0; - if (rotation.isApprox(Vec3d::Zero())) - { - for (unsigned int i : m_list) + if (!is_wipe_tower()) { + int rot_axis_max = 0; + if (rotation.isApprox(Vec3d::Zero())) { - GLVolume &volume = *(*m_volumes)[i]; - if (m_mode == Instance) - { - volume.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation()); - volume.set_instance_offset(m_cache.volumes_data[i].get_instance_position()); - } - else if (m_mode == Volume) - { - volume.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); - volume.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); - } - } - } - else - { - //FIXME this does not work for absolute rotations (transformation_type.absolute() is true) - rotation.cwiseAbs().maxCoeff(&rot_axis_max); - - // For generic rotation, we want to rotate the first volume in selection, and then to synchronize the other volumes with it. - std::vector<int> object_instance_first(m_model->objects.size(), -1); - auto rotate_instance = [this, &rotation, &object_instance_first, rot_axis_max, transformation_type](GLVolume &volume, int i) { - int first_volume_idx = object_instance_first[volume.object_idx()]; - if (rot_axis_max != 2 && first_volume_idx != -1) { - // Generic rotation, but no rotation around the Z axis. - // Always do a local rotation (do not consider the selection to be a rigid body). - assert(is_approx(rotation.z(), 0.0)); - const GLVolume &first_volume = *(*m_volumes)[first_volume_idx]; - const Vec3d &rotation = first_volume.get_instance_rotation(); - double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation()); - volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff)); - } - else { - // extracts rotations from the composed transformation - Vec3d new_rotation = transformation_type.world() ? - Geometry::extract_euler_angles(Geometry::assemble_transform(Vec3d::Zero(), rotation) * m_cache.volumes_data[i].get_instance_rotation_matrix()) : - transformation_type.absolute() ? rotation : rotation + m_cache.volumes_data[i].get_instance_rotation(); - if (rot_axis_max == 2 && transformation_type.joint()) { - // Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis. - Vec3d offset = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, new_rotation(2) - m_cache.volumes_data[i].get_instance_rotation()(2))) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); - volume.set_instance_offset(m_cache.dragging_center + offset); - } - volume.set_instance_rotation(new_rotation); - object_instance_first[volume.object_idx()] = i; - } - }; - - for (unsigned int i : m_list) - { - GLVolume &volume = *(*m_volumes)[i]; - if (is_single_full_instance()) - rotate_instance(volume, i); - else if (is_single_volume() || is_single_modifier()) - { - if (transformation_type.independent()) - volume.set_volume_rotation(volume.get_volume_rotation() + rotation); - else - { - Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); - Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - volume.set_volume_rotation(new_rotation); - } - } - else + for (unsigned int i : m_list) { + GLVolume &volume = *(*m_volumes)[i]; if (m_mode == Instance) - rotate_instance(volume, i); + { + volume.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation()); + volume.set_instance_offset(m_cache.volumes_data[i].get_instance_position()); + } else if (m_mode == Volume) { - // extracts rotations from the composed transformation - Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); - Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - if (transformation_type.joint()) - { - Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center; - Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot); - volume.set_volume_offset(local_pivot + offset); - } - volume.set_volume_rotation(new_rotation); + volume.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); + volume.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); } } } - } + else { // this is not the wipe tower + //FIXME this does not work for absolute rotations (transformation_type.absolute() is true) + rotation.cwiseAbs().maxCoeff(&rot_axis_max); -#if !DISABLE_INSTANCES_SYNCH - if (m_mode == Instance) - synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL); - else if (m_mode == Volume) - synchronize_unselected_volumes(); -#endif // !DISABLE_INSTANCES_SYNCH + // For generic rotation, we want to rotate the first volume in selection, and then to synchronize the other volumes with it. + std::vector<int> object_instance_first(m_model->objects.size(), -1); + auto rotate_instance = [this, &rotation, &object_instance_first, rot_axis_max, transformation_type](GLVolume &volume, int i) { + int first_volume_idx = object_instance_first[volume.object_idx()]; + if (rot_axis_max != 2 && first_volume_idx != -1) { + // Generic rotation, but no rotation around the Z axis. + // Always do a local rotation (do not consider the selection to be a rigid body). + assert(is_approx(rotation.z(), 0.0)); + const GLVolume &first_volume = *(*m_volumes)[first_volume_idx]; + const Vec3d &rotation = first_volume.get_instance_rotation(); + double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation()); + volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff)); + } + else { + // extracts rotations from the composed transformation + Vec3d new_rotation = transformation_type.world() ? + Geometry::extract_euler_angles(Geometry::assemble_transform(Vec3d::Zero(), rotation) * m_cache.volumes_data[i].get_instance_rotation_matrix()) : + transformation_type.absolute() ? rotation : rotation + m_cache.volumes_data[i].get_instance_rotation(); + if (rot_axis_max == 2 && transformation_type.joint()) { + // Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis. + Vec3d offset = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, new_rotation(2) - m_cache.volumes_data[i].get_instance_rotation()(2))) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); + volume.set_instance_offset(m_cache.dragging_center + offset); + } + volume.set_instance_rotation(new_rotation); + object_instance_first[volume.object_idx()] = i; + } + }; + + for (unsigned int i : m_list) + { + GLVolume &volume = *(*m_volumes)[i]; + if (is_single_full_instance()) + rotate_instance(volume, i); + else if (is_single_volume() || is_single_modifier()) + { + if (transformation_type.independent()) + volume.set_volume_rotation(volume.get_volume_rotation() + rotation); + else + { + Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); + Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); + volume.set_volume_rotation(new_rotation); + } + } + else + { + if (m_mode == Instance) + rotate_instance(volume, i); + else if (m_mode == Volume) + { + // extracts rotations from the composed transformation + Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); + Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); + if (transformation_type.joint()) + { + Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center; + Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot); + volume.set_volume_offset(local_pivot + offset); + } + volume.set_volume_rotation(new_rotation); + } + } + } + } + + #if !DISABLE_INSTANCES_SYNCH + if (m_mode == Instance) + synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL); + else if (m_mode == Volume) + synchronize_unselected_volumes(); + #endif // !DISABLE_INSTANCES_SYNCH + } + else { // it's the wipe tower that's selected and being rotated + GLVolume& volume = *((*m_volumes)[*m_list.begin()]); // the wipe tower is always alone in the selection + + // make sure the wipe tower rotates around its center, not origin + // we can assume that only Z rotation changes + Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset(); + Vec3d center_local_new = Eigen::AngleAxisd(rotation(2)-volume.get_volume_rotation()(2), Vec3d(0, 0, 1)) * center_local; + volume.set_volume_rotation(rotation); + volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new); + } this->set_bounding_boxes_dirty(); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 3a1b5d37d..4e2403914 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2333,7 +2333,20 @@ void TabPrinter::update_pages() // set m_pages_(technology after changing) to m_pages // m_printer_technology will be set by Tab::load_current_preset() if (new_printer_technology == ptFFF) - m_pages_fff.empty() ? build_fff() : m_pages.swap(m_pages_fff); + { + if (m_pages_fff.empty()) + { + build_fff(); + if (m_extruders_count > 1) + { + m_preset_bundle->update_multi_material_filament_presets(); + on_value_change("extruders_count", m_extruders_count); + wxGetApp().sidebar().update_objects_list_extruder_column(m_extruders_count); + } + } + else + m_pages.swap(m_pages_fff); + } else m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 58bd3cfb5..5f01988f5 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -312,7 +312,7 @@ class TabPrint : public Tab bool is_msg_dlg_already_exist {false}; public: TabPrint(wxNotebook* parent) : - Tab(parent, _(L("Print Settings")), "print") {} + Tab(parent, _(L("Print Settings")), L("print")) {} ~TabPrint() {} ogStaticText* m_recommended_thin_wall_thickness_description_line; @@ -330,7 +330,7 @@ class TabFilament : public Tab ogStaticText* m_cooling_description_line; public: TabFilament(wxNotebook* parent) : - Tab(parent, _(L("Filament Settings")), "filament") {} + Tab(parent, _(L("Filament Settings")), L("filament")) {} ~TabFilament() {} void build() override; @@ -363,7 +363,7 @@ public: PrinterTechnology m_printer_technology = ptFFF; - TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), "printer") {} + TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), L("printer")) {} ~TabPrinter() {} void build() override; @@ -386,7 +386,7 @@ class TabSLAMaterial : public Tab { public: TabSLAMaterial(wxNotebook* parent) : - Tab(parent, _(L("Material Settings")), "sla_material") {} + Tab(parent, _(L("Material Settings")), L("sla_material")) {} ~TabSLAMaterial() {} void build() override; @@ -400,7 +400,7 @@ class TabSLAPrint : public Tab { public: TabSLAPrint(wxNotebook* parent) : - Tab(parent, _(L("Print Settings")), "sla_print") {} + Tab(parent, _(L("Print Settings")), L("sla_print")) {} ~TabSLAPrint() {} void build() override; void reload_config() override;