diff --git a/deps/OpenEXR/OpenEXR.cmake b/deps/OpenEXR/OpenEXR.cmake index 046223fed9..dc1d2fab1a 100644 --- a/deps/OpenEXR/OpenEXR.cmake +++ b/deps/OpenEXR/OpenEXR.cmake @@ -4,6 +4,7 @@ prusaslicer_add_cmake_project(OpenEXR URL_HASH SHA256=0307a3d7e1fa1e77e9d84d7e9a8694583fbbbfd50bdc6884e2c96b8ef6b902de DEPENDS ${ZLIB_PKG} GIT_TAG v2.5.5 + PATCH_COMMAND COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/OpenEXR.patch CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_TESTING=OFF @@ -14,4 +15,4 @@ prusaslicer_add_cmake_project(OpenEXR if (MSVC) add_debug_dep(dep_OpenEXR) -endif () \ No newline at end of file +endif () diff --git a/deps/OpenEXR/OpenEXR.patch b/deps/OpenEXR/OpenEXR.patch new file mode 100644 index 0000000000..b9f9f1c28e --- /dev/null +++ b/deps/OpenEXR/OpenEXR.patch @@ -0,0 +1,30 @@ +--- ../OpenEXR-orig/OpenEXR/IlmImf/ImfDwaCompressor.cpp 2021-02-12 17:56:19.000000000 +0100 ++++ ./OpenEXR/IlmImf/ImfDwaCompressor.cpp 2023-06-01 13:21:32.666695400 +0200 +@@ -159,6 +159,7 @@ + #include + + #include ++#include + + + // Windows specific addition to prevent the indirect import of the redefined min/max macros +--- ../OpenEXR-orig/OpenEXR/IlmImf/ImfHuf.cpp 2021-02-12 17:56:19.000000000 +0100 ++++ ./OpenEXR/IlmImf/ImfHuf.cpp 2023-06-01 13:21:53.018583400 +0200 +@@ -53,6 +53,7 @@ + #include + #include + #include ++#include + + + using namespace std; +--- ../OpenEXR-orig/OpenEXR/IlmImf/ImfMisc.cpp 2021-02-12 17:56:19.000000000 +0100 ++++ ./OpenEXR/IlmImf/ImfMisc.cpp 2023-06-01 13:22:15.777480000 +0200 +@@ -40,6 +40,7 @@ + // + //----------------------------------------------------------------------------- + ++#include + #include + #include + #include diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake index 661ea766c7..8174be589d 100644 --- a/deps/wxWidgets/wxWidgets.cmake +++ b/deps/wxWidgets/wxWidgets.cmake @@ -13,8 +13,8 @@ if (UNIX AND NOT APPLE) # wxWidgets will not use char as the underlying type for endif() prusaslicer_add_cmake_project(wxWidgets - URL https://github.com/prusa3d/wxWidgets/archive/0b49beaacce17d90f0c370ecd73221abd089667a.zip - URL_HASH SHA256=8fa978a76d6bd811b30eecc5124186b9ad54290b820f3a354e85bfa9dae6a5ce + URL https://github.com/prusa3d/wxWidgets/archive/78aa2dc0ea7ce99dc19adc1140f74c3e2e3f3a26.zip + URL_HASH SHA256=94b7d972373503e380e5a8b0ca63b1ccb956da4006402298dd89a0c5c7041b1e DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG dep_NanoSVG CMAKE_ARGS -DwxBUILD_PRECOMP=ON diff --git a/resources/localization/be/PrusaSlicer.mo b/resources/localization/be/PrusaSlicer.mo index 1c45b44e3e..ca0eb52fab 100644 Binary files a/resources/localization/be/PrusaSlicer.mo and b/resources/localization/be/PrusaSlicer.mo differ diff --git a/resources/localization/be/PrusaSlicer_be.po b/resources/localization/be/PrusaSlicer_be.po index 7a039e35b0..f44477aa1d 100644 --- a/resources/localization/be/PrusaSlicer_be.po +++ b/resources/localization/be/PrusaSlicer_be.po @@ -1512,7 +1512,7 @@ msgstr "" #: src/slic3r/GUI/DoubleSlider.cpp:1465 msgid "Edit current color - Right click the colored slider segment" msgstr "" -"Змяніць бягучы колер - Правая кнопка мышы по каляроваму адрэзку " +"Змяніць бягучы колер - Правая кнопка мышы по каляроваму адрэзку " "паўзунка" #: src/slic3r/GUI/DoubleSlider.cpp:1467 @@ -1533,32 +1533,32 @@ msgstr "Рэжым друку" #: src/slic3r/GUI/DoubleSlider.cpp:1495 msgid "Add extruder change - Left click" -msgstr "Дадаць змену экструдара - Левая кнопка мышы" +msgstr "Дадаць змену экструдара - Левая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1497 msgid "" "Add color change - Left click for predefined color or Shift + Left click for " "custom color selection" msgstr "" -"Дадаць змену колера - Левая кнопка мышы для колера з спіску " -"першапачатковых колераў ці Shift + Левая кнопка мышы для выбору " +"Дадаць змену колера - Левая кнопка мышы для колера з спіску " +"першапачатковых колераў ці Shift + Левая кнопка мышы для выбору " "свайго колеру" #: src/slic3r/GUI/DoubleSlider.cpp:1499 msgid "Add color change - Left click" -msgstr "Дадаць змену колера - Левая кнопка мышы" +msgstr "Дадаць змену колера - Левая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1500 msgid "or press \"+\" key" -msgstr "альбо клавіша +" +msgstr "альбо клавіша \"+\"" #: src/slic3r/GUI/DoubleSlider.cpp:1502 msgid "Add another code - Ctrl + Left click" -msgstr "Дадаць іншы кода - Ctrl + левая кнопка мышы" +msgstr "Дадаць іншы кода - Ctrl + левая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1503 msgid "Add another code - Right click" -msgstr "Дадаць іншы код - Правая кнопка мышы" +msgstr "Дадаць іншы код - Правая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1509 msgid "" @@ -1639,15 +1639,15 @@ msgstr "" #: src/slic3r/GUI/DoubleSlider.cpp:1565 msgid "Delete tick mark - Left click or press \"-\" key" -msgstr "Выдаліц птушку - Левая кнопка мышы альбо клавіша -" +msgstr "Выдаліц птушку - Левая кнопка мышы альбо клавіша \"-\"" #: src/slic3r/GUI/DoubleSlider.cpp:1567 msgid "Edit tick mark - Ctrl + Left click" -msgstr "Змяніць птушку - Ctrl + левая кнопка мышы" +msgstr "Змяніць птушку - Ctrl + левая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1568 msgid "Edit tick mark - Right click" -msgstr "Змяніць птушку - Правая кнопка мышы" +msgstr "Змяніць птушку - Правая кнопка мышы" #: src/slic3r/GUI/DoubleSlider.cpp:1671 src/slic3r/GUI/DoubleSlider.cpp:1702 #: src/slic3r/GUI/GUI_Factories.cpp:870 @@ -2495,7 +2495,7 @@ msgstr "Пераменная вышыня пластоў" #: src/slic3r/GUI/GLCanvas3D.cpp:191 msgid "Left mouse button:" -msgstr "Левая кнопка мышы:" +msgstr "Левая кнопка мышы:" #: src/slic3r/GUI/GLCanvas3D.cpp:193 msgid "Add detail" @@ -2503,7 +2503,7 @@ msgstr "Павялічыць дэтальнасць" #: src/slic3r/GUI/GLCanvas3D.cpp:195 msgid "Right mouse button:" -msgstr "Правая кнопка мышы:" +msgstr "Правая кнопка мышы:" #: src/slic3r/GUI/GLCanvas3D.cpp:197 msgid "Remove detail" @@ -2511,7 +2511,7 @@ msgstr "Паменьшыць дэтальнасць" #: src/slic3r/GUI/GLCanvas3D.cpp:199 msgid "Shift + Left mouse button:" -msgstr "Shift + Левая кнопка мышы:" +msgstr "Shift + Левая кнопка мышы:" #: src/slic3r/GUI/GLCanvas3D.cpp:201 msgid "Reset to base" @@ -2519,7 +2519,7 @@ msgstr "Скід да звычайнай вышыні пласта" #: src/slic3r/GUI/GLCanvas3D.cpp:203 msgid "Shift + Right mouse button:" -msgstr "Shift + Правая кнопка мышы:" +msgstr "Shift + Правая кнопка мышы:" #: src/slic3r/GUI/GLCanvas3D.cpp:205 msgid "Smoothing" @@ -2527,7 +2527,7 @@ msgstr "Згладжванне" #: src/slic3r/GUI/GLCanvas3D.cpp:207 msgid "Mouse wheel:" -msgstr "Кола мышы:" +msgstr "Кола мышы:" #: src/slic3r/GUI/GLCanvas3D.cpp:209 msgid "Increase/decrease edit area" @@ -2676,7 +2676,7 @@ msgstr "Налады ўпарадкавання" #: src/slic3r/GUI/GLCanvas3D.cpp:4845 #, boost-format msgid "Press %1%left mouse button to enter the exact value" -msgstr "Націсніце %1% левую кнопку мышы для ўводу дакладнага значэння" +msgstr "Націсніце %1% левую кнопку мышы для ўводу дакладнага значэння" #: src/slic3r/GUI/GLCanvas3D.cpp:4847 msgid "Spacing" @@ -2739,7 +2739,7 @@ msgstr "Упарадкаваць абраныя" #: src/slic3r/GUI/GLCanvas3D.cpp:5325 msgid "Click right mouse button to show arrangement options" msgstr "" -"Пстрыкніце правую кнопку мышы, каб адлюстраваць налады ўпарадкавання" +"Пстрыкніце правую кнопку мышы, каб адлюстраваць налады ўпарадкавання" #: src/slic3r/GUI/GLCanvas3D.cpp:5345 msgid "Copy" @@ -2769,7 +2769,7 @@ msgstr "Падзяліць на часткі" #: src/slic3r/GUI/GLCanvas3D.cpp:5506 src/slic3r/GUI/GLCanvas3D.cpp:5543 msgid "Click right mouse button to open/close History" msgstr "" -"Псктрыкнуць правую кнопку мышы, каб адлюстраваць/схаваць Гісторы дзей" +"Псктрыкнуць правую кнопку мышы, каб адлюстраваць/схаваць Гісторы дзей" #: src/slic3r/GUI/GLCanvas3D.cpp:5528 #, boost-format @@ -2942,7 +2942,7 @@ msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1268 #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1269 msgid "Left click" -msgstr "Левая кнопка мышы" +msgstr "Левая кнопка мышы" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:823 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:2821 @@ -2952,7 +2952,7 @@ msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824 #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1266 msgid "Right click" -msgstr "Правая кнопка мышы" +msgstr "Правая кнопка мышы" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:824 msgid "Remove connector" @@ -3612,7 +3612,7 @@ msgstr "Форма пэндзаля" #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:110 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:35 msgid "Left mouse button" -msgstr "Левая кнопка мышы" +msgstr "Левая кнопка мышы" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:55 msgid "Enforce supports" @@ -3622,7 +3622,7 @@ msgstr "Прымусовая падтрымка" #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:112 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:37 msgid "Right mouse button" -msgstr "Правая кнопка мышы" +msgstr "Правая кнопка мышы" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:57 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:575 @@ -3633,7 +3633,7 @@ msgstr "Блакаваць падтрымкі" #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:114 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:39 msgid "Shift + Left mouse button" -msgstr "Shift + Левая кнопка мышы" +msgstr "Shift + Левая кнопка мышы" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:59 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:570 @@ -3747,7 +3747,7 @@ msgstr "Фарбуе толькі адну мяжу." #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:462 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:129 msgid "Alt + Mouse wheel" -msgstr "Alt + Кола мышы" +msgstr "Alt + Кола мышы" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:290 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/GLGizmoSeam.cpp:167 msgid "Ctrl + Mouse wheel" -msgstr "Ctrl + Кола мышы" +msgstr "Ctrl + Кола мышы" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:328 #: src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp:488 @@ -5566,28 +5566,28 @@ msgstr "Засталося памылак" #: src/slic3r/GUI/GUI_ObjectList.cpp:480 msgid "Right button click the icon to fix STL through Netfabb" msgstr "" -"Пстрыкніце правай кнопкай мышы на гузік, каб выправіць STL з " +"Пстрыкніце правай кнопкай мышы на гузік, каб выправіць STL з " "дапамогай сервіса Netfabb" #: src/slic3r/GUI/GUI_ObjectList.cpp:526 msgid "Right button click the icon to change the object settings" msgstr "" -"Пстрыкніце правай кнопкай мышы на гузік, каб змяніць налады мадэлі" +"Пстрыкніце правай кнопкай мышы на гузік, каб змяніць налады мадэлі" #: src/slic3r/GUI/GUI_ObjectList.cpp:528 msgid "Click the icon to change the object settings" -msgstr "Пстрыкніце кнопкай мышы на гузік, каб змяніць налады мадэлі" +msgstr "Пстрыкніце кнопкай мышы на гузік, каб змяніць налады мадэлі" #: src/slic3r/GUI/GUI_ObjectList.cpp:532 msgid "Right button click the icon to change the object printable property" msgstr "" -"Пстрыкніце правай кнопкай мышы на гузік, каб змяніць уласцівасці " +"Пстрыкніце правай кнопкай мышы на гузік, каб змяніць уласцівасці " "друку мадэлі" #: src/slic3r/GUI/GUI_ObjectList.cpp:534 msgid "Click the icon to change the object printable property" msgstr "" -"Пстрыкніце кнопкай мышы на гузік, каб змяніць уласцівасці друку мадэлі" +"Пстрыкніце кнопкай мышы на гузік, каб змяніць уласцівасці друку мадэлі" #: src/slic3r/GUI/GUI_ObjectList.cpp:660 msgid "Change Extruder" @@ -6515,7 +6515,7 @@ msgstr "Націсніце, каб актываваць прастакутнік #: src/slic3r/GUI/KBShortcutsDialog.cpp:239 #: src/slic3r/GUI/KBShortcutsDialog.cpp:254 msgid "Arrow Up" -msgstr "Стрэлка ўверх" +msgstr "Стрэлка ўверх" #: src/slic3r/GUI/KBShortcutsDialog.cpp:148 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:255 msgid "Arrow Down" -msgstr "Стрэлка ўніз" +msgstr "Стрэлка ўніз" #: src/slic3r/GUI/KBShortcutsDialog.cpp:149 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:252 msgid "Arrow Left" -msgstr "Стрэлка налева" +msgstr "Стрэлка налева" #: src/slic3r/GUI/KBShortcutsDialog.cpp:150 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:253 msgid "Arrow Right" -msgstr "Стрэлка направа" +msgstr "Стрэлка направа" #: src/slic3r/GUI/KBShortcutsDialog.cpp:151 msgid "Move selection 10 mm in positive X direction" @@ -6569,7 +6569,7 @@ msgstr "Рух абранага ў прасторы камеры" #: src/slic3r/GUI/KBShortcutsDialog.cpp:154 msgid "Page Up" -msgstr "Page Up" +msgstr "Page Up" #: src/slic3r/GUI/KBShortcutsDialog.cpp:154 msgid "Rotate selection 45 degrees CCW" @@ -6577,7 +6577,7 @@ msgstr "Вярчэнне абранага на 45° супраць гадзін #: src/slic3r/GUI/KBShortcutsDialog.cpp:155 msgid "Page Down" -msgstr "Page Down" +msgstr "Page Down" #: src/slic3r/GUI/KBShortcutsDialog.cpp:155 msgid "Rotate selection 45 degrees CW" @@ -6688,8 +6688,8 @@ msgstr "Стол" #: src/slic3r/GUI/KBShortcutsDialog.cpp:190 msgid "All gizmos: Rotate - left mouse button; Pan - right mouse button" msgstr "" -"Усе штуковіны: Вярчэнне камеры - Левая кнопка мышы; Рух камеры - " -"Правая кнопка мышы" +"Усе штуковіны: Вярчэнне камеры - Левая кнопка мышы; Рух камеры - " +"Правая кнопка мышы" #: src/slic3r/GUI/KBShortcutsDialog.cpp:191 msgid "Gizmo move: Press to snap by 1mm" @@ -8216,7 +8216,7 @@ msgstr "Нарэзаць зараз" #: src/slic3r/GUI/Plater.cpp:1124 msgid "Hold Shift to Slice & Export G-code" -msgstr "Утрымлівайце Shift, каб нарэзаць і экспартаваць у G-код" +msgstr "Утрымлівайце Shift, каб нарэзаць і экспартаваць у G-код" #: src/slic3r/GUI/Plater.cpp:1321 #, boost-format @@ -11163,7 +11163,7 @@ msgstr "" msgid "" "Some fields are too long to fit. Right mouse click reveals the full text." msgstr "" -"Некаторыя палі занадта доўгія. Пстрыкніце правай кнопкай мышы, каб " +"Некаторыя палі занадта доўгія. Пстрыкніце правай кнопкай мышы, каб " "адлюстраваць поўны тэкст." #: src/slic3r/GUI/UnsavedChangesDialog.cpp:969 @@ -17761,7 +17761,7 @@ msgid "" "size of the gap between objects and to allow automatic rotations?" msgstr "" "Налады ўпарадкавання\n" -"Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на гузік " +"Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на гузік " "Упарадкаваць гузікі, каб наладзіць прагал паміж мадэлямя і дазволіць " "аўтаматычнае вярчэнне?" @@ -17788,8 +17788,8 @@ msgid "" msgstr "" "Спрасціць сетку\n" "Ці ведаеце вы, што вы можаце паменьшыць колкасць трыкутнікаў у паліганальнай " -"сетцы, калі ўжыць функцыю спрашчэння сеткі? Пстрыкніце правай кнопкай " -"мышы на мадэлі і абярыце Спрасціць мадэль. Больш падрабязна " +"сетцы, калі ўжыць функцыю спрашчэння сеткі? Пстрыкніце правай кнопкай " +"мышы на мадэлі і абярыце Спрасціць мадэль. Больш падрабязна " "чытайце ў дакументацыі." #: resources/data/hints.ini: [hint:Reload from disk] @@ -17801,9 +17801,9 @@ msgid "" msgstr "" "Перазагрузіць з дыску\n" "Ці ведаеце вы, што калі вы стварылі больш новую версію сваёй мадэлі, вы " -"можаце проста перазагрузіць яе ў PrusaSlicer? Пстрыкніце правай кнопкай " -"мышы на мадэлі ў акне 3D-прагляду і абярыце Перазагрузіць з дыска. Больш падрабязна чытайце ў дакументацыі." +"можаце проста перазагрузіць яе ў PrusaSlicer? Пстрыкніце правай кнопкай " +"мышы на мадэлі ў акне 3D-прагляду і абярыце Перазагрузіць з дыска" +". Больш падрабязна чытайце ў дакументацыі." #: resources/data/hints.ini: [hint:Hiding sidebar] msgid "" @@ -17833,7 +17833,7 @@ msgid "" "between predefined camera angles?" msgstr "" "Выгляд з камеры\n" -"Ці ведаеце вы, што вы можаце ўжываць лічбавыя клавішы 0-6, каб " +"Ці ведаеце вы, што вы можаце ўжываць лічбавыя клавішы 0-6, каб " "хутка пераключацца паміж папярэдне зададзенымі ракурсамі камеры?" #: resources/data/hints.ini: [hint:Place on face] @@ -17855,7 +17855,7 @@ msgid "" "instances instead of copy-pasting it several times?" msgstr "" "Ужыць колькасць асобнікаў\n" -"Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на мадэлі " +"Ці ведаеце вы, што вы можаце пстрыкнуць правай кнопкай мышы на мадэлі " "і задаць дакладную колькасць копіяў мадэлі замест таго, каб капіяваць і " "ўстаўляць её некалькі разоў?" @@ -17890,7 +17890,7 @@ msgid "" "history of changes and to undo or redo several actions at once?" msgstr "" "Гісторыя адкаціць/зрабіць нанова\n" -"Ці ведаеце вы, вы можаце пстрыкнуць правай кнопкай мышы на стрэлкі " +"Ці ведаеце вы, вы можаце пстрыкнуць правай кнопкай мышы на стрэлкі " "адмены/паўтору, каб праглядзець гісторыю змяненняў і адмяніць ці " "паўтарыць некалькі дзеянняў адначасова?" @@ -17904,8 +17904,8 @@ msgid "" msgstr "" "Розная вышыня пластаў для кожнай мадэлі\n" "Ці ведаеце вы, што вы можаце надрукаваць кожную мадэль на стале з рознай " -"вышынёй пластоў? Пстрыкніце правай кнопкай мышы на мадэлі ў акне 3D-" -"прагляду, абярыце Пласты і перыметры, наладзьце значэнні на правай " +"вышынёй пластоў? Пстрыкніце правай кнопкай мышы на мадэлі ў акне 3D-" +"прагляду, абярыце Пласты і перыметры, наладзьце значэнні на правай " "панэлі. Больш падрабязна чытайце ў дакументацыі." #: resources/data/hints.ini: [hint:Solid infill threshold area] @@ -17938,8 +17938,8 @@ msgid "" "also box-deselect objects with Alt+Mouse drag." msgstr "" "Выдзяленне прастакутнікам\n" -"Ці ведаеце вы, што вы можаце вылучыць поле з дапамогай Shift + " -"перацягванне мышшу? Вы так сама можаце адмяніць вылучэнне мадэляў з " +"Ці ведаеце вы, што вы можаце вылучыць поле з дапамогай Shift + " +"перацягванне мышшу? Вы так сама можаце адмяніць вылучэнне мадэляў з " "дапамогай спалучэння клавішаў Alt + перацягванне мышшу." #: resources/data/hints.ini: [hint:Zoom on selected objects or all if none @@ -17965,8 +17965,8 @@ msgstr "" "Перамыкач для друку\n" "Ці ведаеце вы, што вы можаце адключыць стварэнне G-кода для абранай мадэлі, " "без неабходнасці рухаць ці выдаляць яе? Пераключыце ўласцівасць мадэлі " -"Для друку з кантэкстнага меню, калі пстрыкнуць правай кнопкай " -"мышы." +"Для друку з кантэкстнага меню, калі пстрыкнуць правай кнопкай " +"мышы." #: resources/data/hints.ini: [hint:Mirror] msgid "" @@ -17976,8 +17976,8 @@ msgid "" msgstr "" "Люстраваць\n" "Ці ведаеце вы, што вы можаце люстраваць абраную мадэль, каб стварыць яе " -"зваротную версію? Пстрыкніце правай кнопкай мышы на мадэль, абярыце " -"Люстраваць і абярыце вось." +"зваротную версію? Пстрыкніце правай кнопкай мышы на мадэль, абярыце " +"Люстраваць і абярыце вось." #: resources/data/hints.ini: [hint:PageUp / PageDown quick rotation by 45 #: degrees] @@ -18056,7 +18056,7 @@ msgid "" msgstr "" "Уставіць прыпынак\n" "Ці ведаеце вы, што вы можаце запланаваць прыпынак друку на поэным пласту? " -"Пстрыкніце правай кнопкай мышы на паўзунке пласта ў акне папярэдняга " +"Пстрыкніце правай кнопкай мышы на паўзунке пласта ў акне папярэдняга " "прагляду і абярыце \"Дадаць прыпынак друку\" (M601). Можна ўжываць для " "ўстаўкі ў ўстаўкі магнітаў, грузікаў ці гаек увашыя мадэлі. Больш падрабязна " "чытайце ў дакументацыі." @@ -18071,9 +18071,9 @@ msgid "" msgstr "" "Карыстальніцкі G-код\n" "Ці ведаеце вы, што вы можаце ўставіць карыстальніцкі G-код на пэўным пласту? " -"Пстрыкніце левай кнопкай мышы на пласт у акне папярэдняга прагляду, " -"пстрыкніце правай кнопкай мышы гузік плюсу і абярыце Дадаць " -"карыстальніцкі G-код. З дапамогай гэтай функцыі можна, напрыклад, " +"Пстрыкніце левай кнопкай мышы на пласт у акне папярэдняга прагляду, " +"пстрыкніце правай кнопкай мышы гузік плюсу і абярыце Дадаць " +"карыстальніцкі G-код. З дапамогай гэтай функцыі можна, напрыклад, " "стварыць тэмпературную вежу. Больш падрабязна чытайце ў дакументацыі." #: resources/data/hints.ini: [hint:Configuration snapshots] @@ -18111,8 +18111,8 @@ msgstr "" "Налады ў асобным акне\n" "Ці ведаеце вы, што вы можаце адчыніць налады ў новым немадальным акне? Гэта " "значыць, што налады можна адчыніць на адным экране, а папярэдні прагляд G-" -"кода на іншчым. Перайдзіце ў Перавагі і абярыце Налады будуць " -"адлюстроўвацца ў асобным акне." +"кода на іншчым. Перайдзіце ў Перавагі і абярыце Налады будуць " +"адлюстроўвацца ў асобным акне." #: resources/data/hints.ini: [hint:Adaptive infills] msgid "" @@ -19531,7 +19531,7 @@ msgstr "Колер фону" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:52 msgid "Backspace" -msgstr "Backspace" +msgstr "Backspace" #: ../src/common/fmapbase.cpp:160 msgid "Baltic (ISO-8859-13)" @@ -20904,7 +20904,7 @@ msgstr "Канец" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:55 msgid "Enter" -msgstr "Enter" +msgstr "Enter" #: ../src/richtext/richtextstyledlg.cpp:934 msgid "Enter a box style name" @@ -20991,7 +20991,7 @@ msgstr "Памылка: " #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:69 msgid "Esc" -msgstr "Esc" +msgstr "Esc" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:70 @@ -22180,7 +22180,7 @@ msgstr "Ініцыялізацыя не атрымалася ў post init, пе #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:54 msgid "Ins" -msgstr "Ins" +msgstr "Ins" #. TRANSLATORS: Name of keyboard key #: ../src/richtext/richtextsymboldlg.cpp:472 ../src/common/accelcmn.cpp:53 @@ -22879,7 +22879,7 @@ msgstr "&Згарнуць" #. TRANSLATORS: System cursor name #: ../src/propgrid/advprops.cpp:1763 msgid "Middle Button" -msgstr "Сярэдняя кнопка" +msgstr "Сярэдняя кнопка" #: ../src/richtext/richtextsizepage.cpp:409 msgid "Min height:" @@ -23111,117 +23111,117 @@ msgstr "Заўвага, 8 1/2 x 11 цалі" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:105 msgid "Num *" -msgstr "Num *" +msgstr "Num *" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:106 msgid "Num +" -msgstr "Num +" +msgstr "Num +" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:107 msgid "Num ," -msgstr "Num ," +msgstr "Num ," #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:108 msgid "Num -" -msgstr "Num -" +msgstr "Num -" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:109 msgid "Num ." -msgstr "Num ." +msgstr "Num ." #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:110 msgid "Num /" -msgstr "Num /" +msgstr "Num /" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:104 msgid "Num =" -msgstr "Num =" +msgstr "Num =" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:101 msgid "Num Begin" -msgstr "Num Begin" +msgstr "Num Begin" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:103 msgid "Num Delete" -msgstr "Num Delete" +msgstr "Num Delete" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:95 msgid "Num Down" -msgstr "Num Down" +msgstr "Num Down" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:100 msgid "Num End" -msgstr "Num End" +msgstr "Num End" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:90 msgid "Num Enter" -msgstr "Num Enter" +msgstr "Num Enter" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:91 msgid "Num Home" -msgstr "Num Home" +msgstr "Num Home" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:102 msgid "Num Insert" -msgstr "Num Insert" +msgstr "Num Insert" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:86 msgid "Num Lock" -msgstr "Num Lock" +msgstr "Num Lock" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:97 msgid "Num Page Down" -msgstr "Num Page Down" +msgstr "Num Page Down" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:96 msgid "Num Page Up" -msgstr "Num Page Up" +msgstr "Num Page Up" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:94 msgid "Num Right" -msgstr "Num Right" +msgstr "Num Right" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:88 msgid "Num Space" -msgstr "Num Space" +msgstr "Num Space" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:89 msgid "Num Tab" -msgstr "Num Tab" +msgstr "Num Tab" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:93 msgid "Num Up" -msgstr "Num Up" +msgstr "Num Up" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:92 msgid "Num left" -msgstr "Num left" +msgstr "Num left" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:86 msgid "Num_lock" -msgstr "Num_lock" +msgstr "Num_lock" #: ../src/richtext/richtextliststylepage.cpp:487 #: ../src/richtext/richtextbulletspage.cpp:279 @@ -23490,12 +23490,12 @@ msgstr "Налады старонкі" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:58 msgid "PageDown" -msgstr "PageDown" +msgstr "PageDown" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:57 msgid "PageUp" -msgstr "PageUp" +msgstr "PageUp" #: ../src/generic/prntdlgg.cpp:216 msgid "Pages" @@ -23545,12 +23545,12 @@ msgstr "Дазволы" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:60 msgid "PgDn" -msgstr "PgDn" +msgstr "PgDn" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:59 msgid "PgUp" -msgstr "PgUp" +msgstr "PgUp" #: ../src/richtext/richtextbuffer.cpp:12868 msgid "Picture Properties" @@ -25636,17 +25636,17 @@ msgstr "Кірыліца Windows/DOS OEM (CP 866)" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:111 msgid "Windows_Left" -msgstr "Windows_Left" +msgstr "Windows_Left" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:113 msgid "Windows_Menu" -msgstr "Windows_Menu" +msgstr "Windows_Menu" #. TRANSLATORS: Name of keyboard key #: ../src/common/accelcmn.cpp:112 msgid "Windows_Right" -msgstr "Windows_Right" +msgstr "Windows_Right" #: ../src/common/ffile.cpp:150 #, c-format @@ -25709,7 +25709,7 @@ msgstr "Вы не можаце дадаць новы каталог у гэту #: ../src/propgrid/propgrid.cpp:3299 msgid "You have entered invalid value. Press ESC to cancel editing." msgstr "" -"Вы ўвялі недапушчальнае значэнне. Націсніце Esc, каб адмяніць змены." +"Вы ўвялі недапушчальнае значэнне. Націсніце ESC, каб адмяніць змены." #: ../src/common/stockitem.cpp:209 msgid "Zoom &In" diff --git a/resources/localization/cs/PrusaSlicer.mo b/resources/localization/cs/PrusaSlicer.mo index fa1b4c8fac..e80adb4755 100644 Binary files a/resources/localization/cs/PrusaSlicer.mo and b/resources/localization/cs/PrusaSlicer.mo differ diff --git a/resources/profiles/Anycubic.idx b/resources/profiles/Anycubic.idx index a941cef9c2..24c53137e4 100644 --- a/resources/profiles/Anycubic.idx +++ b/resources/profiles/Anycubic.idx @@ -1,4 +1,5 @@ -min_slic3r_version = 2.6.0-alpha4 +min_slic3r_version = 2.6.0-beta1 +0.2.5 Fixed output file format for MONO SE. 0.2.4 Enable pad for Anycubic SLA profiles 0.2.3 Added Photon Mono printer. 0.2.2 Added Photon Mono SE printer. diff --git a/resources/profiles/Anycubic.ini b/resources/profiles/Anycubic.ini index 771b38d012..46d82cefe6 100644 --- a/resources/profiles/Anycubic.ini +++ b/resources/profiles/Anycubic.ini @@ -5,7 +5,7 @@ name = Anycubic # 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. -config_version = 0.2.1 +config_version = 0.2.5 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/ # changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -2386,7 +2386,7 @@ output_filename_format = [input_filename_base].pwmx [sla_print:0.05 Normal @ANYCUBIC MONO SE] inherits = 0.05 Normal @ANYCUBIC ABSTRACT compatible_printers_condition = printer_notes=~/.*PHOTONMONOSE\n.*/ -output_filename_format = [input_filename_base].pwma +output_filename_format = [input_filename_base].pwms ## SLA materials @@ -2497,4 +2497,5 @@ max_initial_exposure_time = 300 printer_correction = 1,1,1 gamma_correction = 1 area_fill = 45 -printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONOX\nPRINTER_TECHNOLOGY_SLA\n \ No newline at end of file +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONOX\nPRINTER_TECHNOLOGY_SLA\n + diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index 9f9ecebadc..54d2615903 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,4 +1,5 @@ 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-beta2 Added profiles for Original Prusa MK4 Input Shaper (Alpha). min_slic3r_version = 2.6.0-beta0 diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 3150d0032e..5d4f33e979 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -5,7 +5,7 @@ name = Prusa Research # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.9.0-beta3 +config_version = 1.9.0 # Where to get the updates from? 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% diff --git a/resources/profiles/PrusaResearch/MK2.5MMU2_thumbnail.png b/resources/profiles/PrusaResearch/MK2.5MMU2_thumbnail.png index 7d6e9feded..4affdf8abc 100644 Binary files a/resources/profiles/PrusaResearch/MK2.5MMU2_thumbnail.png and b/resources/profiles/PrusaResearch/MK2.5MMU2_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK2.5SMMU2S_thumbnail.png b/resources/profiles/PrusaResearch/MK2.5SMMU2S_thumbnail.png index 7d6e9feded..058a5d07da 100644 Binary files a/resources/profiles/PrusaResearch/MK2.5SMMU2S_thumbnail.png and b/resources/profiles/PrusaResearch/MK2.5SMMU2S_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK2.5S_thumbnail.png b/resources/profiles/PrusaResearch/MK2.5S_thumbnail.png index d9bf3260d4..ef62a4512b 100644 Binary files a/resources/profiles/PrusaResearch/MK2.5S_thumbnail.png and b/resources/profiles/PrusaResearch/MK2.5S_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK2.5_thumbnail.png b/resources/profiles/PrusaResearch/MK2.5_thumbnail.png index d9bf3260d4..9465e5e0ac 100644 Binary files a/resources/profiles/PrusaResearch/MK2.5_thumbnail.png and b/resources/profiles/PrusaResearch/MK2.5_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK3MMU2_thumbnail.png b/resources/profiles/PrusaResearch/MK3MMU2_thumbnail.png index eb5dccf08c..ad913624a6 100644 Binary files a/resources/profiles/PrusaResearch/MK3MMU2_thumbnail.png and b/resources/profiles/PrusaResearch/MK3MMU2_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK3SMMU2S_thumbnail.png b/resources/profiles/PrusaResearch/MK3SMMU2S_thumbnail.png index eb5dccf08c..ad41b7bd6d 100644 Binary files a/resources/profiles/PrusaResearch/MK3SMMU2S_thumbnail.png and b/resources/profiles/PrusaResearch/MK3SMMU2S_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK3S_thumbnail.png b/resources/profiles/PrusaResearch/MK3S_thumbnail.png index 8a859b82e7..559888aa06 100644 Binary files a/resources/profiles/PrusaResearch/MK3S_thumbnail.png and b/resources/profiles/PrusaResearch/MK3S_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch/MK4_thumbnail.png b/resources/profiles/PrusaResearch/MK4_thumbnail.png index 2b729f930c..7602b0c3a2 100644 Binary files a/resources/profiles/PrusaResearch/MK4_thumbnail.png and b/resources/profiles/PrusaResearch/MK4_thumbnail.png differ diff --git a/src/libslic3r/Algorithm/RegionExpansion.cpp b/src/libslic3r/Algorithm/RegionExpansion.cpp index e36f5e62c7..ee2a5aaf2a 100644 --- a/src/libslic3r/Algorithm/RegionExpansion.cpp +++ b/src/libslic3r/Algorithm/RegionExpansion.cpp @@ -480,10 +480,8 @@ std::vector expand_expolygons(const ExPolygons &src, const ExPolygons return out; } -std::vector expand_merge_expolygons(ExPolygons &&src, const ExPolygons &boundary, const RegionExpansionParameters ¶ms) +std::vector merge_expansions_into_expolygons(ExPolygons &&src, std::vector &&expanded) { - // expanded regions are sorted by boundary id and source id - std::vector expanded = propagate_waves(src, boundary, params); // expanded regions will be merged into source regions, thus they will be re-sorted by source id. std::sort(expanded.begin(), expanded.end(), [](const auto &l, const auto &r) { return l.src_id < r.src_id; }); uint32_t last = 0; @@ -535,5 +533,12 @@ std::vector expand_merge_expolygons(ExPolygons &&src, const ExPolygon return out; } +std::vector expand_merge_expolygons(ExPolygons &&src, const ExPolygons &boundary, const RegionExpansionParameters ¶ms) +{ + // expanded regions are sorted by boundary id and source id + std::vector expanded = propagate_waves(src, boundary, params); + return merge_expansions_into_expolygons(std::move(src), std::move(expanded)); +} + } // Algorithm } // Slic3r diff --git a/src/libslic3r/Algorithm/RegionExpansion.hpp b/src/libslic3r/Algorithm/RegionExpansion.hpp index 26aab198a3..eb99674902 100644 --- a/src/libslic3r/Algorithm/RegionExpansion.hpp +++ b/src/libslic3r/Algorithm/RegionExpansion.hpp @@ -72,6 +72,7 @@ struct RegionExpansion }; std::vector propagate_waves(const WaveSeeds &seeds, const ExPolygons &boundary, const RegionExpansionParameters ¶ms); +std::vector propagate_waves(const ExPolygons &src, const ExPolygons &boundary, const RegionExpansionParameters ¶ms); std::vector propagate_waves(const ExPolygons &src, const ExPolygons &boundary, // Scaled expansion value @@ -106,6 +107,9 @@ std::vector expand_expolygons(const ExPolygons &src, const ExPolygons // Don't take more than max_nr_steps for small expansion_step. size_t max_nr_steps); +// Merge src with expansions, return the merged expolygons. +std::vector merge_expansions_into_expolygons(ExPolygons &&src, std::vector &&expanded); + std::vector expand_merge_expolygons(ExPolygons &&src, const ExPolygons &boundary, const RegionExpansionParameters ¶ms); } // Algorithm diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 6042c6ded4..ea71a1a55f 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -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::lowest() + 2 * bed.center.x()) / 4.01); + C My = C((std::numeric_limits::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 Slic3r diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 874742ecb5..f705a1ad85 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -55,6 +55,25 @@ struct IrregularBed { using ArrangeBed = boost::variant; +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(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); /// A logical bed representing an object not being arranged. Either the arrange diff --git a/src/libslic3r/ExtrusionRole.hpp b/src/libslic3r/ExtrusionRole.hpp index 5952d3fc56..986c139a24 100644 --- a/src/libslic3r/ExtrusionRole.hpp +++ b/src/libslic3r/ExtrusionRole.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace Slic3r { diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 5a6c2d5bec..64a49cc7e8 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1065,6 +1065,9 @@ void GCodeProcessor::process_file(const std::string& filename, std::function, 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 g1_feedrate = std::nullopt; + if (line.has_f()) g1_feedrate = (double)line.f(); + std::optional 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, 4>& axes, std::optional feedrate, std::optional cmt) { const float filament_diameter = (static_cast(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 area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); auto move_type = [this](const AxisCoords& delta_pos) { - EMoveType type = EMoveType::Noop; - if (m_wiping) - type = EMoveType::Wipe; + return EMoveType::Wipe; 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) { 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) - type = EMoveType::Extrude; - } + return EMoveType::Extrude; + } 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 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; @@ -2383,27 +2416,26 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // updates axes positions from line 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 - if (line.has_f()) - m_feedrate = m_feed_multiply.current * line.f() * MMMIN_TO_MMSEC; + if (feedrate.has_value()) + m_feedrate = m_feed_multiply.current * (*feedrate) * MMMIN_TO_MMSEC; - // calculates movement deltas - AxisCoords delta_pos; + // calculates movement deltas + AxisCoords delta_pos; 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.; })) - return; - + return; + const float volume_extruded_filament = area_filament_cross_section * delta_pos[E]; if (volume_extruded_filament != 0.) - m_used_filaments.increase_caches(volume_extruded_filament, - m_extruder_id, area_filament_cross_section * m_parking_position, - area_filament_cross_section * m_extra_loading_move); + m_used_filaments.increase_caches(volume_extruded_filament, m_extruder_id, area_filament_cross_section * m_parking_position, + area_filament_cross_section * m_extra_loading_move); const EMoveType type = move_type(delta_pos); if (type == EMoveType::Extrude) { @@ -2420,7 +2452,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) m_height = m_forced_height; else if (m_layer_id == 0) 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) 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)) 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_options_z_corrector.update(m_height); @@ -2464,7 +2496,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // time estimate section 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]); }; @@ -2485,8 +2517,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) TimeMachine::State& prev = machine.prev; std::vector& blocks = machine.blocks; - curr.feedrate = (delta_pos[E] == 0.0f) ? - minimum_travel_feedrate(static_cast(i), m_feedrate) : + curr.feedrate = (delta_pos[E] == 0.0f) ? minimum_travel_feedrate(static_cast(i), m_feedrate) : minimum_feedrate(static_cast(i), m_feedrate); TimeBlock block; @@ -2521,11 +2552,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } // calculates block acceleration - float acceleration = - (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) : - (is_extrusion_only_move(delta_pos) ? - get_retract_acceleration(static_cast(i)) : - get_acceleration(static_cast(i))); + float acceleration = (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) : + (is_extrusion_only_move(delta_pos) ? get_retract_acceleration(static_cast(i)) : + get_acceleration(static_cast(i))); for (unsigned char a = X; a <= E; ++a) { const float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); @@ -2551,8 +2580,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // calculates block entry feedrate float vmax_junction = curr.safe_feedrate; if (!blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD) { - 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 bool prev_speed_larger = 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. 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. const float jerk = - (v_exit > v_entry) ? - ((v_entry > 0.0f || v_exit < 0.0f) ? - // coasting - (v_exit - v_entry) : - // axis reversal - std::max(v_exit, -v_entry)) : - // v_exit <= v_entry - ((v_entry < 0.0f || v_exit > 0.0f) ? - // coasting - (v_entry - v_exit) : - // axis reversal - std::max(-v_exit, v_entry)); + (v_exit > v_entry) ? + ((v_entry > 0.0f || v_exit < 0.0f) ? + // coasting + (v_exit - v_entry) : + // axis reversal + std::max(v_exit, -v_entry)) : + // v_exit <= v_entry + ((v_entry < 0.0f || v_exit > 0.0f) ? + // coasting + (v_entry - v_exit) : + // axis reversal + std::max(-v_exit, v_entry)); const float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); if (jerk > axis_max_jerk) { @@ -2664,7 +2693,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } // 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) @@ -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 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 end_radius() const { return (end - center).norm(); } @@ -2778,18 +2807,18 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc return ret; }; - auto internal_only_g1_line = [](const AxisCoords& target, bool has_z, const std::optional& feedrate, const std::optional& extrusion) { - std::string ret = (boost::format("G1 X%1% Y%2%") % target[X] % target[Y]).str(); + auto internal_only_g1_line = [this](const AxisCoords& target, bool has_z, const std::optional& feedrate, const std::optional& extrusion) { + std::array, 4> g1_axes = { target[X], target[Y], std::nullopt, std::nullopt }; + std::optional g1_feedrate = std::nullopt; if (has_z) - ret += (boost::format(" Z%1%") % target[Z]).str(); + g1_axes[Z] = target[Z]; if (feedrate.has_value()) - ret += (boost::format(" F%1%") % *feedrate).str(); + g1_feedrate = (double)*feedrate; if (extrusion.has_value()) - ret += (boost::format(" E%1%") % target[E]).str(); + g1_axes[E] = target[E]; + std::optional g1_cmt = INTERNAL_G2G3_TAG; - ret += (boost::format(" ;%1%\n") % INTERNAL_G2G3_TAG).str(); - - return ret; + process_G1(g1_axes, g1_feedrate, g1_cmt); }; // 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 // segments count - static const double MM_PER_ARC_SEGMENT = 0.5; - const size_t segments = std::ceil(travel_length / MM_PER_ARC_SEGMENT); - assert(segments >= 1); + static const double MM_PER_ARC_SEGMENT = 1.0; + const size_t segments = std::max(std::floor(travel_length / MM_PER_ARC_SEGMENT), 1); - const double theta_per_segment = arc.angle / double(segments); - const double z_per_segment = arc.delta_z() / double(segments); - const double extruder_per_segment = (extrusion.has_value()) ? *extrusion / double(segments) : 0.0; + const double inv_segment = 1.0 / double(segments); + const double theta_per_segment = arc.angle * inv_segment; + 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 * sq_theta_per_segment; // Small angle approximation - const double sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6.0; // Small angle approximation + const double cos_T = 1.0 - 0.5 * sqr(theta_per_segment); // Small angle approximation + const double sin_T = theta_per_segment; AxisCoords prev_target = m_start_position; 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]; static const size_t N_ARC_CORRECTION = 25; - Vec3d curr_rel_arc_start = arc.relative_start(); - - std::string gcode; - - size_t n_arc_correction = N_ARC_CORRECTION; + size_t count = 0; for (size_t i = 1; i < segments; ++i) { - if (n_arc_correction-- == 0) { - // Calculate the actual position for r_axis_x and r_axis_y - 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 + if (count < N_ARC_CORRECTION) { + // Apply vector rotation matrix 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.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 @@ -2850,23 +2875,14 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc arc_target[Z] += z_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; - - // feedrate is constant, we do not need to repeat it - feedrate.reset(); } // 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); - - // 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); - }); + 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); } void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 90d52c231a..fcba4321ae 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -680,6 +680,8 @@ namespace Slic3r { // Move void process_G0(const GCodeReader::GCodeLine& line); void process_G1(const GCodeReader::GCodeLine& line); + void process_G1(const std::array, 4>& axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt }, + std::optional feedrate = std::nullopt, std::optional cmt = std::nullopt); // Arc Move void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise); diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 9485998dc4..73f225c577 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -170,7 +170,9 @@ static ExPolygons fill_surfaces_extract_expolygons(Surfaces &surfaces, std::init Surfaces expand_bridges_detect_orientations( Surfaces &surfaces, ExPolygons &shells, - const Algorithm::RegionExpansionParameters &expansion_params, + const Algorithm::RegionExpansionParameters &expansion_params_into_solid_infill, + ExPolygons &sparse, + const Algorithm::RegionExpansionParameters &expansion_params_into_sparse_infill, const float closing_radius) { using namespace Slic3r::Algorithm; @@ -181,8 +183,23 @@ Surfaces expand_bridges_detect_orientations( return {}; // Calculate bridge anchors and their expansions in their respective shell region. - WaveSeeds bridge_anchors = wave_seeds(bridges_ex, shells, expansion_params.tiny_expansion, true); - std::vector bridge_expansions = propagate_waves_ex(bridge_anchors, shells, expansion_params); + WaveSeeds bridge_anchors = wave_seeds(bridges_ex, shells, expansion_params_into_solid_infill.tiny_expansion, true); + std::vector bridge_expansions = propagate_waves_ex(bridge_anchors, shells, expansion_params_into_solid_infill); + bool expanded_into_shells = ! bridge_expansions.empty(); + bool expanded_into_sparse = false; + { + WaveSeeds bridge_anchors_sparse = wave_seeds(bridges_ex, sparse, expansion_params_into_sparse_infill.tiny_expansion, true); + std::vector bridge_expansions_sparse = propagate_waves_ex(bridge_anchors_sparse, sparse, expansion_params_into_sparse_infill); + if (! bridge_expansions_sparse.empty()) { + expanded_into_sparse = true; + for (WaveSeed &seed : bridge_anchors_sparse) + seed.boundary += uint32_t(shells.size()); + for (RegionExpansionEx &expansion : bridge_expansions_sparse) + expansion.boundary_id += uint32_t(shells.size()); + append(bridge_anchors, std::move(bridge_anchors_sparse)); + append(bridge_expansions, std::move(bridge_expansions_sparse)); + } + } // Cache for detecting bridge orientation and merging regions with overlapping expansions. struct Bridge { @@ -259,7 +276,7 @@ Surfaces expand_bridges_detect_orientations( 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)) { last_anchor_id = int(it_bridge_anchor->boundary); - append(anchor_areas, to_polygons(shells[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) { // reserve_more_power_of_2(lines, polyline.size() - 1); @@ -270,17 +287,18 @@ Surfaces expand_bridges_detect_orientations( lines = to_lines(diff_pl(to_polylines(bridge.expolygon), expand(anchor_areas, float(SCALED_EPSILON)))); auto [bridging_dir, unsupported_dist] = detect_bridging_direction(lines, to_polygons(bridge.expolygon)); bridge.angle = M_PI + std::atan2(bridging_dir.y(), bridging_dir.x()); - // #if 1 - // coordf_t stroke_width = scale_(0.06); - // BoundingBox bbox = get_extents(initial); - // bbox.offset(scale_(1.)); - // ::Slic3r::SVG - // svg(debug_out_path(("bridge"+std::to_string(bridges[idx_last].bridge_angle)+"_"+std::to_string(this->layer()->bottom_z())).c_str()), - // bbox); - - // svg.draw(initial, "cyan"); - // svg.draw(to_lines(lower_layer->lslices), "green", stroke_width); - // #endif +#if 0 + coordf_t stroke_width = scale_(0.06); + BoundingBox bbox = get_extents(anchor_areas); + bbox.merge(get_extents(bridge.expolygon)); + bbox.offset(scale_(1.)); + ::Slic3r::SVG + svg(debug_out_path(("bridge" + std::to_string(bridge.angle) + "_" /* + std::to_string(this->layer()->bottom_z())*/).c_str()), + bbox); + svg.draw(bridge.expolygon, "cyan"); + svg.draw(lines, "green", stroke_width); + svg.draw(anchor_areas, "red"); +#endif } } @@ -322,8 +340,11 @@ Surfaces expand_bridges_detect_orientations( } } - // Clip the shells by the expanded bridges. - shells = diff_ex(shells, out); + // Clip by the expanded bridges. + if (expanded_into_shells) + shells = diff_ex(shells, out); + if (expanded_into_sparse) + sparse = diff_ex(sparse, out); return out; } @@ -332,23 +353,43 @@ Surfaces expand_bridges_detect_orientations( static Surfaces expand_merge_surfaces( Surfaces &surfaces, SurfaceType surface_type, - ExPolygons &shells, - const Algorithm::RegionExpansionParameters ¶ms, + ExPolygons &shells, + const Algorithm::RegionExpansionParameters &expansion_params_into_solid_infill, + ExPolygons &sparse, + const Algorithm::RegionExpansionParameters &expansion_params_into_sparse_infill, const float closing_radius, const double bridge_angle = -1.) { + using namespace Slic3r::Algorithm; + double thickness; ExPolygons src = fill_surfaces_extract_expolygons(surfaces, {surface_type}, thickness); if (src.empty()) return {}; - std::vector expanded = expand_merge_expolygons(std::move(src), shells, params); + std::vector expansions = propagate_waves(src, shells, expansion_params_into_solid_infill); + bool expanded_into_shells = !expansions.empty(); + bool expanded_into_sparse = false; + { + std::vector expansions2 = propagate_waves(src, sparse, expansion_params_into_sparse_infill); + if (! expansions2.empty()) { + expanded_into_sparse = true; + for (RegionExpansion &expansion : expansions2) + expansion.boundary_id += uint32_t(shells.size()); + append(expansions, std::move(expansions2)); + } + } + + std::vector expanded = merge_expansions_into_expolygons(std::move(src), std::move(expansions)); //NOTE: The current regularization of the shells can create small unasigned regions in the object (E.G. benchy) // without the following closing operation, those regions will stay unfilled and cause small holes in the expanded surface. // look for narrow_ensure_vertical_wall_thickness_region_radius filter. expanded = closing_ex(expanded, closing_radius); // Trim the shells by the expanded expolygons. - shells = diff_ex(shells, expanded); + if (expanded_into_shells) + shells = diff_ex(shells, expanded); + if (expanded_into_sparse) + sparse = diff_ex(sparse, expanded); Surface templ{ surface_type, {} }; templ.bridge_angle = bridge_angle; @@ -361,20 +402,25 @@ static Surfaces expand_merge_surfaces( void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered) { + using namespace Slic3r::Algorithm; + #ifdef SLIC3R_DEBUG_SLICE_PROCESSING export_region_fill_surfaces_to_svg_debug("4_process_external_surfaces-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ // Width of the perimeters. float shell_width = 0; + float expansion_min = 0; if (int num_perimeters = this->region().config().perimeters; num_perimeters > 0) { Flow external_perimeter_flow = this->flow(frExternalPerimeter); Flow perimeter_flow = this->flow(frPerimeter); - shell_width += 0.5f * external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing(); + shell_width = 0.5f * external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing(); shell_width += perimeter_flow.scaled_spacing() * (num_perimeters - 1); + expansion_min = perimeter_flow.scaled_spacing(); } else { // TODO: Maybe there is better solution when printing with zero perimeters, but this works reasonably well, given the situation - shell_width = float(SCALED_EPSILON); + shell_width = float(SCALED_EPSILON); + expansion_min = float(SCALED_EPSILON);; } // Scaled expansions of the respective external surfaces. @@ -390,16 +436,18 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly // Expand the top / bottom / bridge surfaces into the shell thickness solid infills. double layer_thickness; - ExPolygons shells = union_ex(fill_surfaces_extract_expolygons(m_fill_surfaces.surfaces, {stInternalSolid}, layer_thickness)); + ExPolygons shells = union_ex(fill_surfaces_extract_expolygons(m_fill_surfaces.surfaces, { stInternalSolid }, layer_thickness)); + ExPolygons sparse = union_ex(fill_surfaces_extract_expolygons(m_fill_surfaces.surfaces, { stInternal }, layer_thickness)); SurfaceCollection bridges; + const auto expansion_params_into_sparse_infill = RegionExpansionParameters::build(expansion_min, expansion_step, max_nr_expansion_steps); { BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges. layer" << this->layer()->print_z; const double custom_angle = this->region().config().bridge_angle.value; - const auto params = Algorithm::RegionExpansionParameters::build(expansion_bottom_bridge, expansion_step, max_nr_expansion_steps); + const auto expansion_params_into_solid_infill = RegionExpansionParameters::build(expansion_bottom_bridge, expansion_step, max_nr_expansion_steps); bridges.surfaces = custom_angle > 0 ? - expand_merge_surfaces(m_fill_surfaces.surfaces, stBottomBridge, shells, params, closing_radius, Geometry::deg2rad(custom_angle)) : - expand_bridges_detect_orientations(m_fill_surfaces.surfaces, shells, params, closing_radius); + expand_merge_surfaces(m_fill_surfaces.surfaces, stBottomBridge, shells, expansion_params_into_solid_infill, sparse, expansion_params_into_sparse_infill, closing_radius, Geometry::deg2rad(custom_angle)) : + expand_bridges_detect_orientations(m_fill_surfaces.surfaces, shells, expansion_params_into_solid_infill, sparse, expansion_params_into_sparse_infill, closing_radius); BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges - done"; #if 0 { @@ -410,15 +458,25 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly } Surfaces bottoms = expand_merge_surfaces(m_fill_surfaces.surfaces, stBottom, shells, - Algorithm::RegionExpansionParameters::build(expansion_bottom, expansion_step, max_nr_expansion_steps), closing_radius); + RegionExpansionParameters::build(expansion_bottom, expansion_step, max_nr_expansion_steps), + sparse, expansion_params_into_sparse_infill, closing_radius); Surfaces tops = expand_merge_surfaces(m_fill_surfaces.surfaces, stTop, shells, - Algorithm::RegionExpansionParameters::build(expansion_top, expansion_step, max_nr_expansion_steps), closing_radius); + RegionExpansionParameters::build(expansion_top, expansion_step, max_nr_expansion_steps), + sparse, expansion_params_into_sparse_infill, closing_radius); - m_fill_surfaces.remove_types({ stBottomBridge, stBottom, stTop, stInternalSolid }); - reserve_more(m_fill_surfaces.surfaces, shells.size() + bridges.size() + bottoms.size() + tops.size()); - Surface solid_templ(stInternalSolid, {}); - solid_templ.thickness = layer_thickness; - m_fill_surfaces.append(std::move(shells), solid_templ); +// m_fill_surfaces.remove_types({ stBottomBridge, stBottom, stTop, stInternal, stInternalSolid }); + m_fill_surfaces.clear(); + reserve_more(m_fill_surfaces.surfaces, shells.size() + sparse.size() + bridges.size() + bottoms.size() + tops.size()); + { + Surface solid_templ(stInternalSolid, {}); + solid_templ.thickness = layer_thickness; + m_fill_surfaces.append(std::move(shells), solid_templ); + } + { + Surface sparse_templ(stInternal, {}); + sparse_templ.thickness = layer_thickness; + m_fill_surfaces.append(std::move(sparse), sparse_templ); + } m_fill_surfaces.append(std::move(bridges.surfaces)); m_fill_surfaces.append(std::move(bottoms)); m_fill_surfaces.append(std::move(tops)); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 8002d46d71..3a5e9a0d48 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -510,6 +510,8 @@ public: bool has_solid_mesh() const; // Detect if object has at least one negative volume mash 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 has_connectors() const; diff --git a/src/libslic3r/PNGReadWrite.hpp b/src/libslic3r/PNGReadWrite.hpp index 01e1f47450..399c622438 100644 --- a/src/libslic3r/PNGReadWrite.hpp +++ b/src/libslic3r/PNGReadWrite.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace Slic3r { namespace png { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 13625748a1..f42b3f7708 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -2240,7 +2240,7 @@ namespace PresetUtils { { const VendorProfile::PrinterModel *out = nullptr; if (preset.vendor != nullptr) { - auto *printer_model = preset.config.opt("printer_model"); + const auto *printer_model = preset.config.opt("printer_model"); 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; }); if (it != preset.vendor->models.end()) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a8cc410ab7..ca8aa76d35 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -68,7 +68,7 @@ static const t_config_enum_values s_keys_map_PrintHostType { { "prusalink", htPrusaLink }, { "prusaconnect", htPrusaConnect }, { "octoprint", htOctoPrint }, - { "mainsail", htMainSail }, + { "moonraker", htMoonraker }, { "duet", htDuet }, { "flashair", htFlashAir }, { "astrobox", htAstroBox }, @@ -1953,7 +1953,7 @@ void PrintConfigDef::init_fff_params() { "prusalink", "PrusaLink" }, { "prusaconnect", "PrusaConnect" }, { "octoprint", "OctoPrint" }, - { "mainsail", "Mainsail/Fluidd" }, + { "moonraker", "Klipper (via Moonraker)" }, { "duet", "Duet" }, { "flashair", "FlashAir" }, { "astrobox", "AstroBox" }, @@ -4214,6 +4214,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va else if (value == "marlinfirmware") // the "new" marlin firmware flavor used to be called "marlinfirmware" for some time during PrusaSlicer 2.4.0-alpha development. value = "marlin2"; + } else if (opt_key == "host_type" && value == "mainsail") { + // the "mainsail" key (introduced in 2.6.0-alpha6) was renamed to "moonraker" (in 2.6.0-rc1). + value = "moonraker"; } else if (opt_key == "fill_density" && value.find("%") == std::string::npos) { try { // fill_density was turned into a percent value diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 36a63d33d2..54a835fe79 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -44,7 +44,7 @@ enum class MachineLimitsUsage { }; enum PrintHostType { - htPrusaLink, htPrusaConnect, htOctoPrint, htMainSail, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS + htPrusaLink, htPrusaConnect, htOctoPrint, htMoonraker, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS }; enum AuthorizationType { diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index f9fa624fec..ff7906da07 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -981,11 +981,12 @@ void PrintObject::detect_surfaces_type() surface_type_bottom_other); #else // Any surface lying on the void is a true bottom bridge (an overhang) - ExPolygons true_bridge = diff_ex(layerm->slices().surfaces, lower_layer->lslices, ApplySafetyOffset::Yes); - // expand the bridges by one extrusion width, to ensure reasonable anchoring whenever possible - true_bridge = intersection_ex(layerm->slices().surfaces, - offset_ex(true_bridge, layerm->bridging_flow(frSolidInfill).scaled_spacing())); - surfaces_append(bottom, true_bridge, surface_type_bottom_other); + surfaces_append( + bottom, + opening_ex( + diff_ex(layerm->slices().surfaces, lower_layer->lslices, ApplySafetyOffset::Yes), + offset), + surface_type_bottom_other); // if user requested internal shells, we need to identify surfaces // lying on other slices not belonging to this region if (interface_shells) { diff --git a/src/libslic3r/Thread.cpp b/src/libslic3r/Thread.cpp index 924fbe9223..f040750274 100644 --- a/src/libslic3r/Thread.cpp +++ b/src/libslic3r/Thread.cpp @@ -211,6 +211,12 @@ bool is_main_thread_active() 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. // 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() @@ -274,16 +280,16 @@ void set_current_thread_qos() #endif // __APPLE__ } -void TBBLocalesSetter::on_scheduler_entry(bool is_worker) +void ThreadData::tbb_worker_thread_set_c_locales() { // static std::atomic cnt = 0; // 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_c_locales(); // OSX specific: Elevate QOS on Apple Silicon. set_current_thread_qos(); - is_locales_sets = true; + m_tbb_worker_thread_c_locales_set = true; } } diff --git a/src/libslic3r/Thread.hpp b/src/libslic3r/Thread.hpp index 19ad29801c..61629addfb 100644 --- a/src/libslic3r/Thread.hpp +++ b/src/libslic3r/Thread.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,27 @@ template inline boost::thread create_thread(Fn &&fn) return create_thread(attrs, std::forward(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 // 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 @@ -79,11 +101,7 @@ class TBBLocalesSetter : public tbb::task_scheduler_observer public: TBBLocalesSetter() { this->observe(true); } ~TBBLocalesSetter() override { this->observe(false); }; - - void on_scheduler_entry(bool is_worker) override; - -private: - tbb::enumerable_thread_specific, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{ false }; + void on_scheduler_entry(bool /* is_worker */) override { thread_data().tbb_worker_thread_set_c_locales(); } }; } diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index af851cc4af..02d12be3f4 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -255,8 +255,8 @@ set(SLIC3R_GUI_SOURCES Utils/Http.hpp Utils/FixModelByWin10.cpp Utils/FixModelByWin10.hpp - Utils/Mainsail.cpp - Utils/Mainsail.hpp + Utils/Moonraker.cpp + Utils/Moonraker.hpp Utils/OctoPrint.cpp Utils/OctoPrint.hpp Utils/Duet.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 62ea106faf..8773b15a4a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -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; } +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) { 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) { 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); assert(instance != nullptr); set_type(instance->first, ESLAViewType::Processed); @@ -4696,6 +4701,13 @@ std::pair> GLCanvas3D::get_layers_h 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) { m_sla_view.set_type(type); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 425e200357..f02442ab61 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1005,6 +1005,7 @@ public: std::pair> get_layers_height_data(int object_id); + void detect_sla_view_type(); void set_sla_view_type(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; } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a380692370..ec7f43ae11 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2281,14 +2281,7 @@ bool GUI_App::load_language(wxString language, bool initial) } #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)) { -#endif // Loading the language dictionary failed. wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed."; #if !defined(_WIN32) && !defined(__APPLE__) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index e7cd63fece..ec6f66577e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -855,6 +855,7 @@ void GLGizmoSlaSupports::on_set_state() 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->selection_info()->set_use_shift(false); // see top of on_render for details diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index fbf6c8d1f1..2a0964c5e7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -962,6 +962,8 @@ bool GLGizmosManager::activate_gizmo(EType type) if (type == Undefined) { // it is deactivation of gizmo m_current = Undefined; + if (m_parent.current_printer_technology() == ptSLA) + m_parent.detect_sla_view_type(); return true; } diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 47cd01fdbe..b5c328ae8e 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -99,7 +99,6 @@ void ArrangeJob::prepare_selected() { clear_input(); Model &model = m_plater->model(); - double stride = bed_stride(m_plater); std::vector obj_sel(model.objects.size(), nullptr); @@ -143,12 +142,6 @@ void ArrangeJob::prepare_selected() { // If the selection was empty arrange everything if (m_selected.empty()) 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, @@ -261,6 +254,10 @@ void ArrangeJob::prepare() } 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) @@ -268,11 +265,9 @@ void ArrangeJob::process(Ctl &ctl) static const auto arrangestr = _u8L("Arranging"); arrangement::ArrangeParams params; - arrangement::ArrangeBed bed; - ctl.call_on_main_thread([this, ¶ms, &bed]{ + ctl.call_on_main_thread([this, ¶ms]{ prepare(); 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; params.min_bed_distance = std::max(params.min_bed_distance, min_inset); }).wait(); @@ -293,13 +288,13 @@ void ArrangeJob::process(Ctl &ctl) 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) { 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. 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(); } - m_plater->update((unsigned int)Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH); + m_plater->update(static_cast( + Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH)); + wxGetApp().obj_manipul()->set_dirty(); if (!m_unarranged.empty()) { @@ -442,4 +439,26 @@ arrangement::ArrangeParams get_arrange_params(Plater *p) return params; } +void assign_logical_beds(std::vector &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(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 diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index 4defc07e8b..c7070f213d 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -21,6 +21,7 @@ class ArrangeJob : public Job ArrangePolygons m_selected, m_unselected, m_unprintable; std::vector m_unarranged; + arrangement::ArrangeBed m_bed; coord_t m_min_bed_inset = 0.; Plater *m_plater; @@ -89,7 +90,6 @@ arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater) using ArrangePolygon = arrangement::ArrangePolygon; 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) { if (p.is_arranged()) { Vec2d t = p.translation.cast(); @@ -109,6 +109,10 @@ arrangement::ArrangeParams get_arrange_params(Plater *p); coord_t get_skirt_offset(const Plater* plater); +void assign_logical_beds(std::vector &items, + const arrangement::ArrangeBed &bed, + double stride); + }} // namespace Slic3r::GUI #endif // ARRANGEJOB_HPP diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 11d9450c2e..7594d32109 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -17,7 +17,6 @@ void FillBedJob::prepare() { m_selected.clear(); m_unselected.clear(); - m_bedpts.clear(); m_min_bed_inset = 0.; m_object_idx = m_plater->get_selected_object_idx(); @@ -41,10 +40,10 @@ void FillBedJob::prepare() if (m_selected.empty()) return; - m_bedpts = get_bed_shape(*m_plater->config()); + Points bedpts = get_bed_shape(*m_plater->config()); 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) if (int(idx) != m_object_idx) @@ -72,7 +71,7 @@ void FillBedJob::prepare() }) / sc; 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. int needed_items = (bed_area - fixed_area) / poly_area; @@ -85,13 +84,11 @@ void FillBedJob::prepare() for (int i = 0; i < needed_items; ++i) { ArrangePolygon ap = template_ap; - ap.poly = m_selected.front().poly; ap.bed_idx = arrangement::UNARRANGED; 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]; - ModelInstance *inst = mo->add_instance(*mi); - inst->set_transformation(m); + ModelInstance *inst = mo->add_instance(m); inst->apply_arrange_result(p.translation.cast(), p.rotation); }; m_selected.emplace_back(ap); @@ -99,14 +96,6 @@ void FillBedJob::prepare() 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; for (auto &ap : m_selected) { min_offset = std::max(ap.inflation, min_offset); @@ -123,6 +112,14 @@ void FillBedJob::prepare() } 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) @@ -154,7 +151,7 @@ void FillBedJob::process(Ctl &ctl) 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. 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(); - m_plater->update(); + m_plater->update(static_cast( + Plater::UpdateParams::FORCE_FULL_SCREEN_REFRESH)); // FIXME: somebody explain why this is needed for increase_object_instances if (inst_cnt == 1) diff --git a/src/slic3r/GUI/Jobs/FillBedJob.hpp b/src/slic3r/GUI/Jobs/FillBedJob.hpp index b953e0e981..ae8680de16 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.hpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.hpp @@ -18,7 +18,7 @@ class FillBedJob : public Job ArrangePolygons m_unselected; coord_t m_min_bed_inset = 0.; - Points m_bedpts; + arrangement::ArrangeBed m_bed; int m_status_range = 0; Plater *m_plater; diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index f7b632579a..c54cda1202 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -116,7 +116,7 @@ void PresetForPrinter::update_full_printer_name() wxString printer_name = m_parent->get_printer_name(); wxString preset_name = m_presets_list->GetString(m_presets_list->GetSelection()); - m_full_printer_name->SetLabelText(printer_name + " * " + preset_name); + m_full_printer_name->SetLabelText(printer_name + from_u8(PhysicalPrinter::separator()) + preset_name); } std::string PresetForPrinter::get_preset_name() @@ -654,6 +654,24 @@ wxString PhysicalPrinterDialog::get_printer_name() void PhysicalPrinterDialog::update_full_printer_names() { + // check input symbols for usability + + const char* unusable_symbols = "<>[]:/\\|?*\""; + + wxString printer_name = m_printer_name->GetValue(); + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + size_t pos = printer_name.find_first_of(unusable_symbols[i]); + if (pos != std::string::npos) { + wxString str = printer_name.SubString(pos, 1); + printer_name.Remove(pos, 1); + InfoDialog(this, format_wxstr("%1%: \"%2%\" ", _L("Unexpected character"), str), + _L("The following characters are not allowed in the name") + ": " + unusable_symbols).ShowModal(); + m_printer_name->SetValue(printer_name); + m_printer_name->SetInsertionPointEnd(); + return; + } + } + for (PresetForPrinter* preset : m_presets) preset->update_full_printer_name(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5e987d6669..187e2737d4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -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()); - 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); else { const Transform3d mesh_trafo_inv = object->trafo().inverse(); @@ -7696,7 +7696,7 @@ PlaterAfterLoadAutoArrange::PlaterAfterLoadAutoArrange() Plater* plater = wxGetApp().plater(); m_enabled = plater->model().objects.empty() && plater->printer_technology() == ptFFF && - plater->fff_print().config().printer_model.value == "XL"; + is_XL_printer(plater->fff_print().config()); } PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange() diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 93017714e7..184b8af707 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -216,10 +216,10 @@ void Tab::create_preset_tab() m_mode_sizer = new ModeSizer(panel, int (0.5*em_unit(this))); const float scale_factor = em_unit(this)*0.1;// GetContentScaleFactor(); - m_hsizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_hsizer, 0, wxEXPAND | wxBOTTOM, 3); - m_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); - m_hsizer->AddSpacer(int(4*scale_factor)); + m_top_hsizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(m_top_hsizer, 0, wxEXPAND | wxBOTTOM | wxALIGN_CENTER_VERTICAL, 3); + m_top_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); + m_top_hsizer->AddSpacer(int(4*scale_factor)); m_h_buttons_sizer = new wxBoxSizer(wxHORIZONTAL); 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->Add(m_btn_compare_preset, 0, wxALIGN_CENTER_VERTICAL); - m_hsizer->Add(m_h_buttons_sizer, 1, wxEXPAND); - m_hsizer->AddSpacer(int(16*scale_factor)); - // m_hsizer->AddStretchSpacer(32); + m_top_hsizer->Add(m_h_buttons_sizer, 1, wxEXPAND | wxALIGN_CENTRE_VERTICAL); + m_top_hsizer->AddSpacer(int(16*scale_factor)); // StretchSpacer has a strange behavior under OSX, so // There is used just additional sizer for m_mode_sizer with right alignment 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 // to wrong vertical size assigned to wxBitmapComboBoxes, see GH issue #7176. 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. m_hsizer = new wxBoxSizer(wxHORIZONTAL); @@ -461,20 +462,15 @@ void Tab::OnActivate() activate_selected_page([](){}); m_hsizer->Layout(); -#ifdef _MSW_DARK_MODE - // Because of DarkMode we use our own Notebook (inherited from wxSiplebook) instead of wxNotebook - // And it looks like first Layout of the page doesn't update a size of the m_presets_choice - // So we have to set correct size explicitely - if (wxSize ok_sz = wxSize(35 * m_em_unit, m_presets_choice->GetBestSize().y); - ok_sz != m_presets_choice->GetSize()) { - m_presets_choice->SetMinSize(ok_sz); - m_presets_choice->SetSize(ok_sz); - GetSizer()->GetItem(size_t(0))->GetSizer()->Layout(); - if (wxGetApp().tabs_as_menu()) - m_presets_choice->update(); + if (m_presets_choice->IsShown()) + Refresh(); // Just refresh page, if m_presets_choice is already shown + else { + // on first OnActivate call show top sizer + m_top_hsizer->ShowItems(true); + if (TabFilament* tab = dynamic_cast(this)) + tab->update_extruder_combobox(); + Layout(); } -#endif // _MSW_DARK_MODE - Refresh(); } void Tab::update_label_colours() @@ -1950,6 +1946,9 @@ void TabFilament::create_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(m_preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter"))->values.size(); m_extruders_cb->Show(extruder_cnt > 1); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index bbe1d1b17b..81344c6151 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -172,6 +172,7 @@ protected: ScalableButton* m_btn_delete_preset; ScalableButton* m_btn_edit_ph_printer {nullptr}; ScalableButton* m_btn_hide_incompatible_presets; + wxBoxSizer* m_top_hsizer; wxBoxSizer* m_hsizer; wxBoxSizer* m_h_buttons_sizer; wxBoxSizer* m_left_sizer; diff --git a/src/slic3r/Utils/Mainsail.cpp b/src/slic3r/Utils/Moonraker.cpp similarity index 94% rename from src/slic3r/Utils/Mainsail.cpp rename to src/slic3r/Utils/Moonraker.cpp index 303d754e38..53aeb08b02 100644 --- a/src/slic3r/Utils/Mainsail.cpp +++ b/src/slic3r/Utils/Moonraker.cpp @@ -1,4 +1,4 @@ -#include "Mainsail.hpp" +#include "Moonraker.hpp" #include #include @@ -63,28 +63,28 @@ std::string substitute_host(const std::string& orig_addr, std::string sub_addr) } #endif } -Mainsail::Mainsail(DynamicPrintConfig *config) : +Moonraker::Moonraker(DynamicPrintConfig *config) : m_host(config->opt_string("print_host")), m_apikey(config->opt_string("printhost_apikey")), m_cafile(config->opt_string("printhost_cafile")), m_ssl_revoke_best_effort(config->opt_bool("printhost_ssl_ignore_revoke")) {} -const char* Mainsail::get_name() const { return "Mainsail"; } +const char* Moonraker::get_name() const { return "Moonraker"; } -wxString Mainsail::get_test_ok_msg () const +wxString Moonraker::get_test_ok_msg () const { - return _(L("Connection to Mainsail works correctly.")); + return _(L("Connection to Moonraker works correctly.")); } -wxString Mainsail::get_test_failed_msg (wxString &msg) const +wxString Moonraker::get_test_failed_msg (wxString &msg) const { return GUI::format_wxstr("%s: %s" - , _L("Could not connect to Mainsail") + , _L("Could not connect to Moonraker") , msg); } -bool Mainsail::test(wxString& msg) const +bool Moonraker::test(wxString& msg) const { // GET /server/info @@ -142,7 +142,7 @@ bool Mainsail::test(wxString& msg) const return res; } -bool Mainsail::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const +bool Moonraker::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const { // POST /server/files/upload @@ -232,7 +232,7 @@ bool Mainsail::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error return res; } -void Mainsail::set_auth(Http &http) const +void Moonraker::set_auth(Http &http) const { if (!m_apikey.empty()) http.header("X-Api-Key", m_apikey); @@ -240,7 +240,7 @@ void Mainsail::set_auth(Http &http) const http.ca_file(m_cafile); } -std::string Mainsail::make_url(const std::string &path) const +std::string Moonraker::make_url(const std::string &path) const { if (m_host.find("http://") == 0 || m_host.find("https://") == 0) { if (m_host.back() == '/') { diff --git a/src/slic3r/Utils/Mainsail.hpp b/src/slic3r/Utils/Moonraker.hpp similarity index 91% rename from src/slic3r/Utils/Mainsail.hpp rename to src/slic3r/Utils/Moonraker.hpp index 136c7dc574..09a231f49f 100644 --- a/src/slic3r/Utils/Mainsail.hpp +++ b/src/slic3r/Utils/Moonraker.hpp @@ -1,5 +1,5 @@ -#ifndef slic3r_Mainsail_hpp_ -#define slic3r_Mainsail_hpp_ +#ifndef slic3r_Moonraker_hpp_ +#define slic3r_Moonraker_hpp_ #include #include @@ -16,11 +16,11 @@ class DynamicPrintConfig; class Http; // https://moonraker.readthedocs.io/en/latest/web_api -class Mainsail : public PrintHost +class Moonraker : public PrintHost { public: - Mainsail(DynamicPrintConfig *config); - ~Mainsail() override = default; + Moonraker(DynamicPrintConfig *config); + ~Moonraker() override = default; const char* get_name() const override; diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index cddada0680..d9152ef214 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -19,7 +19,7 @@ #include "AstroBox.hpp" #include "Repetier.hpp" #include "MKS.hpp" -#include "Mainsail.hpp" +#include "Moonraker.hpp" #include "../GUI/PrintHostDialogs.hpp" namespace fs = boost::filesystem; @@ -55,7 +55,7 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) case htPrusaLink: return new PrusaLink(config); case htPrusaConnect: return new PrusaConnect(config); case htMKS: return new MKS(config); - case htMainSail: return new Mainsail(config); + case htMoonraker: return new Moonraker(config); default: return nullptr; } } else {