Merge branch 'master' into fs_dir_per_glyph_SPE-1597

This commit is contained in:
Filip Sykala - NTB T15p 2023-06-09 10:58:31 +02:00
commit 1f83fa9966
34 changed files with 380 additions and 270 deletions

View File

@ -13,8 +13,8 @@ if (UNIX AND NOT APPLE) # wxWidgets will not use char as the underlying type for
endif() endif()
prusaslicer_add_cmake_project(wxWidgets prusaslicer_add_cmake_project(wxWidgets
URL https://github.com/prusa3d/wxWidgets/archive/0b49beaacce17d90f0c370ecd73221abd089667a.zip URL https://github.com/prusa3d/wxWidgets/archive/78aa2dc0ea7ce99dc19adc1140f74c3e2e3f3a26.zip
URL_HASH SHA256=8fa978a76d6bd811b30eecc5124186b9ad54290b820f3a354e85bfa9dae6a5ce URL_HASH SHA256=94b7d972373503e380e5a8b0ca63b1ccb956da4006402298dd89a0c5c7041b1e
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG dep_NanoSVG DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG dep_NanoSVG
CMAKE_ARGS CMAKE_ARGS
-DwxBUILD_PRECOMP=ON -DwxBUILD_PRECOMP=ON

View File

@ -1512,7 +1512,7 @@ msgstr ""
#: src/slic3r/GUI/DoubleSlider.cpp:1465 #: src/slic3r/GUI/DoubleSlider.cpp:1465
msgid "Edit current color - Right click the colored slider segment" msgid "Edit current color - Right click the colored slider segment"
msgstr "" msgstr ""
"Змяніць бягучы колер - <b>Правая кнопка мышы</b> по каляроваму адрэзку " "Змяніць бягучы колер - Правая кнопка мышы по каляроваму адрэзку "
"паўзунка" "паўзунка"
#: src/slic3r/GUI/DoubleSlider.cpp:1467 #: src/slic3r/GUI/DoubleSlider.cpp:1467
@ -1533,32 +1533,32 @@ msgstr "Рэжым друку"
#: src/slic3r/GUI/DoubleSlider.cpp:1495 #: src/slic3r/GUI/DoubleSlider.cpp:1495
msgid "Add extruder change - Left click" msgid "Add extruder change - Left click"
msgstr "Дадаць змену экструдара - <b>Левая кнопка мышы</b>" msgstr "Дадаць змену экструдара - Левая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1497 #: src/slic3r/GUI/DoubleSlider.cpp:1497
msgid "" msgid ""
"Add color change - Left click for predefined color or Shift + Left click for " "Add color change - Left click for predefined color or Shift + Left click for "
"custom color selection" "custom color selection"
msgstr "" msgstr ""
"Дадаць змену колера - <b>Левая кнопка мышы</b> для колера з спіску " "Дадаць змену колера - Левая кнопка мышы для колера з спіску "
"першапачатковых колераў ці <b>Shift + Левая кнопка мышы</b> для выбору " "першапачатковых колераў ці Shift + Левая кнопка мышы для выбору "
"свайго колеру" "свайго колеру"
#: src/slic3r/GUI/DoubleSlider.cpp:1499 #: src/slic3r/GUI/DoubleSlider.cpp:1499
msgid "Add color change - Left click" msgid "Add color change - Left click"
msgstr "Дадаць змену колера - <b>Левая кнопка мышы</b>" msgstr "Дадаць змену колера - Левая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1500 #: src/slic3r/GUI/DoubleSlider.cpp:1500
msgid "or press \"+\" key" msgid "or press \"+\" key"
msgstr "альбо клавіша <b>+</b>" msgstr "альбо клавіша \"+\""
#: src/slic3r/GUI/DoubleSlider.cpp:1502 #: src/slic3r/GUI/DoubleSlider.cpp:1502
msgid "Add another code - Ctrl + Left click" msgid "Add another code - Ctrl + Left click"
msgstr "Дадаць іншы кода - <b>Ctrl + левая кнопка мышы</b>" msgstr "Дадаць іншы кода - Ctrl + левая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1503 #: src/slic3r/GUI/DoubleSlider.cpp:1503
msgid "Add another code - Right click" msgid "Add another code - Right click"
msgstr "Дадаць іншы код - <b>Правая кнопка мышы</b>" msgstr "Дадаць іншы код - Правая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1509 #: src/slic3r/GUI/DoubleSlider.cpp:1509
msgid "" msgid ""
@ -1639,15 +1639,15 @@ msgstr ""
#: src/slic3r/GUI/DoubleSlider.cpp:1565 #: src/slic3r/GUI/DoubleSlider.cpp:1565
msgid "Delete tick mark - Left click or press \"-\" key" msgid "Delete tick mark - Left click or press \"-\" key"
msgstr "Выдаліц птушку - <b>Левая кнопка мышы</b> альбо клавіша <b>-</b>" msgstr "Выдаліц птушку - Левая кнопка мышы альбо клавіша \"-\""
#: src/slic3r/GUI/DoubleSlider.cpp:1567 #: src/slic3r/GUI/DoubleSlider.cpp:1567
msgid "Edit tick mark - Ctrl + Left click" msgid "Edit tick mark - Ctrl + Left click"
msgstr "Змяніць птушку - <b>Ctrl + левая кнопка мышы</b>" msgstr "Змяніць птушку - Ctrl + левая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1568 #: src/slic3r/GUI/DoubleSlider.cpp:1568
msgid "Edit tick mark - Right click" msgid "Edit tick mark - Right click"
msgstr "Змяніць птушку - <b>Правая кнопка мышы</b>" msgstr "Змяніць птушку - Правая кнопка мышы"
#: src/slic3r/GUI/DoubleSlider.cpp:1671 src/slic3r/GUI/DoubleSlider.cpp:1702 #: src/slic3r/GUI/DoubleSlider.cpp:1671 src/slic3r/GUI/DoubleSlider.cpp:1702
#: src/slic3r/GUI/GUI_Factories.cpp:870 #: src/slic3r/GUI/GUI_Factories.cpp:870
@ -2495,7 +2495,7 @@ msgstr "Пераменная вышыня пластоў"
#: src/slic3r/GUI/GLCanvas3D.cpp:191 #: src/slic3r/GUI/GLCanvas3D.cpp:191
msgid "Left mouse button:" msgid "Left mouse button:"
msgstr "<b>Левая кнопка мышы</b>:" msgstr "Левая кнопка мышы:"
#: src/slic3r/GUI/GLCanvas3D.cpp:193 #: src/slic3r/GUI/GLCanvas3D.cpp:193
msgid "Add detail" msgid "Add detail"
@ -2503,7 +2503,7 @@ msgstr "Павялічыць дэтальнасць"
#: src/slic3r/GUI/GLCanvas3D.cpp:195 #: src/slic3r/GUI/GLCanvas3D.cpp:195
msgid "Right mouse button:" msgid "Right mouse button:"
msgstr "<b>Правая кнопка мышы</b>:" msgstr "Правая кнопка мышы:"
#: src/slic3r/GUI/GLCanvas3D.cpp:197 #: src/slic3r/GUI/GLCanvas3D.cpp:197
msgid "Remove detail" msgid "Remove detail"
@ -2511,7 +2511,7 @@ msgstr "Паменьшыць дэтальнасць"
#: src/slic3r/GUI/GLCanvas3D.cpp:199 #: src/slic3r/GUI/GLCanvas3D.cpp:199
msgid "Shift + Left mouse button:" msgid "Shift + Left mouse button:"
msgstr "<b>Shift + Левая кнопка мышы</b>:" msgstr "Shift + Левая кнопка мышы:"
#: src/slic3r/GUI/GLCanvas3D.cpp:201 #: src/slic3r/GUI/GLCanvas3D.cpp:201
msgid "Reset to base" msgid "Reset to base"
@ -2519,7 +2519,7 @@ msgstr "Скід да звычайнай вышыні пласта"
#: src/slic3r/GUI/GLCanvas3D.cpp:203 #: src/slic3r/GUI/GLCanvas3D.cpp:203
msgid "Shift + Right mouse button:" msgid "Shift + Right mouse button:"
msgstr "<b>Shift + Правая кнопка мышы</b>:" msgstr "Shift + Правая кнопка мышы:"
#: src/slic3r/GUI/GLCanvas3D.cpp:205 #: src/slic3r/GUI/GLCanvas3D.cpp:205
msgid "Smoothing" msgid "Smoothing"
@ -2527,7 +2527,7 @@ msgstr "Згладжванне"
#: src/slic3r/GUI/GLCanvas3D.cpp:207 #: src/slic3r/GUI/GLCanvas3D.cpp:207
msgid "Mouse wheel:" msgid "Mouse wheel:"
msgstr "<b>Кола мышы</b>:" msgstr "Кола мышы:"
#: src/slic3r/GUI/GLCanvas3D.cpp:209 #: src/slic3r/GUI/GLCanvas3D.cpp:209
msgid "Increase/decrease edit area" msgid "Increase/decrease edit area"
@ -2676,7 +2676,7 @@ msgstr "Налады ўпарадкавання"
#: src/slic3r/GUI/GLCanvas3D.cpp:4845 #: src/slic3r/GUI/GLCanvas3D.cpp:4845
#, boost-format #, boost-format
msgid "Press %1%left mouse button to enter the exact value" msgid "Press %1%left mouse button to enter the exact value"
msgstr "Націсніце %1% <b>левую кнопку мышы</b> для ўводу дакладнага значэння" msgstr "Націсніце %1% левую кнопку мышы для ўводу дакладнага значэння"
#: src/slic3r/GUI/GLCanvas3D.cpp:4847 #: src/slic3r/GUI/GLCanvas3D.cpp:4847
msgid "Spacing" msgid "Spacing"
@ -2739,7 +2739,7 @@ msgstr "Упарадкаваць абраныя"
#: src/slic3r/GUI/GLCanvas3D.cpp:5325 #: src/slic3r/GUI/GLCanvas3D.cpp:5325
msgid "Click right mouse button to show arrangement options" msgid "Click right mouse button to show arrangement options"
msgstr "" msgstr ""
"Пстрыкніце <b>правую кнопку мышы</b>, каб адлюстраваць налады ўпарадкавання" "Пстрыкніце правую кнопку мышы, каб адлюстраваць налады ўпарадкавання"
#: src/slic3r/GUI/GLCanvas3D.cpp:5345 #: src/slic3r/GUI/GLCanvas3D.cpp:5345
msgid "Copy" msgid "Copy"
@ -2769,7 +2769,7 @@ msgstr "Падзяліць на часткі"
#: src/slic3r/GUI/GLCanvas3D.cpp:5506 src/slic3r/GUI/GLCanvas3D.cpp:5543 #: src/slic3r/GUI/GLCanvas3D.cpp:5506 src/slic3r/GUI/GLCanvas3D.cpp:5543
msgid "Click right mouse button to open/close History" msgid "Click right mouse button to open/close History"
msgstr "" msgstr ""
"Псктрыкнуць <b>правую кнопку мышы</b>, каб адлюстраваць/схаваць Гісторы дзей" "Псктрыкнуць правую кнопку мышы, каб адлюстраваць/схаваць Гісторы дзей"
#: src/slic3r/GUI/GLCanvas3D.cpp:5528 #: src/slic3r/GUI/GLCanvas3D.cpp:5528
#, boost-format #, boost-format
@ -2942,7 +2942,7 @@ msgstr ""
#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1268 #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1268
#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1269 #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1269
msgid "Left click" msgid "Left click"
msgstr "<b>Левая кнопка мышы</b>" msgstr "Левая кнопка мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:823 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:823
#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:2821 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:2821
@ -2952,7 +2952,7 @@ msgstr ""
#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824
#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1266 #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1266
msgid "Right click" msgid "Right click"
msgstr "<b>Правая кнопка мышы</b>" msgstr "Правая кнопка мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824
msgid "Remove connector" msgid "Remove connector"
@ -3612,7 +3612,7 @@ msgstr "Форма пэндзаля"
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:110 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:110
#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:35 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:35
msgid "Left mouse button" msgid "Left mouse button"
msgstr "<b>Левая кнопка мышы</b>" msgstr "Левая кнопка мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:55 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:55
msgid "Enforce supports" msgid "Enforce supports"
@ -3622,7 +3622,7 @@ msgstr "Прымусовая падтрымка"
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:112 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:112
#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:37 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:37
msgid "Right mouse button" msgid "Right mouse button"
msgstr "<b>Правая кнопка мышы</b>" msgstr "Правая кнопка мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:57 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:57
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:575 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:575
@ -3633,7 +3633,7 @@ msgstr "Блакаваць падтрымкі"
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:114 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:114
#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:39 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:39
msgid "Shift + Left mouse button" msgid "Shift + Left mouse button"
msgstr "<b>Shift + Левая кнопка мышы</b>" msgstr "Shift + Левая кнопка мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:59 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:59
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:570 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:570
@ -3747,7 +3747,7 @@ msgstr "Фарбуе толькі адну мяжу."
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:462 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:462
#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:129 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:129
msgid "Alt + Mouse wheel" msgid "Alt + Mouse wheel"
msgstr "<b>Alt + Кола мышы</b>" msgstr "Alt + Кола мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:290 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:290
msgid "Splits bigger facets into smaller ones while the object is painted." msgid "Splits bigger facets into smaller ones while the object is painted."
@ -3757,7 +3757,7 @@ msgstr "Падчас фарбоўкі мадэлі разбівае вялікі
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:483 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:483
#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:167 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:167
msgid "Ctrl + Mouse wheel" msgid "Ctrl + Mouse wheel"
msgstr "<b>Ctrl + Кола мышы</b>" msgstr "Ctrl + Кола мышы"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:328 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:328
#: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:488 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:488
@ -5566,28 +5566,28 @@ msgstr "Засталося памылак"
#: src/slic3r/GUI/GUI_ObjectList.cpp:480 #: src/slic3r/GUI/GUI_ObjectList.cpp:480
msgid "Right button click the icon to fix STL through Netfabb" msgid "Right button click the icon to fix STL through Netfabb"
msgstr "" msgstr ""
"Пстрыкніце <b>правай кнопкай мышы</b> на гузік, каб выправіць STL з " "Пстрыкніце правай кнопкай мышы на гузік, каб выправіць STL з "
"дапамогай сервіса Netfabb" "дапамогай сервіса Netfabb"
#: src/slic3r/GUI/GUI_ObjectList.cpp:526 #: src/slic3r/GUI/GUI_ObjectList.cpp:526
msgid "Right button click the icon to change the object settings" msgid "Right button click the icon to change the object settings"
msgstr "" msgstr ""
"Пстрыкніце <b>правай кнопкай мышы</b> на гузік, каб змяніць налады мадэлі" "Пстрыкніце правай кнопкай мышы на гузік, каб змяніць налады мадэлі"
#: src/slic3r/GUI/GUI_ObjectList.cpp:528 #: src/slic3r/GUI/GUI_ObjectList.cpp:528
msgid "Click the icon to change the object settings" msgid "Click the icon to change the object settings"
msgstr "Пстрыкніце <b>кнопкай мышы</b> на гузік, каб змяніць налады мадэлі" msgstr "Пстрыкніце кнопкай мышы на гузік, каб змяніць налады мадэлі"
#: src/slic3r/GUI/GUI_ObjectList.cpp:532 #: src/slic3r/GUI/GUI_ObjectList.cpp:532
msgid "Right button click the icon to change the object printable property" msgid "Right button click the icon to change the object printable property"
msgstr "" msgstr ""
"Пстрыкніце <b>правай кнопкай мышы</b> на гузік, каб змяніць уласцівасці " "Пстрыкніце правай кнопкай мышы на гузік, каб змяніць уласцівасці "
"друку мадэлі" "друку мадэлі"
#: src/slic3r/GUI/GUI_ObjectList.cpp:534 #: src/slic3r/GUI/GUI_ObjectList.cpp:534
msgid "Click the icon to change the object printable property" msgid "Click the icon to change the object printable property"
msgstr "" msgstr ""
"Пстрыкніце <b>кнопкай мышы</b> на гузік, каб змяніць уласцівасці друку мадэлі" "Пстрыкніце кнопкай мышы на гузік, каб змяніць уласцівасці друку мадэлі"
#: src/slic3r/GUI/GUI_ObjectList.cpp:660 #: src/slic3r/GUI/GUI_ObjectList.cpp:660
msgid "Change Extruder" msgid "Change Extruder"
@ -6515,7 +6515,7 @@ msgstr "Націсніце, каб актываваць прастакутнік
#: src/slic3r/GUI/KBShortcutsDialog.cpp:239 #: src/slic3r/GUI/KBShortcutsDialog.cpp:239
#: src/slic3r/GUI/KBShortcutsDialog.cpp:254 #: src/slic3r/GUI/KBShortcutsDialog.cpp:254
msgid "Arrow Up" msgid "Arrow Up"
msgstr "<b>Стрэлка ўверх</b>" msgstr "Стрэлка ўверх"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:148 #: src/slic3r/GUI/KBShortcutsDialog.cpp:148
msgid "Move selection 10 mm in positive Y direction" msgid "Move selection 10 mm in positive Y direction"
@ -6526,7 +6526,7 @@ msgstr "Рушыць абранае на 10 мм у станоўчым кіру
#: src/slic3r/GUI/KBShortcutsDialog.cpp:240 #: src/slic3r/GUI/KBShortcutsDialog.cpp:240
#: src/slic3r/GUI/KBShortcutsDialog.cpp:255 #: src/slic3r/GUI/KBShortcutsDialog.cpp:255
msgid "Arrow Down" msgid "Arrow Down"
msgstr "<b>Стрэлка ўніз</b>" msgstr "Стрэлка ўніз"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:149 #: src/slic3r/GUI/KBShortcutsDialog.cpp:149
msgid "Move selection 10 mm in negative Y direction" msgid "Move selection 10 mm in negative Y direction"
@ -6537,7 +6537,7 @@ msgstr "Рушыць абранае на 10 мм у адмоўным кірун
#: src/slic3r/GUI/KBShortcutsDialog.cpp:241 #: src/slic3r/GUI/KBShortcutsDialog.cpp:241
#: src/slic3r/GUI/KBShortcutsDialog.cpp:252 #: src/slic3r/GUI/KBShortcutsDialog.cpp:252
msgid "Arrow Left" msgid "Arrow Left"
msgstr "<b>Стрэлка налева</b>" msgstr "Стрэлка налева"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:150 #: src/slic3r/GUI/KBShortcutsDialog.cpp:150
msgid "Move selection 10 mm in negative X direction" msgid "Move selection 10 mm in negative X direction"
@ -6548,7 +6548,7 @@ msgstr "Рушыць абранае на 10 мм у адмоўным кірун
#: src/slic3r/GUI/KBShortcutsDialog.cpp:242 #: src/slic3r/GUI/KBShortcutsDialog.cpp:242
#: src/slic3r/GUI/KBShortcutsDialog.cpp:253 #: src/slic3r/GUI/KBShortcutsDialog.cpp:253
msgid "Arrow Right" msgid "Arrow Right"
msgstr "<b>Стрэлка направа</b>" msgstr "Стрэлка направа"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:151 #: src/slic3r/GUI/KBShortcutsDialog.cpp:151
msgid "Move selection 10 mm in positive X direction" msgid "Move selection 10 mm in positive X direction"
@ -6569,7 +6569,7 @@ msgstr "Рух абранага ў прасторы камеры"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:154 #: src/slic3r/GUI/KBShortcutsDialog.cpp:154
msgid "Page Up" msgid "Page Up"
msgstr "<b>Page Up</b>" msgstr "Page Up"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:154 #: src/slic3r/GUI/KBShortcutsDialog.cpp:154
msgid "Rotate selection 45 degrees CCW" msgid "Rotate selection 45 degrees CCW"
@ -6577,7 +6577,7 @@ msgstr "Вярчэнне абранага на 45° супраць гадзін
#: src/slic3r/GUI/KBShortcutsDialog.cpp:155 #: src/slic3r/GUI/KBShortcutsDialog.cpp:155
msgid "Page Down" msgid "Page Down"
msgstr "<b>Page Down</b>" msgstr "Page Down"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:155 #: src/slic3r/GUI/KBShortcutsDialog.cpp:155
msgid "Rotate selection 45 degrees CW" msgid "Rotate selection 45 degrees CW"
@ -6688,8 +6688,8 @@ msgstr "Стол"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:190 #: src/slic3r/GUI/KBShortcutsDialog.cpp:190
msgid "All gizmos: Rotate - left mouse button; Pan - right mouse button" msgid "All gizmos: Rotate - left mouse button; Pan - right mouse button"
msgstr "" msgstr ""
"Усе штуковіны: Вярчэнне камеры - <b>Левая кнопка мышы</b>; Рух камеры - " "Усе штуковіны: Вярчэнне камеры - Левая кнопка мышы; Рух камеры - "
"<b>Правая кнопка мышы</b>" "Правая кнопка мышы"
#: src/slic3r/GUI/KBShortcutsDialog.cpp:191 #: src/slic3r/GUI/KBShortcutsDialog.cpp:191
msgid "Gizmo move: Press to snap by 1mm" msgid "Gizmo move: Press to snap by 1mm"
@ -8216,7 +8216,7 @@ msgstr "Нарэзаць зараз"
#: src/slic3r/GUI/Plater.cpp:1124 #: src/slic3r/GUI/Plater.cpp:1124
msgid "Hold Shift to Slice & Export G-code" msgid "Hold Shift to Slice & Export G-code"
msgstr "Утрымлівайце <b>Shift</b>, каб нарэзаць і экспартаваць у G-код" msgstr "Утрымлівайце Shift, каб нарэзаць і экспартаваць у G-код"
#: src/slic3r/GUI/Plater.cpp:1321 #: src/slic3r/GUI/Plater.cpp:1321
#, boost-format #, boost-format
@ -11163,7 +11163,7 @@ msgstr ""
msgid "" msgid ""
"Some fields are too long to fit. Right mouse click reveals the full text." "Some fields are too long to fit. Right mouse click reveals the full text."
msgstr "" msgstr ""
"Некаторыя палі занадта доўгія. Пстрыкніце <b>правай кнопкай мышы</b>, каб " "Некаторыя палі занадта доўгія. Пстрыкніце правай кнопкай мышы, каб "
"адлюстраваць поўны тэкст." "адлюстраваць поўны тэкст."
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:969 #: src/slic3r/GUI/UnsavedChangesDialog.cpp:969
@ -17761,7 +17761,7 @@ msgid ""
"size of the gap between objects and to allow automatic rotations?" "size of the gap between objects and to allow automatic rotations?"
msgstr "" msgstr ""
"Налады ўпарадкавання\n" "Налады ўпарадкавання\n"
"Ці ведаеце вы, што вы можаце пстрыкнуць <b>правай кнопкай мышы</b> на гузік " "Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на гузік "
"<a>Упарадкаваць гузікі</a>, каб наладзіць прагал паміж мадэлямя і дазволіць " "<a>Упарадкаваць гузікі</a>, каб наладзіць прагал паміж мадэлямя і дазволіць "
"аўтаматычнае вярчэнне?" "аўтаматычнае вярчэнне?"
@ -17788,8 +17788,8 @@ msgid ""
msgstr "" msgstr ""
"Спрасціць сетку\n" "Спрасціць сетку\n"
"Ці ведаеце вы, што вы можаце паменьшыць колкасць трыкутнікаў у паліганальнай " "Ці ведаеце вы, што вы можаце паменьшыць колкасць трыкутнікаў у паліганальнай "
"сетцы, калі ўжыць функцыю спрашчэння сеткі? Пстрыкніце <b>правай кнопкай " "сетцы, калі ўжыць функцыю спрашчэння сеткі? Пстрыкніце правай кнопкай "
"мышы</b> на мадэлі і абярыце <a>Спрасціць мадэль</a>. Больш падрабязна " "мышы на мадэлі і абярыце Спрасціць мадэль. Больш падрабязна "
"чытайце ў дакументацыі." "чытайце ў дакументацыі."
#: resources/data/hints.ini: [hint:Reload from disk] #: resources/data/hints.ini: [hint:Reload from disk]
@ -17801,9 +17801,9 @@ msgid ""
msgstr "" msgstr ""
"Перазагрузіць з дыску\n" "Перазагрузіць з дыску\n"
"Ці ведаеце вы, што калі вы стварылі больш новую версію сваёй мадэлі, вы " "Ці ведаеце вы, што калі вы стварылі больш новую версію сваёй мадэлі, вы "
"можаце проста перазагрузіць яе ў PrusaSlicer? Пстрыкніце <b>правай кнопкай " "можаце проста перазагрузіць яе ў PrusaSlicer? Пстрыкніце правай кнопкай "
"мышы</b> на мадэлі ў акне 3D-прагляду і абярыце <a>Перазагрузіць з дыска</" "мышы на мадэлі ў акне 3D-прагляду і абярыце Перазагрузіць з дыска"
"a>. Больш падрабязна чытайце ў дакументацыі." ". Больш падрабязна чытайце ў дакументацыі."
#: resources/data/hints.ini: [hint:Hiding sidebar] #: resources/data/hints.ini: [hint:Hiding sidebar]
msgid "" msgid ""
@ -17833,7 +17833,7 @@ msgid ""
"between predefined camera angles?" "between predefined camera angles?"
msgstr "" msgstr ""
"Выгляд з камеры\n" "Выгляд з камеры\n"
"Ці ведаеце вы, што вы можаце ўжываць лічбавыя клавішы <b>0</b>-<b>6</b>, каб " "Ці ведаеце вы, што вы можаце ўжываць лічбавыя клавішы <b>0-6</b>, каб "
"хутка пераключацца паміж папярэдне зададзенымі ракурсамі камеры?" "хутка пераключацца паміж папярэдне зададзенымі ракурсамі камеры?"
#: resources/data/hints.ini: [hint:Place on face] #: resources/data/hints.ini: [hint:Place on face]
@ -17855,7 +17855,7 @@ msgid ""
"instances instead of copy-pasting it several times?" "instances instead of copy-pasting it several times?"
msgstr "" msgstr ""
"Ужыць колькасць асобнікаў\n" "Ужыць колькасць асобнікаў\n"
"Ці ведаеце вы, што вы можаце пстрыкнуць <b>правай кнопкай мышы</b> на мадэлі " "Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на мадэлі "
"і задаць дакладную колькасць копіяў мадэлі замест таго, каб капіяваць і " "і задаць дакладную колькасць копіяў мадэлі замест таго, каб капіяваць і "
"ўстаўляць её некалькі разоў?" "ўстаўляць её некалькі разоў?"
@ -17890,7 +17890,7 @@ msgid ""
"history of changes and to undo or redo several actions at once?" "history of changes and to undo or redo several actions at once?"
msgstr "" msgstr ""
"Гісторыя адкаціць/зрабіць нанова\n" "Гісторыя адкаціць/зрабіць нанова\n"
"Ці ведаеце вы, вы можаце пстрыкнуць <b>правай кнопкай мышы</b> на <a>стрэлкі " "Ці ведаеце вы, вы можаце пстрыкнуць правай кнопкай мышы на <a>стрэлкі "
"адмены/паўтору</a>, каб праглядзець гісторыю змяненняў і адмяніць ці " "адмены/паўтору</a>, каб праглядзець гісторыю змяненняў і адмяніць ці "
"паўтарыць некалькі дзеянняў адначасова?" "паўтарыць некалькі дзеянняў адначасова?"
@ -17904,8 +17904,8 @@ msgid ""
msgstr "" msgstr ""
"Розная вышыня пластаў для кожнай мадэлі\n" "Розная вышыня пластаў для кожнай мадэлі\n"
"Ці ведаеце вы, што вы можаце надрукаваць кожную мадэль на стале з рознай " "Ці ведаеце вы, што вы можаце надрукаваць кожную мадэль на стале з рознай "
"вышынёй пластоў? Пстрыкніце <b>правай кнопкай мышы</b> на мадэлі ў акне 3D-" "вышынёй пластоў? Пстрыкніце правай кнопкай мышы на мадэлі ў акне 3D-"
"прагляду, абярыце <a>Пласты і перыметры</a>, наладзьце значэнні на правай " "прагляду, абярыце Пласты і перыметры, наладзьце значэнні на правай "
"панэлі. Больш падрабязна чытайце ў дакументацыі." "панэлі. Больш падрабязна чытайце ў дакументацыі."
#: resources/data/hints.ini: [hint:Solid infill threshold area] #: resources/data/hints.ini: [hint:Solid infill threshold area]
@ -17938,8 +17938,8 @@ msgid ""
"also box-deselect objects with <b>Alt+Mouse drag</b>." "also box-deselect objects with <b>Alt+Mouse drag</b>."
msgstr "" msgstr ""
"Выдзяленне прастакутнікам\n" "Выдзяленне прастакутнікам\n"
"Ці ведаеце вы, што вы можаце вылучыць поле з дапамогай <b>Shift + " "Ці ведаеце вы, што вы можаце вылучыць поле з дапамогай Shift + "
"перацягванне мышшу</b>? Вы так сама можаце адмяніць вылучэнне мадэляў з " "перацягванне мышшу? Вы так сама можаце адмяніць вылучэнне мадэляў з "
"дапамогай спалучэння клавішаў <b>Alt + перацягванне мышшу</b>." "дапамогай спалучэння клавішаў <b>Alt + перацягванне мышшу</b>."
#: resources/data/hints.ini: [hint:Zoom on selected objects or all if none #: resources/data/hints.ini: [hint:Zoom on selected objects or all if none
@ -17965,8 +17965,8 @@ msgstr ""
"Перамыкач для друку\n" "Перамыкач для друку\n"
"Ці ведаеце вы, што вы можаце адключыць стварэнне G-кода для абранай мадэлі, " "Ці ведаеце вы, што вы можаце адключыць стварэнне G-кода для абранай мадэлі, "
"без неабходнасці рухаць ці выдаляць яе? Пераключыце ўласцівасць мадэлі " "без неабходнасці рухаць ці выдаляць яе? Пераключыце ўласцівасць мадэлі "
"<a>Для друку</a> з кантэкстнага меню, калі пстрыкнуць <b>правай кнопкай " "Для друку з кантэкстнага меню, калі пстрыкнуць правай кнопкай "
"мышы</b>." "мышы."
#: resources/data/hints.ini: [hint:Mirror] #: resources/data/hints.ini: [hint:Mirror]
msgid "" msgid ""
@ -17976,8 +17976,8 @@ msgid ""
msgstr "" msgstr ""
"Люстраваць\n" "Люстраваць\n"
"Ці ведаеце вы, што вы можаце люстраваць абраную мадэль, каб стварыць яе " "Ці ведаеце вы, што вы можаце люстраваць абраную мадэль, каб стварыць яе "
"зваротную версію? Пстрыкніце <b>правай кнопкай мышы</b> на мадэль, абярыце " "зваротную версію? Пстрыкніце правай кнопкай мышы на мадэль, абярыце "
"<a>Люстраваць</a> і абярыце вось." "Люстраваць і абярыце вось."
#: resources/data/hints.ini: [hint:PageUp / PageDown quick rotation by 45 #: resources/data/hints.ini: [hint:PageUp / PageDown quick rotation by 45
#: degrees] #: degrees]
@ -18056,7 +18056,7 @@ msgid ""
msgstr "" msgstr ""
"Уставіць прыпынак\n" "Уставіць прыпынак\n"
"Ці ведаеце вы, што вы можаце запланаваць прыпынак друку на поэным пласту? " "Ці ведаеце вы, што вы можаце запланаваць прыпынак друку на поэным пласту? "
"Пстрыкніце <b>правай кнопкай мышы</b> на паўзунке пласта ў акне папярэдняга " "Пстрыкніце правай кнопкай мышы на паўзунке пласта ў акне папярэдняга "
"прагляду і абярыце \"Дадаць прыпынак друку\" (M601). Можна ўжываць для " "прагляду і абярыце \"Дадаць прыпынак друку\" (M601). Можна ўжываць для "
"ўстаўкі ў ўстаўкі магнітаў, грузікаў ці гаек увашыя мадэлі. Больш падрабязна " "ўстаўкі ў ўстаўкі магнітаў, грузікаў ці гаек увашыя мадэлі. Больш падрабязна "
"чытайце ў дакументацыі." "чытайце ў дакументацыі."
@ -18071,9 +18071,9 @@ msgid ""
msgstr "" msgstr ""
"Карыстальніцкі G-код\n" "Карыстальніцкі G-код\n"
"Ці ведаеце вы, што вы можаце ўставіць карыстальніцкі G-код на пэўным пласту? " "Ці ведаеце вы, што вы можаце ўставіць карыстальніцкі G-код на пэўным пласту? "
"Пстрыкніце <b>левай кнопкай мышы</b> на пласт у акне папярэдняга прагляду, " "Пстрыкніце левай кнопкай мышы на пласт у акне папярэдняга прагляду, "
"пстрыкніце <b>правай кнопкай мышы</b> гузік плюсу і абярыце <a>Дадаць " "пстрыкніце правай кнопкай мышы гузік плюсу і абярыце Дадаць "
"карыстальніцкі G-код</a>. З дапамогай гэтай функцыі можна, напрыклад, " "карыстальніцкі G-код. З дапамогай гэтай функцыі можна, напрыклад, "
"стварыць тэмпературную вежу. Больш падрабязна чытайце ў дакументацыі." "стварыць тэмпературную вежу. Больш падрабязна чытайце ў дакументацыі."
#: resources/data/hints.ini: [hint:Configuration snapshots] #: resources/data/hints.ini: [hint:Configuration snapshots]
@ -18111,8 +18111,8 @@ msgstr ""
"Налады ў асобным акне\n" "Налады ў асобным акне\n"
"Ці ведаеце вы, што вы можаце адчыніць налады ў новым немадальным акне? Гэта " "Ці ведаеце вы, што вы можаце адчыніць налады ў новым немадальным акне? Гэта "
"значыць, што налады можна адчыніць на адным экране, а папярэдні прагляд G-" "значыць, што налады можна адчыніць на адным экране, а папярэдні прагляд G-"
"кода на іншчым. Перайдзіце ў <a>Перавагі</a> і абярыце <a>Налады будуць " "кода на іншчым. Перайдзіце ў <a>Перавагі</a> і абярыце Налады будуць "
"адлюстроўвацца ў асобным акне</a>." "адлюстроўвацца ў асобным акне."
#: resources/data/hints.ini: [hint:Adaptive infills] #: resources/data/hints.ini: [hint:Adaptive infills]
msgid "" msgid ""
@ -19531,7 +19531,7 @@ msgstr "Колер фону"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:52 #: ../src/common/accelcmn.cpp:52
msgid "Backspace" msgid "Backspace"
msgstr "<b>Backspace</b>" msgstr "Backspace"
#: ../src/common/fmapbase.cpp:160 #: ../src/common/fmapbase.cpp:160
msgid "Baltic (ISO-8859-13)" msgid "Baltic (ISO-8859-13)"
@ -20904,7 +20904,7 @@ msgstr "Канец"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:55 #: ../src/common/accelcmn.cpp:55
msgid "Enter" msgid "Enter"
msgstr "<b>Enter</b>" msgstr "Enter"
#: ../src/richtext/richtextstyledlg.cpp:934 #: ../src/richtext/richtextstyledlg.cpp:934
msgid "Enter a box style name" msgid "Enter a box style name"
@ -20991,7 +20991,7 @@ msgstr "Памылка: "
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:69 #: ../src/common/accelcmn.cpp:69
msgid "Esc" msgid "Esc"
msgstr "<b>Esc</b>" msgstr "Esc"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:70 #: ../src/common/accelcmn.cpp:70
@ -22180,7 +22180,7 @@ msgstr "Ініцыялізацыя не атрымалася ў post init, пе
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:54 #: ../src/common/accelcmn.cpp:54
msgid "Ins" msgid "Ins"
msgstr "<b>Ins</b>" msgstr "Ins"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/richtext/richtextsymboldlg.cpp:472 ../src/common/accelcmn.cpp:53 #: ../src/richtext/richtextsymboldlg.cpp:472 ../src/common/accelcmn.cpp:53
@ -22879,7 +22879,7 @@ msgstr "&Згарнуць"
#. TRANSLATORS: System cursor name #. TRANSLATORS: System cursor name
#: ../src/propgrid/advprops.cpp:1763 #: ../src/propgrid/advprops.cpp:1763
msgid "Middle Button" msgid "Middle Button"
msgstr "<b>Сярэдняя кнопка</b>" msgstr "Сярэдняя кнопка"
#: ../src/richtext/richtextsizepage.cpp:409 #: ../src/richtext/richtextsizepage.cpp:409
msgid "Min height:" msgid "Min height:"
@ -23111,117 +23111,117 @@ msgstr "Заўвага, 8 1/2 x 11 цалі"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:105 #: ../src/common/accelcmn.cpp:105
msgid "Num *" msgid "Num *"
msgstr "<b>Num *</b>" msgstr "Num *"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:106 #: ../src/common/accelcmn.cpp:106
msgid "Num +" msgid "Num +"
msgstr "<b>Num +</b>" msgstr "Num +"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:107 #: ../src/common/accelcmn.cpp:107
msgid "Num ," msgid "Num ,"
msgstr "<b>Num ,</b>" msgstr "Num ,"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:108 #: ../src/common/accelcmn.cpp:108
msgid "Num -" msgid "Num -"
msgstr "<b>Num -</b>" msgstr "Num -"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:109 #: ../src/common/accelcmn.cpp:109
msgid "Num ." msgid "Num ."
msgstr "<b>Num .</b>" msgstr "Num ."
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:110 #: ../src/common/accelcmn.cpp:110
msgid "Num /" msgid "Num /"
msgstr "<b>Num /</b>" msgstr "Num /"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:104 #: ../src/common/accelcmn.cpp:104
msgid "Num =" msgid "Num ="
msgstr "<b>Num =</b>" msgstr "Num ="
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:101 #: ../src/common/accelcmn.cpp:101
msgid "Num Begin" msgid "Num Begin"
msgstr "<b>Num Begin</b>" msgstr "Num Begin"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:103 #: ../src/common/accelcmn.cpp:103
msgid "Num Delete" msgid "Num Delete"
msgstr "<b>Num Delete</b>" msgstr "Num Delete"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:95 #: ../src/common/accelcmn.cpp:95
msgid "Num Down" msgid "Num Down"
msgstr "<b>Num Down</b>" msgstr "Num Down"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:100 #: ../src/common/accelcmn.cpp:100
msgid "Num End" msgid "Num End"
msgstr "<b>Num End</b>" msgstr "Num End"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:90 #: ../src/common/accelcmn.cpp:90
msgid "Num Enter" msgid "Num Enter"
msgstr "<b>Num Enter</b>" msgstr "Num Enter"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:91 #: ../src/common/accelcmn.cpp:91
msgid "Num Home" msgid "Num Home"
msgstr "<b>Num Home</b>" msgstr "Num Home"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:102 #: ../src/common/accelcmn.cpp:102
msgid "Num Insert" msgid "Num Insert"
msgstr "<b>Num Insert</b>" msgstr "Num Insert"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:86 #: ../src/common/accelcmn.cpp:86
msgid "Num Lock" msgid "Num Lock"
msgstr "<b>Num Lock</b>" msgstr "Num Lock"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:97 #: ../src/common/accelcmn.cpp:97
msgid "Num Page Down" msgid "Num Page Down"
msgstr "<b>Num Page Down</b>" msgstr "Num Page Down"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:96 #: ../src/common/accelcmn.cpp:96
msgid "Num Page Up" msgid "Num Page Up"
msgstr "<b>Num Page Up</b>" msgstr "Num Page Up"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:94 #: ../src/common/accelcmn.cpp:94
msgid "Num Right" msgid "Num Right"
msgstr "<b>Num Right</b>" msgstr "Num Right"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:88 #: ../src/common/accelcmn.cpp:88
msgid "Num Space" msgid "Num Space"
msgstr "<b>Num Space</b>" msgstr "Num Space"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:89 #: ../src/common/accelcmn.cpp:89
msgid "Num Tab" msgid "Num Tab"
msgstr "<b>Num Tab</b>" msgstr "Num Tab"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:93 #: ../src/common/accelcmn.cpp:93
msgid "Num Up" msgid "Num Up"
msgstr "<b>Num Up</b>" msgstr "Num Up"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:92 #: ../src/common/accelcmn.cpp:92
msgid "Num left" msgid "Num left"
msgstr "<b>Num left</b>" msgstr "Num left"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:86 #: ../src/common/accelcmn.cpp:86
msgid "Num_lock" msgid "Num_lock"
msgstr "<b>Num_lock</b>" msgstr "Num_lock"
#: ../src/richtext/richtextliststylepage.cpp:487 #: ../src/richtext/richtextliststylepage.cpp:487
#: ../src/richtext/richtextbulletspage.cpp:279 #: ../src/richtext/richtextbulletspage.cpp:279
@ -23490,12 +23490,12 @@ msgstr "Налады старонкі"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:58 #: ../src/common/accelcmn.cpp:58
msgid "PageDown" msgid "PageDown"
msgstr "<b>PageDown</b>" msgstr "PageDown"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:57 #: ../src/common/accelcmn.cpp:57
msgid "PageUp" msgid "PageUp"
msgstr "<b>PageUp</b>" msgstr "PageUp"
#: ../src/generic/prntdlgg.cpp:216 #: ../src/generic/prntdlgg.cpp:216
msgid "Pages" msgid "Pages"
@ -23545,12 +23545,12 @@ msgstr "Дазволы"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:60 #: ../src/common/accelcmn.cpp:60
msgid "PgDn" msgid "PgDn"
msgstr "<b>PgDn</b>" msgstr "PgDn"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:59 #: ../src/common/accelcmn.cpp:59
msgid "PgUp" msgid "PgUp"
msgstr "<b>PgUp</b>" msgstr "PgUp"
#: ../src/richtext/richtextbuffer.cpp:12868 #: ../src/richtext/richtextbuffer.cpp:12868
msgid "Picture Properties" msgid "Picture Properties"
@ -25636,17 +25636,17 @@ msgstr "Кірыліца Windows/DOS OEM (CP 866)"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:111 #: ../src/common/accelcmn.cpp:111
msgid "Windows_Left" msgid "Windows_Left"
msgstr "<b>Windows_Left</b>" msgstr "Windows_Left"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:113 #: ../src/common/accelcmn.cpp:113
msgid "Windows_Menu" msgid "Windows_Menu"
msgstr "<b>Windows_Menu</b>" msgstr "Windows_Menu"
#. TRANSLATORS: Name of keyboard key #. TRANSLATORS: Name of keyboard key
#: ../src/common/accelcmn.cpp:112 #: ../src/common/accelcmn.cpp:112
msgid "Windows_Right" msgid "Windows_Right"
msgstr "<b>Windows_Right</b>" msgstr "Windows_Right"
#: ../src/common/ffile.cpp:150 #: ../src/common/ffile.cpp:150
#, c-format #, c-format
@ -25709,7 +25709,7 @@ msgstr "Вы не можаце дадаць новы каталог у гэту
#: ../src/propgrid/propgrid.cpp:3299 #: ../src/propgrid/propgrid.cpp:3299
msgid "You have entered invalid value. Press ESC to cancel editing." msgid "You have entered invalid value. Press ESC to cancel editing."
msgstr "" msgstr ""
"Вы ўвялі недапушчальнае значэнне. Націсніце <b>Esc</b>, каб адмяніць змены." "Вы ўвялі недапушчальнае значэнне. Націсніце ESC, каб адмяніць змены."
#: ../src/common/stockitem.cpp:209 #: ../src/common/stockitem.cpp:209
msgid "Zoom &In" msgid "Zoom &In"

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.6.0-beta2 min_slic3r_version = 2.6.0-beta2
1.9.0 Bumped up configuration version.
1.9.0-beta3 Updated start g-code for MK4 (modified purge line and nozzle cleaning). 1.9.0-beta3 Updated start g-code for MK4 (modified purge line and nozzle cleaning).
1.9.0-beta2 Added profiles for Original Prusa MK4 Input Shaper (Alpha). 1.9.0-beta2 Added profiles for Original Prusa MK4 Input Shaper (Alpha).
min_slic3r_version = 2.6.0-beta0 min_slic3r_version = 2.6.0-beta0

View File

@ -5,7 +5,7 @@
name = Prusa Research name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs. # Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded. # This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 1.9.0-beta3 config_version = 1.9.0
# Where to get the updates from? # Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/ config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -755,5 +755,21 @@ void arrange(ArrangePolygons &items,
} }
} }
BoundingBox bounding_box(const InfiniteBed &bed)
{
BoundingBox ret;
using C = coord_t;
// It is important for Mx and My to be strictly less than half of the
// range of type C. width(), height() and area() will not overflow this way.
C Mx = C((std::numeric_limits<C>::lowest() + 2 * bed.center.x()) / 4.01);
C My = C((std::numeric_limits<C>::lowest() + 2 * bed.center.y()) / 4.01);
ret.max = bed.center - Point{Mx, My};
ret.min = bed.center + Point{Mx, My};
return ret;
}
} // namespace arr } // namespace arr
} // namespace Slic3r } // namespace Slic3r

View File

@ -55,6 +55,25 @@ struct IrregularBed {
using ArrangeBed = boost::variant<InfiniteBed, RectangleBed, CircleBed, SegmentedRectangleBed, IrregularBed>; using ArrangeBed = boost::variant<InfiniteBed, RectangleBed, CircleBed, SegmentedRectangleBed, IrregularBed>;
BoundingBox bounding_box(const InfiniteBed &bed);
inline BoundingBox bounding_box(const RectangleBed &b) { return b.bb; }
inline BoundingBox bounding_box(const SegmentedRectangleBed &b) { return b.bb; }
inline BoundingBox bounding_box(const CircleBed &b)
{
auto r = static_cast<coord_t>(std::round(b.radius()));
Point R{r, r};
return {b.center() - R, b.center() + R};
}
inline BoundingBox bounding_box(const ArrangeBed &b)
{
BoundingBox ret;
auto visitor = [&ret](const auto &b) { ret = bounding_box(b); };
boost::apply_visitor(visitor, b);
return ret;
}
ArrangeBed to_arrange_bed(const Points &bedpts); ArrangeBed to_arrange_bed(const Points &bedpts);
/// A logical bed representing an object not being arranged. Either the arrange /// A logical bed representing an object not being arranged. Either the arrange

View File

@ -1065,6 +1065,9 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
apply_config_superslicer(filename); apply_config_superslicer(filename);
else if (m_producer == EProducer::KissSlicer) else if (m_producer == EProducer::KissSlicer)
apply_config_kissslicer(filename); apply_config_kissslicer(filename);
if (m_result.extruders_count == 0)
m_result.extruders_count = MIN_EXTRUDERS_COUNT;
} }
} }
@ -2352,28 +2355,58 @@ void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line)
} }
void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
{
std::array<std::optional<double>, 4> g1_axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt };
if (line.has_x()) g1_axes[X] = (double)line.x();
if (line.has_y()) g1_axes[Y] = (double)line.y();
if (line.has_z()) g1_axes[Z] = (double)line.z();
if (line.has_e()) g1_axes[E] = (double)line.e();
std::optional<double> g1_feedrate = std::nullopt;
if (line.has_f()) g1_feedrate = (double)line.f();
std::optional<std::string> g1_cmt = std::nullopt;
if (!line.comment().empty()) g1_cmt = line.comment();
process_G1(g1_axes, g1_feedrate, g1_cmt);
}
void GCodeProcessor::process_G1(const std::array<std::optional<double>, 4>& axes, std::optional<double> feedrate, std::optional<std::string> cmt)
{ {
const float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back(); const float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back();
const float filament_radius = 0.5f * filament_diameter; const float filament_radius = 0.5f * filament_diameter;
const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius); const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
auto move_type = [this](const AxisCoords& delta_pos) { auto move_type = [this](const AxisCoords& delta_pos) {
EMoveType type = EMoveType::Noop;
if (m_wiping) if (m_wiping)
type = EMoveType::Wipe; return EMoveType::Wipe;
else if (delta_pos[E] < 0.0f) else if (delta_pos[E] < 0.0f)
type = (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : EMoveType::Retract; return (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : EMoveType::Retract;
else if (delta_pos[E] > 0.0f) { else if (delta_pos[E] > 0.0f) {
if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f) if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f)
type = (delta_pos[Z] == 0.0f) ? EMoveType::Unretract : EMoveType::Travel; return (delta_pos[Z] == 0.0f) ? EMoveType::Unretract : EMoveType::Travel;
else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f) else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f)
type = EMoveType::Extrude; return EMoveType::Extrude;
} }
else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f)
type = EMoveType::Travel; return EMoveType::Travel;
return type; return EMoveType::Noop;
};
auto extract_absolute_position_on_axis = [&](Axis axis, std::optional<double> value, double area_filament_cross_section)
{
if (value.has_value()) {
bool is_relative = (m_global_positioning_type == EPositioningType::Relative);
if (axis == E)
is_relative |= (m_e_local_positioning_type == EPositioningType::Relative);
const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0;
double ret = *value * lengthsScaleFactor;
if (axis == E && m_use_volumetric_e)
ret /= area_filament_cross_section;
return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret;
}
else
return m_start_position[axis];
}; };
++m_g1_line_id; ++m_g1_line_id;
@ -2383,27 +2416,26 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// updates axes positions from line // updates axes positions from line
for (unsigned char a = X; a <= E; ++a) { for (unsigned char a = X; a <= E; ++a) {
m_end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section)); m_end_position[a] = extract_absolute_position_on_axis((Axis)a, axes[a], double(area_filament_cross_section));
} }
// updates feedrate from line, if present // updates feedrate from line, if present
if (line.has_f()) if (feedrate.has_value())
m_feedrate = m_feed_multiply.current * line.f() * MMMIN_TO_MMSEC; m_feedrate = m_feed_multiply.current * (*feedrate) * MMMIN_TO_MMSEC;
// calculates movement deltas // calculates movement deltas
AxisCoords delta_pos; AxisCoords delta_pos;
for (unsigned char a = X; a <= E; ++a) for (unsigned char a = X; a <= E; ++a)
delta_pos[a] = m_end_position[a] - m_start_position[a]; delta_pos[a] = m_end_position[a] - m_start_position[a];
if (std::all_of(delta_pos.begin(), delta_pos.end(), [](double d) { return d == 0.; })) if (std::all_of(delta_pos.begin(), delta_pos.end(), [](double d) { return d == 0.; }))
return; return;
const float volume_extruded_filament = area_filament_cross_section * delta_pos[E]; const float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
if (volume_extruded_filament != 0.) if (volume_extruded_filament != 0.)
m_used_filaments.increase_caches(volume_extruded_filament, m_used_filaments.increase_caches(volume_extruded_filament, m_extruder_id, area_filament_cross_section * m_parking_position,
m_extruder_id, area_filament_cross_section * m_parking_position, area_filament_cross_section * m_extra_loading_move);
area_filament_cross_section * m_extra_loading_move);
const EMoveType type = move_type(delta_pos); const EMoveType type = move_type(delta_pos);
if (type == EMoveType::Extrude) { if (type == EMoveType::Extrude) {
@ -2420,7 +2452,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
m_height = m_forced_height; m_height = m_forced_height;
else if (m_layer_id == 0) else if (m_layer_id == 0)
m_height = m_first_layer_height + m_z_offset; m_height = m_first_layer_height + m_z_offset;
else if (line.comment() != INTERNAL_G2G3_TAG){ else if (!cmt.has_value() || *cmt != INTERNAL_G2G3_TAG) {
if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0) if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0)
m_height = m_end_position[Z] - m_extruded_last_z; m_height = m_end_position[Z] - m_extruded_last_z;
} }
@ -2431,7 +2463,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_end_position[Z] == 0.0f || (m_extrusion_role == GCodeExtrusionRole::Custom && m_layer_id == 0)) if (m_end_position[Z] == 0.0f || (m_extrusion_role == GCodeExtrusionRole::Custom && m_layer_id == 0))
m_end_position[Z] = m_height; m_end_position[Z] = m_height;
if (line.comment() != INTERNAL_G2G3_TAG) if (!cmt.has_value() || *cmt != INTERNAL_G2G3_TAG)
m_extruded_last_z = m_end_position[Z]; m_extruded_last_z = m_end_position[Z];
m_options_z_corrector.update(m_height); m_options_z_corrector.update(m_height);
@ -2464,7 +2496,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// time estimate section // time estimate section
auto move_length = [](const AxisCoords& delta_pos) { auto move_length = [](const AxisCoords& delta_pos) {
float sq_xyz_length = sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]); const float sq_xyz_length = sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]);
return (sq_xyz_length > 0.0f) ? std::sqrt(sq_xyz_length) : std::abs(delta_pos[E]); return (sq_xyz_length > 0.0f) ? std::sqrt(sq_xyz_length) : std::abs(delta_pos[E]);
}; };
@ -2485,8 +2517,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
TimeMachine::State& prev = machine.prev; TimeMachine::State& prev = machine.prev;
std::vector<TimeBlock>& blocks = machine.blocks; std::vector<TimeBlock>& blocks = machine.blocks;
curr.feedrate = (delta_pos[E] == 0.0f) ? curr.feedrate = (delta_pos[E] == 0.0f) ? minimum_travel_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), m_feedrate) :
minimum_travel_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), m_feedrate) :
minimum_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), m_feedrate); minimum_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), m_feedrate);
TimeBlock block; TimeBlock block;
@ -2521,11 +2552,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
} }
// calculates block acceleration // calculates block acceleration
float acceleration = float acceleration = (type == EMoveType::Travel) ? get_travel_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) :
(type == EMoveType::Travel) ? get_travel_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) : (is_extrusion_only_move(delta_pos) ? get_retract_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) :
(is_extrusion_only_move(delta_pos) ? get_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)));
get_retract_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)) :
get_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)));
for (unsigned char a = X; a <= E; ++a) { for (unsigned char a = X; a <= E; ++a) {
const float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a)); const float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
@ -2551,8 +2580,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// calculates block entry feedrate // calculates block entry feedrate
float vmax_junction = curr.safe_feedrate; float vmax_junction = curr.safe_feedrate;
if (!blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD) { if (!blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD) {
bool prev_speed_larger = prev.feedrate > block.feedrate_profile.cruise; const bool prev_speed_larger = prev.feedrate > block.feedrate_profile.cruise;
float smaller_speed_factor = prev_speed_larger ? (block.feedrate_profile.cruise / prev.feedrate) : (prev.feedrate / block.feedrate_profile.cruise); const float smaller_speed_factor = prev_speed_larger ? (block.feedrate_profile.cruise / prev.feedrate) : (prev.feedrate / block.feedrate_profile.cruise);
// Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting.
vmax_junction = prev_speed_larger ? block.feedrate_profile.cruise : prev.feedrate; vmax_junction = prev_speed_larger ? block.feedrate_profile.cruise : prev.feedrate;
@ -2574,18 +2603,18 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. // Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction.
const float jerk = const float jerk =
(v_exit > v_entry) ? (v_exit > v_entry) ?
((v_entry > 0.0f || v_exit < 0.0f) ? ((v_entry > 0.0f || v_exit < 0.0f) ?
// coasting // coasting
(v_exit - v_entry) : (v_exit - v_entry) :
// axis reversal // axis reversal
std::max(v_exit, -v_entry)) : std::max(v_exit, -v_entry)) :
// v_exit <= v_entry // v_exit <= v_entry
((v_entry < 0.0f || v_exit > 0.0f) ? ((v_entry < 0.0f || v_exit > 0.0f) ?
// coasting // coasting
(v_entry - v_exit) : (v_entry - v_exit) :
// axis reversal // axis reversal
std::max(-v_exit, v_entry)); std::max(-v_exit, v_entry));
const float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a)); const float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
if (jerk > axis_max_jerk) { if (jerk > axis_max_jerk) {
@ -2664,7 +2693,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
} }
// store move // store move
store_move_vertex(type, line.comment() == INTERNAL_G2G3_TAG); store_move_vertex(type, cmt.has_value() && *cmt == INTERNAL_G2G3_TAG);
} }
void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise) void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise)
@ -2693,7 +2722,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
double delta_z() const { return end.z() - start.z(); } double delta_z() const { return end.z() - start.z(); }
double length() const { return angle * start_radius(); } double length() const { return angle * start_radius(); }
double travel_length() const { return std::sqrt(sqr(length() + sqr(delta_z()))); } double travel_length() const { return std::sqrt(sqr(length()) + sqr(delta_z())); }
double start_radius() const { return (start - center).norm(); } double start_radius() const { return (start - center).norm(); }
double end_radius() const { return (end - center).norm(); } double end_radius() const { return (end - center).norm(); }
@ -2778,18 +2807,18 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
return ret; return ret;
}; };
auto internal_only_g1_line = [](const AxisCoords& target, bool has_z, const std::optional<float>& feedrate, const std::optional<float>& extrusion) { auto internal_only_g1_line = [this](const AxisCoords& target, bool has_z, const std::optional<float>& feedrate, const std::optional<float>& extrusion) {
std::string ret = (boost::format("G1 X%1% Y%2%") % target[X] % target[Y]).str(); std::array<std::optional<double>, 4> g1_axes = { target[X], target[Y], std::nullopt, std::nullopt };
std::optional<double> g1_feedrate = std::nullopt;
if (has_z) if (has_z)
ret += (boost::format(" Z%1%") % target[Z]).str(); g1_axes[Z] = target[Z];
if (feedrate.has_value()) if (feedrate.has_value())
ret += (boost::format(" F%1%") % *feedrate).str(); g1_feedrate = (double)*feedrate;
if (extrusion.has_value()) if (extrusion.has_value())
ret += (boost::format(" E%1%") % target[E]).str(); g1_axes[E] = target[E];
std::optional<std::string> g1_cmt = INTERNAL_G2G3_TAG;
ret += (boost::format(" ;%1%\n") % INTERNAL_G2G3_TAG).str(); process_G1(g1_axes, g1_feedrate, g1_cmt);
return ret;
}; };
// calculate arc segments // calculate arc segments
@ -2798,17 +2827,16 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
// https://github.com/prusa3d/Prusa-Firmware/blob/MK3/Firmware/motion_control.cpp // https://github.com/prusa3d/Prusa-Firmware/blob/MK3/Firmware/motion_control.cpp
// segments count // segments count
static const double MM_PER_ARC_SEGMENT = 0.5; static const double MM_PER_ARC_SEGMENT = 1.0;
const size_t segments = std::ceil(travel_length / MM_PER_ARC_SEGMENT); const size_t segments = std::max<size_t>(std::floor(travel_length / MM_PER_ARC_SEGMENT), 1);
assert(segments >= 1);
const double theta_per_segment = arc.angle / double(segments); const double inv_segment = 1.0 / double(segments);
const double z_per_segment = arc.delta_z() / double(segments); const double theta_per_segment = arc.angle * inv_segment;
const double extruder_per_segment = (extrusion.has_value()) ? *extrusion / double(segments) : 0.0; const double z_per_segment = arc.delta_z() * inv_segment;
const double extruder_per_segment = (extrusion.has_value()) ? *extrusion * inv_segment : 0.0;
const double sq_theta_per_segment = sqr(theta_per_segment); const double cos_T = 1.0 - 0.5 * sqr(theta_per_segment); // Small angle approximation
const double cos_T = 1.0 - 0.5 * sq_theta_per_segment; // Small angle approximation const double sin_T = theta_per_segment;
const double sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6.0; // Small angle approximation
AxisCoords prev_target = m_start_position; AxisCoords prev_target = m_start_position;
AxisCoords arc_target; AxisCoords arc_target;
@ -2820,28 +2848,25 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
arc_target[E] = m_start_position[E]; arc_target[E] = m_start_position[E];
static const size_t N_ARC_CORRECTION = 25; static const size_t N_ARC_CORRECTION = 25;
Vec3d curr_rel_arc_start = arc.relative_start(); Vec3d curr_rel_arc_start = arc.relative_start();
size_t count = 0;
std::string gcode;
size_t n_arc_correction = N_ARC_CORRECTION;
for (size_t i = 1; i < segments; ++i) { for (size_t i = 1; i < segments; ++i) {
if (n_arc_correction-- == 0) { if (count < N_ARC_CORRECTION) {
// Calculate the actual position for r_axis_x and r_axis_y // Apply vector rotation matrix
const double cos_Ti = ::cos((double)i * theta_per_segment);
const double sin_Ti = ::sin((double)i * theta_per_segment);
curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti;
curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti;
// reset n_arc_correction
n_arc_correction = N_ARC_CORRECTION;
}
else {
// Calculate X and Y using the small angle approximation
const float r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T; const float r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T;
curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T; curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T;
curr_rel_arc_start.y() = r_axisi; curr_rel_arc_start.y() = r_axisi;
++count;
}
else {
// Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
const double cos_Ti = ::cos(i * theta_per_segment);
const double sin_Ti = ::sin(i * theta_per_segment);
curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti;
curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti;
count = 0;
} }
// Update arc_target location // Update arc_target location
@ -2850,23 +2875,14 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
arc_target[Z] += z_per_segment; arc_target[Z] += z_per_segment;
arc_target[E] += extruder_per_segment; arc_target[E] += extruder_per_segment;
gcode += internal_only_g1_line(adjust_target(arc_target, prev_target), z_per_segment != 0.0, feedrate, extrusion); m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line()
internal_only_g1_line(adjust_target(arc_target, prev_target), z_per_segment != 0.0, (i == 1) ? feedrate : std::nullopt, extrusion);
prev_target = arc_target; prev_target = arc_target;
// feedrate is constant, we do not need to repeat it
feedrate.reset();
} }
// Ensure last segment arrives at target location. // Ensure last segment arrives at target location.
gcode += internal_only_g1_line(adjust_target(end_position, prev_target), arc.delta_z() != 0.0, feedrate, extrusion); m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line()
internal_only_g1_line(adjust_target(end_position, prev_target), arc.delta_z() != 0.0, (segments == 1) ? feedrate : std::nullopt, extrusion);
// process fake gcode lines
GCodeReader parser;
parser.parse_buffer(gcode, [this](GCodeReader&, const GCodeReader::GCodeLine& line) {
// force all lines to share the same id
--m_line_id;
process_gcode_line(line, false);
});
} }
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)

View File

@ -680,6 +680,8 @@ namespace Slic3r {
// Move // Move
void process_G0(const GCodeReader::GCodeLine& line); void process_G0(const GCodeReader::GCodeLine& line);
void process_G1(const GCodeReader::GCodeLine& line); void process_G1(const GCodeReader::GCodeLine& line);
void process_G1(const std::array<std::optional<double>, 4>& axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt },
std::optional<double> feedrate = std::nullopt, std::optional<std::string> cmt = std::nullopt);
// Arc Move // Arc Move
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise); void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);

View File

@ -276,7 +276,7 @@ Surfaces expand_bridges_detect_orientations(
for (; it_bridge_anchor != bridge_anchors.end() && it_bridge_anchor->src == bridge_id; ++ it_bridge_anchor) { for (; it_bridge_anchor != bridge_anchors.end() && it_bridge_anchor->src == bridge_id; ++ it_bridge_anchor) {
if (last_anchor_id != int(it_bridge_anchor->boundary)) { if (last_anchor_id != int(it_bridge_anchor->boundary)) {
last_anchor_id = int(it_bridge_anchor->boundary); last_anchor_id = int(it_bridge_anchor->boundary);
append(anchor_areas, to_polygons(last_anchor_id < int32_t(shells.size()) ? shells[last_anchor_id] : sparse[last_anchor_id])); append(anchor_areas, to_polygons(last_anchor_id < int32_t(shells.size()) ? shells[last_anchor_id] : sparse[last_anchor_id - int32_t(shells.size())]));
} }
// if (Points &polyline = it_bridge_anchor->path; polyline.size() >= 2) { // if (Points &polyline = it_bridge_anchor->path; polyline.size() >= 2) {
// reserve_more_power_of_2(lines, polyline.size() - 1); // reserve_more_power_of_2(lines, polyline.size() - 1);

View File

@ -509,6 +509,8 @@ public:
bool has_solid_mesh() const; bool has_solid_mesh() const;
// Detect if object has at least one negative volume mash // Detect if object has at least one negative volume mash
bool has_negative_volume_mesh() const; bool has_negative_volume_mesh() const;
// Detect if object has at least one sla drain hole
bool has_sla_drain_holes() const { return !sla_drain_holes.empty(); }
bool is_cut() const { return cut_id.id().valid(); } bool is_cut() const { return cut_id.id().valid(); }
bool has_connectors() const; bool has_connectors() const;

View File

@ -2240,7 +2240,7 @@ namespace PresetUtils {
{ {
const VendorProfile::PrinterModel *out = nullptr; const VendorProfile::PrinterModel *out = nullptr;
if (preset.vendor != nullptr) { if (preset.vendor != nullptr) {
auto *printer_model = preset.config.opt<ConfigOptionString>("printer_model"); const auto *printer_model = preset.config.opt<ConfigOptionString>("printer_model");
if (printer_model != nullptr && ! printer_model->value.empty()) { if (printer_model != nullptr && ! printer_model->value.empty()) {
auto it = std::find_if(preset.vendor->models.begin(), preset.vendor->models.end(), [printer_model](const VendorProfile::PrinterModel &pm) { return pm.id == printer_model->value; }); auto it = std::find_if(preset.vendor->models.begin(), preset.vendor->models.end(), [printer_model](const VendorProfile::PrinterModel &pm) { return pm.id == printer_model->value; });
if (it != preset.vendor->models.end()) if (it != preset.vendor->models.end())

View File

@ -211,6 +211,12 @@ bool is_main_thread_active()
return get_main_thread_id() == boost::this_thread::get_id(); return get_main_thread_id() == boost::this_thread::get_id();
} }
static thread_local ThreadData s_thread_data;
ThreadData& thread_data()
{
return s_thread_data;
}
// Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID. // Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID.
// Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator. // Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator.
void name_tbb_thread_pool_threads_set_locale() void name_tbb_thread_pool_threads_set_locale()
@ -274,16 +280,16 @@ void set_current_thread_qos()
#endif // __APPLE__ #endif // __APPLE__
} }
void TBBLocalesSetter::on_scheduler_entry(bool is_worker) void ThreadData::tbb_worker_thread_set_c_locales()
{ {
// static std::atomic<int> cnt = 0; // static std::atomic<int> cnt = 0;
// std::cout << "TBBLocalesSetter Entering " << cnt ++ << " ID " << std::this_thread::get_id() << "\n"; // std::cout << "TBBLocalesSetter Entering " << cnt ++ << " ID " << std::this_thread::get_id() << "\n";
if (bool& is_locales_sets = m_is_locales_sets.local(); !is_locales_sets) { if (! m_tbb_worker_thread_c_locales_set) {
// Set locales of the worker thread to "C". // Set locales of the worker thread to "C".
set_c_locales(); set_c_locales();
// OSX specific: Elevate QOS on Apple Silicon. // OSX specific: Elevate QOS on Apple Silicon.
set_current_thread_qos(); set_current_thread_qos();
is_locales_sets = true; m_tbb_worker_thread_c_locales_set = true;
} }
} }

View File

@ -4,6 +4,7 @@
#include <utility> #include <utility>
#include <string> #include <string>
#include <thread> #include <thread>
#include <random>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <tbb/task_scheduler_observer.h> #include <tbb/task_scheduler_observer.h>
@ -67,6 +68,27 @@ template<class Fn> inline boost::thread create_thread(Fn &&fn)
return create_thread(attrs, std::forward<Fn>(fn)); return create_thread(attrs, std::forward<Fn>(fn));
} }
class ThreadData {
public:
std::mt19937& random_generator() {
if (! m_random_generator_initialized) {
std::random_device rd;
m_random_generator.seed(rd());
m_random_generator_initialized = true;
}
return m_random_generator;
}
void tbb_worker_thread_set_c_locales();
private:
std::mt19937 m_random_generator;
bool m_random_generator_initialized { false };
bool m_tbb_worker_thread_c_locales_set { false };
};
ThreadData& thread_data();
// For unknown reasons and in sporadic cases when GCode export is processing, some participating thread // For unknown reasons and in sporadic cases when GCode export is processing, some participating thread
// in tbb::parallel_pipeline has not set locales to "C", probably because this thread is newly spawned. // in tbb::parallel_pipeline has not set locales to "C", probably because this thread is newly spawned.
// So in this class method on_scheduler_entry is called for every thread before it starts participating // So in this class method on_scheduler_entry is called for every thread before it starts participating
@ -79,11 +101,7 @@ class TBBLocalesSetter : public tbb::task_scheduler_observer
public: public:
TBBLocalesSetter() { this->observe(true); } TBBLocalesSetter() { this->observe(true); }
~TBBLocalesSetter() override { this->observe(false); }; ~TBBLocalesSetter() override { this->observe(false); };
void on_scheduler_entry(bool /* is_worker */) override { thread_data().tbb_worker_thread_set_c_locales(); }
void on_scheduler_entry(bool is_worker) override;
private:
tbb::enumerable_thread_specific<bool, tbb::cache_aligned_allocator<bool>, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{ false };
}; };
} }

View File

@ -1162,6 +1162,10 @@ static bool object_contains_negative_volumes(const Model& model, int obj_id) {
return (0 <= obj_id && obj_id < (int)model.objects.size()) ? model.objects[obj_id]->has_negative_volume_mesh() : false; return (0 <= obj_id && obj_id < (int)model.objects.size()) ? model.objects[obj_id]->has_negative_volume_mesh() : false;
} }
static bool object_has_sla_drain_holes(const Model& model, int obj_id) {
return (0 <= obj_id && obj_id < (int)model.objects.size()) ? model.objects[obj_id]->has_sla_drain_holes() : false;
}
void GLCanvas3D::SLAView::detect_type_from_volumes(const GLVolumePtrs& volumes) void GLCanvas3D::SLAView::detect_type_from_volumes(const GLVolumePtrs& volumes)
{ {
for (auto& [id, type] : m_instances_cache) { for (auto& [id, type] : m_instances_cache) {
@ -1170,7 +1174,8 @@ void GLCanvas3D::SLAView::detect_type_from_volumes(const GLVolumePtrs& volumes)
for (const GLVolume* v : volumes) { for (const GLVolume* v : volumes) {
if (v->volume_idx() == -(int)slaposDrillHoles) { if (v->volume_idx() == -(int)slaposDrillHoles) {
if (object_contains_negative_volumes(*m_parent.get_model(), v->composite_id.object_id)) { if (object_contains_negative_volumes(*m_parent.get_model(), v->composite_id.object_id) ||
object_has_sla_drain_holes(*m_parent.get_model(), v->composite_id.object_id)) {
const InstancesCacheItem* instance = find_instance_item(v->composite_id); const InstancesCacheItem* instance = find_instance_item(v->composite_id);
assert(instance != nullptr); assert(instance != nullptr);
set_type(instance->first, ESLAViewType::Processed); set_type(instance->first, ESLAViewType::Processed);
@ -4687,6 +4692,13 @@ std::pair<SlicingParameters, const std::vector<double>> GLCanvas3D::get_layers_h
return ret; return ret;
} }
void GLCanvas3D::detect_sla_view_type()
{
m_sla_view.detect_type_from_volumes(m_volumes.volumes);
m_sla_view.update_volumes_visibility(m_volumes.volumes);
m_dirty = true;
}
void GLCanvas3D::set_sla_view_type(ESLAViewType type) void GLCanvas3D::set_sla_view_type(ESLAViewType type)
{ {
m_sla_view.set_type(type); m_sla_view.set_type(type);

View File

@ -1005,6 +1005,7 @@ public:
std::pair<SlicingParameters, const std::vector<double>> get_layers_height_data(int object_id); std::pair<SlicingParameters, const std::vector<double>> get_layers_height_data(int object_id);
void detect_sla_view_type();
void set_sla_view_type(ESLAViewType type); void set_sla_view_type(ESLAViewType type);
void set_sla_view_type(const GLVolume::CompositeID& id, ESLAViewType type); void set_sla_view_type(const GLVolume::CompositeID& id, ESLAViewType type);
void enable_sla_view_type_detection() { m_sla_view_type_detection_active = true; } void enable_sla_view_type_detection() { m_sla_view_type_detection_active = true; }

View File

@ -2281,14 +2281,7 @@ bool GUI_App::load_language(wxString language, bool initial)
} }
#endif #endif
#ifdef __APPLE__
// ysFIXME after fix for wxWidgets issue (https://github.com/wxWidgets/wxWidgets/issues/23209)
// Workaround for wxLANGUAGE_CHINESE(...) languages => Allow to continue even if wxLocale is not available.
// Because of translation will works fine, just locales will set to EN
if (! wxLocale::IsAvailable(language_info->Language) && language_info->CanonicalName.BeforeFirst('_') != "zh" ) {
#else
if (! wxLocale::IsAvailable(language_info->Language)) { if (! wxLocale::IsAvailable(language_info->Language)) {
#endif
// Loading the language dictionary failed. // Loading the language dictionary failed.
wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed."; wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed.";
#if !defined(_WIN32) && !defined(__APPLE__) #if !defined(_WIN32) && !defined(__APPLE__)

View File

@ -855,6 +855,7 @@ void GLGizmoSlaSupports::on_set_state()
m_old_mo_id = -1; m_old_mo_id = -1;
} }
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
m_c->instances_hider()->set_hide_full_scene(false); m_c->instances_hider()->set_hide_full_scene(false);
m_c->selection_info()->set_use_shift(false); // see top of on_render for details m_c->selection_info()->set_use_shift(false); // see top of on_render for details

View File

@ -960,6 +960,8 @@ bool GLGizmosManager::activate_gizmo(EType type)
if (type == Undefined) { if (type == Undefined) {
// it is deactivation of gizmo // it is deactivation of gizmo
m_current = Undefined; m_current = Undefined;
if (m_parent.current_printer_technology() == ptSLA)
m_parent.detect_sla_view_type();
return true; return true;
} }

View File

@ -99,7 +99,6 @@ void ArrangeJob::prepare_selected() {
clear_input(); clear_input();
Model &model = m_plater->model(); Model &model = m_plater->model();
double stride = bed_stride(m_plater);
std::vector<const Selection::InstanceIdxsList *> std::vector<const Selection::InstanceIdxsList *>
obj_sel(model.objects.size(), nullptr); obj_sel(model.objects.size(), nullptr);
@ -143,12 +142,6 @@ void ArrangeJob::prepare_selected() {
// If the selection was empty arrange everything // If the selection was empty arrange everything
if (m_selected.empty()) if (m_selected.empty())
m_selected.swap(m_unselected); m_selected.swap(m_unselected);
// The strides have to be removed from the fixed items. For the
// arrangeable (selected) items bed_idx is ignored and the
// translation is irrelevant.
for (auto &p : m_unselected)
p.translation(X) -= p.bed_idx * stride;
} }
static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret,
@ -261,6 +254,10 @@ void ArrangeJob::prepare()
} }
m_min_bed_inset = min_offset; m_min_bed_inset = min_offset;
} }
double stride = bed_stride(m_plater);
get_bed_shape(*m_plater->config(), m_bed);
assign_logical_beds(m_unselected, m_bed, stride);
} }
void ArrangeJob::process(Ctl &ctl) void ArrangeJob::process(Ctl &ctl)
@ -268,11 +265,9 @@ void ArrangeJob::process(Ctl &ctl)
static const auto arrangestr = _u8L("Arranging"); static const auto arrangestr = _u8L("Arranging");
arrangement::ArrangeParams params; arrangement::ArrangeParams params;
arrangement::ArrangeBed bed; ctl.call_on_main_thread([this, &params]{
ctl.call_on_main_thread([this, &params, &bed]{
prepare(); prepare();
params = get_arrange_params(m_plater); params = get_arrange_params(m_plater);
get_bed_shape(*m_plater->config(), bed);
coord_t min_inset = get_skirt_offset(m_plater) + m_min_bed_inset; coord_t min_inset = get_skirt_offset(m_plater) + m_min_bed_inset;
params.min_bed_distance = std::max(params.min_bed_distance, min_inset); params.min_bed_distance = std::max(params.min_bed_distance, min_inset);
}).wait(); }).wait();
@ -293,13 +288,13 @@ void ArrangeJob::process(Ctl &ctl)
ctl.update_status(0, arrangestr); ctl.update_status(0, arrangestr);
arrangement::arrange(m_selected, m_unselected, bed, params); arrangement::arrange(m_selected, m_unselected, m_bed, params);
params.progressind = [this, count, &ctl](unsigned st) { params.progressind = [this, count, &ctl](unsigned st) {
if (st > 0) ctl.update_status(int(count - st) * 100 / status_range(), arrangestr); if (st > 0) ctl.update_status(int(count - st) * 100 / status_range(), arrangestr);
}; };
arrangement::arrange(m_unprintable, {}, bed, params); arrangement::arrange(m_unprintable, {}, m_bed, params);
// finalize just here. // finalize just here.
ctl.update_status(int(count) * 100 / status_range(), ctl.was_canceled() ? ctl.update_status(int(count) * 100 / status_range(), ctl.was_canceled() ?
@ -358,7 +353,9 @@ void ArrangeJob::finalize(bool canceled, std::exception_ptr &eptr) {
ap.apply(); ap.apply();
} }
m_plater->update((unsigned int)Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH); m_plater->update(static_cast<unsigned int>(
Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH));
wxGetApp().obj_manipul()->set_dirty(); wxGetApp().obj_manipul()->set_dirty();
if (!m_unarranged.empty()) { if (!m_unarranged.empty()) {
@ -442,4 +439,26 @@ arrangement::ArrangeParams get_arrange_params(Plater *p)
return params; return params;
} }
void assign_logical_beds(std::vector<arrangement::ArrangePolygon> &items,
const arrangement::ArrangeBed &bed,
double stride)
{
// The strides have to be removed from the fixed items. For the
// arrangeable (selected) items bed_idx is ignored and the
// translation is irrelevant.
coord_t bedx = bounding_box(bed).min.x();
for (auto &itm : items) {
auto bedidx = std::max(arrangement::UNARRANGED,
static_cast<int>(std::floor(
(get_extents(itm.transformed_poly()).min.x() - bedx) /
stride)));
itm.bed_idx = bedidx;
if (bedidx >= 0)
itm.translation.x() -= bedidx * stride;
}
}
}} // namespace Slic3r::GUI }} // namespace Slic3r::GUI

View File

@ -21,6 +21,7 @@ class ArrangeJob : public Job
ArrangePolygons m_selected, m_unselected, m_unprintable; ArrangePolygons m_selected, m_unselected, m_unprintable;
std::vector<ModelInstance*> m_unarranged; std::vector<ModelInstance*> m_unarranged;
arrangement::ArrangeBed m_bed;
coord_t m_min_bed_inset = 0.; coord_t m_min_bed_inset = 0.;
Plater *m_plater; Plater *m_plater;
@ -89,7 +90,6 @@ arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater)
using ArrangePolygon = arrangement::ArrangePolygon; using ArrangePolygon = arrangement::ArrangePolygon;
ArrangePolygon ap = obj.get_arrange_polygon(); ArrangePolygon ap = obj.get_arrange_polygon();
ap.bed_idx = get_extents(ap.transformed_poly()).min.x() / bed_stride(plater);
ap.setter = [obj, plater](const ArrangePolygon &p) { ap.setter = [obj, plater](const ArrangePolygon &p) {
if (p.is_arranged()) { if (p.is_arranged()) {
Vec2d t = p.translation.cast<double>(); Vec2d t = p.translation.cast<double>();
@ -109,6 +109,10 @@ arrangement::ArrangeParams get_arrange_params(Plater *p);
coord_t get_skirt_offset(const Plater* plater); coord_t get_skirt_offset(const Plater* plater);
void assign_logical_beds(std::vector<arrangement::ArrangePolygon> &items,
const arrangement::ArrangeBed &bed,
double stride);
}} // namespace Slic3r::GUI }} // namespace Slic3r::GUI
#endif // ARRANGEJOB_HPP #endif // ARRANGEJOB_HPP

View File

@ -17,7 +17,6 @@ void FillBedJob::prepare()
{ {
m_selected.clear(); m_selected.clear();
m_unselected.clear(); m_unselected.clear();
m_bedpts.clear();
m_min_bed_inset = 0.; m_min_bed_inset = 0.;
m_object_idx = m_plater->get_selected_object_idx(); m_object_idx = m_plater->get_selected_object_idx();
@ -41,10 +40,10 @@ void FillBedJob::prepare()
if (m_selected.empty()) if (m_selected.empty())
return; return;
m_bedpts = get_bed_shape(*m_plater->config()); Points bedpts = get_bed_shape(*m_plater->config());
auto &objects = m_plater->model().objects; auto &objects = m_plater->model().objects;
BoundingBox bedbb = get_extents(m_bedpts); BoundingBox bedbb = get_extents(bedpts);
for (size_t idx = 0; idx < objects.size(); ++idx) for (size_t idx = 0; idx < objects.size(); ++idx)
if (int(idx) != m_object_idx) if (int(idx) != m_object_idx)
@ -72,7 +71,7 @@ void FillBedJob::prepare()
}) / sc; }) / sc;
double fixed_area = unsel_area + m_selected.size() * poly_area; double fixed_area = unsel_area + m_selected.size() * poly_area;
double bed_area = Polygon{m_bedpts}.area() / sc; double bed_area = Polygon{bedpts}.area() / sc;
// This is the maximum number of items, the real number will always be close but less. // This is the maximum number of items, the real number will always be close but less.
int needed_items = (bed_area - fixed_area) / poly_area; int needed_items = (bed_area - fixed_area) / poly_area;
@ -85,13 +84,11 @@ void FillBedJob::prepare()
for (int i = 0; i < needed_items; ++i) { for (int i = 0; i < needed_items; ++i) {
ArrangePolygon ap = template_ap; ArrangePolygon ap = template_ap;
ap.poly = m_selected.front().poly;
ap.bed_idx = arrangement::UNARRANGED; ap.bed_idx = arrangement::UNARRANGED;
auto m = mi->get_transformation(); auto m = mi->get_transformation();
ap.setter = [this, mi, m](const ArrangePolygon &p) { ap.setter = [this, m](const ArrangePolygon &p) {
ModelObject *mo = m_plater->model().objects[m_object_idx]; ModelObject *mo = m_plater->model().objects[m_object_idx];
ModelInstance *inst = mo->add_instance(*mi); ModelInstance *inst = mo->add_instance(m);
inst->set_transformation(m);
inst->apply_arrange_result(p.translation.cast<double>(), p.rotation); inst->apply_arrange_result(p.translation.cast<double>(), p.rotation);
}; };
m_selected.emplace_back(ap); m_selected.emplace_back(ap);
@ -99,14 +96,6 @@ void FillBedJob::prepare()
m_status_range = m_selected.size(); m_status_range = m_selected.size();
// The strides have to be removed from the fixed items. For the
// arrangeable (selected) items bed_idx is ignored and the
// translation is irrelevant.
double stride = bed_stride(m_plater);
for (auto &p : m_unselected)
if (p.bed_idx > 0)
p.translation(X) -= p.bed_idx * stride;
coord_t min_offset = 0; coord_t min_offset = 0;
for (auto &ap : m_selected) { for (auto &ap : m_selected) {
min_offset = std::max(ap.inflation, min_offset); min_offset = std::max(ap.inflation, min_offset);
@ -123,6 +112,14 @@ void FillBedJob::prepare()
} }
m_min_bed_inset = min_offset; m_min_bed_inset = min_offset;
} }
// The strides have to be removed from the fixed items. For the
// arrangeable (selected) items bed_idx is ignored and the
// translation is irrelevant.
double stride = bed_stride(m_plater);
m_bed = arrangement::to_arrange_bed(bedpts);
assign_logical_beds(m_unselected, m_bed, stride);
} }
void FillBedJob::process(Ctl &ctl) void FillBedJob::process(Ctl &ctl)
@ -154,7 +151,7 @@ void FillBedJob::process(Ctl &ctl)
do_stop = ap.bed_idx > 0 && ap.priority == 0; do_stop = ap.bed_idx > 0 && ap.priority == 0;
}; };
arrangement::arrange(m_selected, m_unselected, m_bedpts, params); arrangement::arrange(m_selected, m_unselected, m_bed, params);
// finalize just here. // finalize just here.
ctl.update_status(100, ctl.was_canceled() ? ctl.update_status(100, ctl.was_canceled() ?
@ -191,7 +188,8 @@ void FillBedJob::finalize(bool canceled, std::exception_ptr &eptr)
model_object->ensure_on_bed(); model_object->ensure_on_bed();
m_plater->update(); m_plater->update(static_cast<unsigned int>(
Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH));
// FIXME: somebody explain why this is needed for increase_object_instances // FIXME: somebody explain why this is needed for increase_object_instances
if (inst_cnt == 1) if (inst_cnt == 1)

View File

@ -18,7 +18,7 @@ class FillBedJob : public Job
ArrangePolygons m_unselected; ArrangePolygons m_unselected;
coord_t m_min_bed_inset = 0.; coord_t m_min_bed_inset = 0.;
Points m_bedpts; arrangement::ArrangeBed m_bed;
int m_status_range = 0; int m_status_range = 0;
Plater *m_plater; Plater *m_plater;

View File

@ -6477,7 +6477,7 @@ void Plater::export_stl_obj(bool extended, bool selection_only)
const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id()); const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id());
if (auto m = object->get_mesh_to_print(); !m || m->empty()) if (!object || !object->get_mesh_to_print() || object->get_mesh_to_print()->empty())
mesh = mesh_to_export_fff(mo, instance_id); mesh = mesh_to_export_fff(mo, instance_id);
else { else {
const Transform3d mesh_trafo_inv = object->trafo().inverse(); const Transform3d mesh_trafo_inv = object->trafo().inverse();
@ -7696,7 +7696,7 @@ PlaterAfterLoadAutoArrange::PlaterAfterLoadAutoArrange()
Plater* plater = wxGetApp().plater(); Plater* plater = wxGetApp().plater();
m_enabled = plater->model().objects.empty() && m_enabled = plater->model().objects.empty() &&
plater->printer_technology() == ptFFF && plater->printer_technology() == ptFFF &&
plater->fff_print().config().printer_model.value == "XL"; is_XL_printer(plater->fff_print().config());
} }
PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange() PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange()

View File

@ -216,10 +216,10 @@ void Tab::create_preset_tab()
m_mode_sizer = new ModeSizer(panel, int (0.5*em_unit(this))); m_mode_sizer = new ModeSizer(panel, int (0.5*em_unit(this)));
const float scale_factor = em_unit(this)*0.1;// GetContentScaleFactor(); const float scale_factor = em_unit(this)*0.1;// GetContentScaleFactor();
m_hsizer = new wxBoxSizer(wxHORIZONTAL); m_top_hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_hsizer, 0, wxEXPAND | wxBOTTOM, 3); sizer->Add(m_top_hsizer, 0, wxEXPAND | wxBOTTOM | wxALIGN_CENTER_VERTICAL, 3);
m_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); m_top_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
m_hsizer->AddSpacer(int(4*scale_factor)); m_top_hsizer->AddSpacer(int(4*scale_factor));
m_h_buttons_sizer = new wxBoxSizer(wxHORIZONTAL); m_h_buttons_sizer = new wxBoxSizer(wxHORIZONTAL);
m_h_buttons_sizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL); m_h_buttons_sizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL);
@ -243,9 +243,8 @@ void Tab::create_preset_tab()
m_h_buttons_sizer->AddSpacer(int(8*scale_factor)); m_h_buttons_sizer->AddSpacer(int(8*scale_factor));
m_h_buttons_sizer->Add(m_btn_compare_preset, 0, wxALIGN_CENTER_VERTICAL); m_h_buttons_sizer->Add(m_btn_compare_preset, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->Add(m_h_buttons_sizer, 1, wxEXPAND); m_top_hsizer->Add(m_h_buttons_sizer, 1, wxEXPAND | wxALIGN_CENTRE_VERTICAL);
m_hsizer->AddSpacer(int(16*scale_factor)); m_top_hsizer->AddSpacer(int(16*scale_factor));
// m_hsizer->AddStretchSpacer(32);
// StretchSpacer has a strange behavior under OSX, so // StretchSpacer has a strange behavior under OSX, so
// There is used just additional sizer for m_mode_sizer with right alignment // There is used just additional sizer for m_mode_sizer with right alignment
if (m_mode_sizer) { if (m_mode_sizer) {
@ -253,8 +252,10 @@ void Tab::create_preset_tab()
// Don't set the 2nd parameter to 1, making the sizer rubbery scalable in Y axis may lead // Don't set the 2nd parameter to 1, making the sizer rubbery scalable in Y axis may lead
// to wrong vertical size assigned to wxBitmapComboBoxes, see GH issue #7176. // to wrong vertical size assigned to wxBitmapComboBoxes, see GH issue #7176.
mode_sizer->Add(m_mode_sizer, 0, wxALIGN_RIGHT); mode_sizer->Add(m_mode_sizer, 0, wxALIGN_RIGHT);
m_hsizer->Add(mode_sizer, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, wxOSX ? 15 : 10); m_top_hsizer->Add(mode_sizer, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, wxOSX ? 15 : 10);
} }
// hide whole top sizer to correct layout later
m_top_hsizer->ShowItems(false);
//Horizontal sizer to hold the tree and the selected page. //Horizontal sizer to hold the tree and the selected page.
m_hsizer = new wxBoxSizer(wxHORIZONTAL); m_hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -461,20 +462,15 @@ void Tab::OnActivate()
activate_selected_page([](){}); activate_selected_page([](){});
m_hsizer->Layout(); m_hsizer->Layout();
#ifdef _MSW_DARK_MODE if (m_presets_choice->IsShown())
// Because of DarkMode we use our own Notebook (inherited from wxSiplebook) instead of wxNotebook Refresh(); // Just refresh page, if m_presets_choice is already shown
// And it looks like first Layout of the page doesn't update a size of the m_presets_choice else {
// So we have to set correct size explicitely // on first OnActivate call show top sizer
if (wxSize ok_sz = wxSize(35 * m_em_unit, m_presets_choice->GetBestSize().y); m_top_hsizer->ShowItems(true);
ok_sz != m_presets_choice->GetSize()) { if (TabFilament* tab = dynamic_cast<TabFilament*>(this))
m_presets_choice->SetMinSize(ok_sz); tab->update_extruder_combobox();
m_presets_choice->SetSize(ok_sz); Layout();
GetSizer()->GetItem(size_t(0))->GetSizer()->Layout();
if (wxGetApp().tabs_as_menu())
m_presets_choice->update();
} }
#endif // _MSW_DARK_MODE
Refresh();
} }
void Tab::update_label_colours() void Tab::update_label_colours()
@ -1950,6 +1946,9 @@ void TabFilament::create_extruder_combobox()
void TabFilament::update_extruder_combobox() void TabFilament::update_extruder_combobox()
{ {
if (!m_presets_choice->IsShown())
return; // it will be updated later, on OnActive()
const size_t extruder_cnt = static_cast<const ConfigOptionFloats*>(m_preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter"))->values.size(); const size_t extruder_cnt = static_cast<const ConfigOptionFloats*>(m_preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter"))->values.size();
m_extruders_cb->Show(extruder_cnt > 1); m_extruders_cb->Show(extruder_cnt > 1);

View File

@ -172,6 +172,7 @@ protected:
ScalableButton* m_btn_delete_preset; ScalableButton* m_btn_delete_preset;
ScalableButton* m_btn_edit_ph_printer {nullptr}; ScalableButton* m_btn_edit_ph_printer {nullptr};
ScalableButton* m_btn_hide_incompatible_presets; ScalableButton* m_btn_hide_incompatible_presets;
wxBoxSizer* m_top_hsizer;
wxBoxSizer* m_hsizer; wxBoxSizer* m_hsizer;
wxBoxSizer* m_h_buttons_sizer; wxBoxSizer* m_h_buttons_sizer;
wxBoxSizer* m_left_sizer; wxBoxSizer* m_left_sizer;