diff --git a/CMakeLists.txt b/CMakeLists.txt index c15371c9ac..98ae4f0c68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,15 +35,27 @@ option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux") +set(IS_CROSS_COMPILE FALSE) + if (APPLE) set(CMAKE_FIND_FRAMEWORK LAST) set(CMAKE_FIND_APPBUNDLE LAST) + list(FIND CMAKE_OSX_ARCHITECTURES ${CMAKE_SYSTEM_PROCESSOR} _arch_idx) + if (CMAKE_OSX_ARCHITECTURES AND _arch_idx LESS 0) + set(IS_CROSS_COMPILE TRUE) + endif () endif () # Proposal for C++ unit tests and sandboxes option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF) option(SLIC3R_BUILD_TESTS "Build unit tests" ON) +if (IS_CROSS_COMPILE) + message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!") + set(SLIC3R_PERL_XS OFF CACHE BOOL "" FORCE) + set(SLIC3R_BUILD_TESTS OFF CACHE BOOL "" FORCE) +endif () + # Print out the SLIC3R_* cache options get_cmake_property(_cache_vars CACHE_VARIABLES) list (SORT _cache_vars) @@ -80,12 +92,21 @@ if (MSVC) # Disable STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. #FIXME Remove this line after eigen library adapts to the new C++17 adaptor rules. add_compile_options(-D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING) + # Disable warnings on conversion from unsigned to signed (possible loss of data) + # C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data. An integer type is converted to a smaller integer type. + # C4267: The compiler detected a conversion from size_t to a smaller type. + add_compile_options(/wd4244 /wd4267) endif () if (MINGW) add_compile_options(-Wa,-mbig-obj) endif () +if (NOT MSVC) + # ARMs (Raspberry PI) use an unsigned char by default. Let's make it consistent for PrusaSlicer on all platforms. + add_compile_options(-fsigned-char) +endif () + # Display and check CMAKE_PREFIX_PATH message(STATUS "SLIC3R_STATIC: ${SLIC3R_STATIC}") if (NOT "${CMAKE_PREFIX_PATH}" STREQUAL "") @@ -190,6 +211,13 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP add_compile_options(-Wno-ignored-attributes) # Tamas: Eigen include dirs are marked as SYSTEM endif() + # Clang reports legacy OpenGL calls as deprecated. Turn off the warning for now + # to reduce the clutter, we know about this one. It should be reenabled after + # we finally get rid of the deprecated code. + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + add_compile_options(-Wno-deprecated-declarations) + endif() + #GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 @@ -223,13 +251,16 @@ include_directories(${LIBDIR}) # For generated header files include_directories(${LIBDIR_BIN}/platform) # For libslic3r.h -include_directories(${LIBDIR}/clipper ${LIBDIR}/polypartition) +include_directories(${LIBDIR}/clipper) if(WIN32) add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) if(MSVC) # BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking. add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 -DBOOST_SYSTEM_USE_UTF8 ) + # Force the source code encoding to UTF-8. See PrusaSlicer GH pull request #5583 + add_compile_options("$<$:/utf-8>") + add_compile_options("$<$:/utf-8>") endif(MSVC) endif(WIN32) @@ -266,10 +297,9 @@ if(SLIC3R_STATIC) endif() #set(Boost_DEBUG ON) # set(Boost_COMPILER "-mgw81") -if(NOT WIN32) - # boost::process was introduced first in version 1.64.0 - set(MINIMUM_BOOST_VERSION "1.64.0") -endif() +# boost::process was introduced first in version 1.64.0, +# boost::beast::detail::base64 was introduced first in version 1.66.0 +set(MINIMUM_BOOST_VERSION "1.66.0") set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time") find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index c6bdec9852..a7eafa545f 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -302,7 +302,7 @@ if(NOT TBB_FOUND) IMPORTED_LOCATION ${TBB_LIBRARIES}) if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) set_target_properties(TBB::tbb PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_DEBUG}>;$<$:${TBB_DEFINITIONS_RELEASE}>" + INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_RELEASE}>;$<$:${TBB_DEFINITIONS_DEBUG}>" IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG} IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_RELEASE} IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE} diff --git a/cmake/modules/OpenVDBUtils.cmake b/cmake/modules/OpenVDBUtils.cmake index f64eda6f2c..f79862b83a 100644 --- a/cmake/modules/OpenVDBUtils.cmake +++ b/cmake/modules/OpenVDBUtils.cmake @@ -157,7 +157,9 @@ function(OPENVDB_ABI_VERSION_FROM_PRINT OPENVDB_PRINT) endif() set(_OpenVDB_ABI) - string(REGEX REPLACE ".*abi([0-9]*).*" "\\1" _OpenVDB_ABI ${_VDB_PRINT_VERSION_STRING}) + if (_VDB_PRINT_VERSION_STRING) + string(REGEX REPLACE ".*abi([0-9]*).*" "\\1" _OpenVDB_ABI ${_VDB_PRINT_VERSION_STRING}) + endif () if(${_OpenVDB_ABI} STREQUAL ${_VDB_PRINT_VERSION_STRING}) set(_OpenVDB_ABI "") endif() diff --git a/deps/deps-linux.cmake b/deps/deps-linux.cmake index 2da2890976..35522504ca 100644 --- a/deps/deps-linux.cmake +++ b/deps/deps-linux.cmake @@ -26,6 +26,7 @@ ExternalProject_Add(dep_boost variant=release threading=multi boost.locale.icu=off + --disable-icu cflags=-fPIC cxxflags=-fPIC install diff --git a/deps/deps-macos.cmake b/deps/deps-macos.cmake index bf9501ca02..53ba008c3e 100644 --- a/deps/deps-macos.cmake +++ b/deps/deps-macos.cmake @@ -33,6 +33,7 @@ ExternalProject_Add(dep_boost variant=release threading=multi boost.locale.icu=off + --disable-icu "cflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" "cxxflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" "mflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 81d52b8424..c0d80bb291 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -76,6 +76,7 @@ ExternalProject_Add(dep_boost variant=release threading=multi boost.locale.icu=off + --disable-icu "${DEP_BOOST_DEBUG}" release install INSTALL_COMMAND "" # b2 does that already ) diff --git a/doc/Dependencies.md b/doc/Dependencies.md index 3f6335cb73..137aaf17ba 100644 --- a/doc/Dependencies.md +++ b/doc/Dependencies.md @@ -22,8 +22,6 @@ * qhull: libqhull-dev does not contain libqhullcpp => link errors. Until it is fixed, we will use the builtin version. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925540 * semver: One module C library, author expects to use clib for installation. No packages. * Shiny: no packages -* poly2tree: Obsolete, candidate for removal -* polypartition: Obsolete, candidate for removal ## Header only * igl diff --git a/doc/How to build - Linux et al.md b/doc/How to build - Linux et al.md index a8f2441be5..b23fef7728 100644 --- a/doc/How to build - Linux et al.md +++ b/doc/How to build - Linux et al.md @@ -7,7 +7,7 @@ as the versions listed - generally versions available on conservative Linux dist Perl is not required any more. -In a typical situation, one would open a command line, go to the PrusaSlicer sources, create a directory called `build` or similar, +In a typical situation, one would open a command line, go to the PrusaSlicer sources (**the root directory of the repository**), create a directory called `build` or similar, `cd` into it and call: cmake .. @@ -37,7 +37,7 @@ To do this, go to the `deps` directory, create a `build` subdirectory (or the li where the target destdir is a directory of your choosing where the dependencies will be installed. You can also omit the `DESTDIR` option to use the default, in that case the `destdir` will be created inside the `build` directory where `cmake` is run. -To pass the destdir path to the top-level PrusaSlicer CMake script, use the `CMAKE_PREFIX_PATH` option along with turning on `SLIC3R_STATIC`: +Once the dependencies have been built, in order to pass the destdir path to the **top-level** PrusaSlicer `CMakeLists.txt` script, use the `CMAKE_PREFIX_PATH` option along with turning on `SLIC3R_STATIC`: cmake .. -DSLIC3R_STATIC=1 -DCMAKE_PREFIX_PATH=/usr/local diff --git a/doc/How to build - Mac OS.md b/doc/How to build - Mac OS.md index bab40ea265..5c2019454e 100644 --- a/doc/How to build - Mac OS.md +++ b/doc/How to build - Mac OS.md @@ -90,8 +90,9 @@ Works on a fresh installation of MacOS Catalina 10.15.6 - Enter: -```brew install cmake git gettext +``` brew update +brew install cmake git gettext brew upgrade git clone https://github.com/prusa3d/PrusaSlicer/ cd PrusaSlicer/deps @@ -105,3 +106,4 @@ cd build cmake .. -DCMAKE_PREFIX_PATH="$PWD/../deps/build/destdir/usr/local" make src/prusa-slicer +``` diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md index 3df17b88f9..54c02fca1d 100644 --- a/doc/How to build - Windows.md +++ b/doc/How to build - Windows.md @@ -38,6 +38,8 @@ cd build cmake .. -G "Visual Studio 16 2019" -DCMAKE_PREFIX_PATH="c:\src\PrusaSlicer-deps\usr\local" ``` +Note that `CMAKE_PREFIX_PATH` must be absolute path. A relative path like "..\..\PrusaSlicer-deps\usr\local" does not work. + ### Compile PrusaSlicer. Double-click c:\src\PrusaSlicer\build\PrusaSlicer.sln to open in Visual Studio 2019. @@ -175,4 +177,4 @@ option to CMake, this will only produce a _Release_ build. Refer to the CMake scripts inside the `deps` directory to see which dependencies are built in what versions and how this is done. \*) Specifically, the problem arises when building boost. Boost build tool appends all build options into paths of -intermediate files, which are not handled correctly by either `b2.exe` or possibly `ninja` (?). \ No newline at end of file +intermediate files, which are not handled correctly by either `b2.exe` or possibly `ninja` (?). diff --git a/resources/icons/compare.svg b/resources/icons/compare.svg new file mode 100644 index 0000000000..fcb458f7c4 --- /dev/null +++ b/resources/icons/compare.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/resources/icons/equal.svg b/resources/icons/equal.svg new file mode 100644 index 0000000000..bce4a24f7c --- /dev/null +++ b/resources/icons/equal.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/resources/icons/not_equal.svg b/resources/icons/not_equal.svg new file mode 100644 index 0000000000..bc88144353 --- /dev/null +++ b/resources/icons/not_equal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/resources/localization/PrusaSlicer.pot b/resources/localization/PrusaSlicer.pot index 5c328e479c..58ed3370e6 100644 --- a/resources/localization/PrusaSlicer.pot +++ b/resources/localization/PrusaSlicer.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-18 13:59+0100\n" +"POT-Creation-Date: 2021-02-03 21:27+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -39,16 +39,16 @@ msgid "About %s" msgstr "" #: src/slic3r/GUI/AboutDialog.cpp:238 src/slic3r/GUI/AboutDialog.cpp:361 -#: src/slic3r/GUI/GUI_App.cpp:235 src/slic3r/GUI/MainFrame.cpp:151 +#: src/slic3r/GUI/GUI_App.cpp:243 src/slic3r/GUI/MainFrame.cpp:151 msgid "Version" msgstr "" #. TRN "Slic3r _is licensed under the_ License" -#: src/slic3r/GUI/AboutDialog.cpp:265 src/slic3r/GUI/GUI_App.cpp:240 +#: src/slic3r/GUI/AboutDialog.cpp:265 src/slic3r/GUI/GUI_App.cpp:248 msgid "is licensed under the" msgstr "" -#: src/slic3r/GUI/AboutDialog.cpp:266 src/slic3r/GUI/GUI_App.cpp:240 +#: src/slic3r/GUI/AboutDialog.cpp:266 src/slic3r/GUI/GUI_App.cpp:248 msgid "GNU Affero General Public License, version 3" msgstr "" @@ -141,8 +141,8 @@ msgid "Scheduling upload to `%1%`. See Window -> Print Host Upload Queue" msgstr "" #: src/slic3r/GUI/BedShapeDialog.cpp:93 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:240 src/slic3r/GUI/Plater.cpp:162 -#: src/slic3r/GUI/Tab.cpp:2536 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:221 src/slic3r/GUI/Plater.cpp:162 +#: src/slic3r/GUI/Tab.cpp:2550 msgid "Size" msgstr "" @@ -150,7 +150,7 @@ msgstr "" msgid "Origin" msgstr "" -#: src/slic3r/GUI/BedShapeDialog.cpp:95 src/libslic3r/PrintConfig.cpp:771 +#: src/slic3r/GUI/BedShapeDialog.cpp:95 src/libslic3r/PrintConfig.cpp:796 msgid "Diameter" msgstr "" @@ -165,47 +165,49 @@ msgid "" msgstr "" #: src/slic3r/GUI/BedShapeDialog.cpp:129 src/slic3r/GUI/ConfigWizard.cpp:242 -#: src/slic3r/GUI/ConfigWizard.cpp:1368 src/slic3r/GUI/ConfigWizard.cpp:1382 +#: src/slic3r/GUI/ConfigWizard.cpp:1366 src/slic3r/GUI/ConfigWizard.cpp:1380 #: src/slic3r/GUI/ExtruderSequenceDialog.cpp:88 -#: src/slic3r/GUI/GCodeViewer.cpp:2337 src/slic3r/GUI/GCodeViewer.cpp:2343 -#: src/slic3r/GUI/GCodeViewer.cpp:2351 src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:179 +#: src/slic3r/GUI/GCodeViewer.cpp:3647 src/slic3r/GUI/GCodeViewer.cpp:3653 +#: src/slic3r/GUI/GCodeViewer.cpp:3661 src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:179 #: src/slic3r/GUI/GUI_ObjectLayers.cpp:145 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:341 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:418 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:486 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:487 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:322 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:399 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:467 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:468 #: src/slic3r/GUI/ObjectDataViewModel.cpp:96 #: src/slic3r/GUI/WipeTowerDialog.cpp:85 src/libslic3r/PrintConfig.cpp:77 #: src/libslic3r/PrintConfig.cpp:84 src/libslic3r/PrintConfig.cpp:95 #: src/libslic3r/PrintConfig.cpp:135 src/libslic3r/PrintConfig.cpp:244 -#: src/libslic3r/PrintConfig.cpp:302 src/libslic3r/PrintConfig.cpp:377 -#: src/libslic3r/PrintConfig.cpp:385 src/libslic3r/PrintConfig.cpp:435 -#: src/libslic3r/PrintConfig.cpp:565 src/libslic3r/PrintConfig.cpp:576 -#: src/libslic3r/PrintConfig.cpp:594 src/libslic3r/PrintConfig.cpp:774 -#: src/libslic3r/PrintConfig.cpp:1258 src/libslic3r/PrintConfig.cpp:1439 -#: src/libslic3r/PrintConfig.cpp:1500 src/libslic3r/PrintConfig.cpp:1518 -#: src/libslic3r/PrintConfig.cpp:1536 src/libslic3r/PrintConfig.cpp:1594 -#: src/libslic3r/PrintConfig.cpp:1604 src/libslic3r/PrintConfig.cpp:1729 -#: src/libslic3r/PrintConfig.cpp:1737 src/libslic3r/PrintConfig.cpp:1778 -#: src/libslic3r/PrintConfig.cpp:1786 src/libslic3r/PrintConfig.cpp:1796 -#: src/libslic3r/PrintConfig.cpp:1804 src/libslic3r/PrintConfig.cpp:1812 -#: src/libslic3r/PrintConfig.cpp:1875 src/libslic3r/PrintConfig.cpp:2141 -#: src/libslic3r/PrintConfig.cpp:2212 src/libslic3r/PrintConfig.cpp:2246 -#: src/libslic3r/PrintConfig.cpp:2375 src/libslic3r/PrintConfig.cpp:2454 -#: src/libslic3r/PrintConfig.cpp:2461 src/libslic3r/PrintConfig.cpp:2468 -#: src/libslic3r/PrintConfig.cpp:2498 src/libslic3r/PrintConfig.cpp:2508 -#: src/libslic3r/PrintConfig.cpp:2518 src/libslic3r/PrintConfig.cpp:2678 -#: src/libslic3r/PrintConfig.cpp:2712 src/libslic3r/PrintConfig.cpp:2851 -#: src/libslic3r/PrintConfig.cpp:2860 src/libslic3r/PrintConfig.cpp:2869 -#: src/libslic3r/PrintConfig.cpp:2879 src/libslic3r/PrintConfig.cpp:2944 -#: src/libslic3r/PrintConfig.cpp:2954 src/libslic3r/PrintConfig.cpp:2966 -#: src/libslic3r/PrintConfig.cpp:2986 src/libslic3r/PrintConfig.cpp:2996 -#: src/libslic3r/PrintConfig.cpp:3006 src/libslic3r/PrintConfig.cpp:3024 -#: src/libslic3r/PrintConfig.cpp:3039 src/libslic3r/PrintConfig.cpp:3053 -#: src/libslic3r/PrintConfig.cpp:3064 src/libslic3r/PrintConfig.cpp:3077 -#: src/libslic3r/PrintConfig.cpp:3122 src/libslic3r/PrintConfig.cpp:3132 -#: src/libslic3r/PrintConfig.cpp:3141 src/libslic3r/PrintConfig.cpp:3151 -#: src/libslic3r/PrintConfig.cpp:3167 src/libslic3r/PrintConfig.cpp:3191 +#: src/libslic3r/PrintConfig.cpp:303 src/libslic3r/PrintConfig.cpp:328 +#: src/libslic3r/PrintConfig.cpp:402 src/libslic3r/PrintConfig.cpp:410 +#: src/libslic3r/PrintConfig.cpp:460 src/libslic3r/PrintConfig.cpp:590 +#: src/libslic3r/PrintConfig.cpp:601 src/libslic3r/PrintConfig.cpp:619 +#: src/libslic3r/PrintConfig.cpp:799 src/libslic3r/PrintConfig.cpp:1085 +#: src/libslic3r/PrintConfig.cpp:1094 src/libslic3r/PrintConfig.cpp:1347 +#: src/libslic3r/PrintConfig.cpp:1528 src/libslic3r/PrintConfig.cpp:1589 +#: src/libslic3r/PrintConfig.cpp:1607 src/libslic3r/PrintConfig.cpp:1625 +#: src/libslic3r/PrintConfig.cpp:1683 src/libslic3r/PrintConfig.cpp:1693 +#: src/libslic3r/PrintConfig.cpp:1818 src/libslic3r/PrintConfig.cpp:1826 +#: src/libslic3r/PrintConfig.cpp:1867 src/libslic3r/PrintConfig.cpp:1875 +#: src/libslic3r/PrintConfig.cpp:1885 src/libslic3r/PrintConfig.cpp:1893 +#: src/libslic3r/PrintConfig.cpp:1901 src/libslic3r/PrintConfig.cpp:1964 +#: src/libslic3r/PrintConfig.cpp:2230 src/libslic3r/PrintConfig.cpp:2301 +#: src/libslic3r/PrintConfig.cpp:2335 src/libslic3r/PrintConfig.cpp:2464 +#: src/libslic3r/PrintConfig.cpp:2543 src/libslic3r/PrintConfig.cpp:2550 +#: src/libslic3r/PrintConfig.cpp:2557 src/libslic3r/PrintConfig.cpp:2587 +#: src/libslic3r/PrintConfig.cpp:2597 src/libslic3r/PrintConfig.cpp:2607 +#: src/libslic3r/PrintConfig.cpp:2767 src/libslic3r/PrintConfig.cpp:2801 +#: src/libslic3r/PrintConfig.cpp:2940 src/libslic3r/PrintConfig.cpp:2949 +#: src/libslic3r/PrintConfig.cpp:2958 src/libslic3r/PrintConfig.cpp:2968 +#: src/libslic3r/PrintConfig.cpp:3033 src/libslic3r/PrintConfig.cpp:3043 +#: src/libslic3r/PrintConfig.cpp:3055 src/libslic3r/PrintConfig.cpp:3075 +#: src/libslic3r/PrintConfig.cpp:3085 src/libslic3r/PrintConfig.cpp:3095 +#: src/libslic3r/PrintConfig.cpp:3113 src/libslic3r/PrintConfig.cpp:3128 +#: src/libslic3r/PrintConfig.cpp:3142 src/libslic3r/PrintConfig.cpp:3153 +#: src/libslic3r/PrintConfig.cpp:3166 src/libslic3r/PrintConfig.cpp:3211 +#: src/libslic3r/PrintConfig.cpp:3221 src/libslic3r/PrintConfig.cpp:3230 +#: src/libslic3r/PrintConfig.cpp:3240 src/libslic3r/PrintConfig.cpp:3256 +#: src/libslic3r/PrintConfig.cpp:3280 msgid "mm" msgstr "" @@ -223,7 +225,7 @@ msgstr "" msgid "Circular" msgstr "" -#: src/slic3r/GUI/BedShapeDialog.cpp:143 src/slic3r/GUI/GUI_Preview.cpp:243 +#: src/slic3r/GUI/BedShapeDialog.cpp:143 src/slic3r/GUI/GUI_Preview.cpp:240 #: src/libslic3r/ExtrusionEntity.cpp:323 src/libslic3r/ExtrusionEntity.cpp:358 msgid "Custom" msgstr "" @@ -233,7 +235,7 @@ msgid "Invalid" msgstr "" #: src/slic3r/GUI/BedShapeDialog.cpp:156 src/slic3r/GUI/BedShapeDialog.cpp:222 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2288 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2306 msgid "Shape" msgstr "" @@ -254,7 +256,7 @@ msgid "Load..." msgstr "" #: src/slic3r/GUI/BedShapeDialog.cpp:333 src/slic3r/GUI/BedShapeDialog.cpp:413 -#: src/slic3r/GUI/Tab.cpp:3484 +#: src/slic3r/GUI/Tab.cpp:3502 msgid "Remove" msgstr "" @@ -296,7 +298,7 @@ msgstr "" msgid "Choose an STL file to import bed model from:" msgstr "" -#: src/slic3r/GUI/BedShapeDialog.hpp:98 src/slic3r/GUI/ConfigWizard.cpp:1327 +#: src/slic3r/GUI/BedShapeDialog.hpp:98 src/slic3r/GUI/ConfigWizard.cpp:1325 msgid "Bed Shape" msgstr "" @@ -320,11 +322,11 @@ msgstr "" msgid "OctoPrint version" msgstr "" -#: src/slic3r/GUI/BonjourDialog.cpp:218 +#: src/slic3r/GUI/BonjourDialog.cpp:224 msgid "Searching for devices" msgstr "" -#: src/slic3r/GUI/BonjourDialog.cpp:225 +#: src/slic3r/GUI/BonjourDialog.cpp:231 msgid "Finished" msgstr "" @@ -332,11 +334,11 @@ msgstr "" msgid "Buttons And Text Colors Description" msgstr "" -#: src/slic3r/GUI/ButtonsDescription.cpp:36 +#: src/slic3r/GUI/ButtonsDescription.cpp:36 src/slic3r/GUI/Preferences.cpp:517 msgid "Value is the same as the system value" msgstr "" -#: src/slic3r/GUI/ButtonsDescription.cpp:53 +#: src/slic3r/GUI/ButtonsDescription.cpp:53 src/slic3r/GUI/Preferences.cpp:528 msgid "" "Value was changed and is not equal to the system value or the last saved " "preset" @@ -362,7 +364,7 @@ msgid "" "The first layer height will be reset to 0.01." msgstr "" -#: src/slic3r/GUI/ConfigManipulation.cpp:61 src/libslic3r/PrintConfig.cpp:969 +#: src/slic3r/GUI/ConfigManipulation.cpp:61 src/libslic3r/PrintConfig.cpp:994 msgid "First layer height" msgstr "" @@ -438,31 +440,31 @@ msgstr "" #: src/slic3r/GUI/ConfigManipulation.cpp:202 #: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:93 -#: src/slic3r/GUI/GUI_ObjectList.cpp:668 src/slic3r/GUI/Plater.cpp:389 -#: src/slic3r/GUI/Tab.cpp:1432 src/slic3r/GUI/Tab.cpp:1434 -#: src/libslic3r/PrintConfig.cpp:259 src/libslic3r/PrintConfig.cpp:472 -#: src/libslic3r/PrintConfig.cpp:496 src/libslic3r/PrintConfig.cpp:848 -#: src/libslic3r/PrintConfig.cpp:862 src/libslic3r/PrintConfig.cpp:899 -#: src/libslic3r/PrintConfig.cpp:1076 src/libslic3r/PrintConfig.cpp:1086 -#: src/libslic3r/PrintConfig.cpp:1153 src/libslic3r/PrintConfig.cpp:1172 -#: src/libslic3r/PrintConfig.cpp:1191 src/libslic3r/PrintConfig.cpp:1928 -#: src/libslic3r/PrintConfig.cpp:1945 +#: src/slic3r/GUI/GUI_ObjectList.cpp:682 src/slic3r/GUI/Plater.cpp:389 +#: src/slic3r/GUI/Tab.cpp:1444 src/slic3r/GUI/Tab.cpp:1446 +#: src/libslic3r/PrintConfig.cpp:259 src/libslic3r/PrintConfig.cpp:497 +#: src/libslic3r/PrintConfig.cpp:521 src/libslic3r/PrintConfig.cpp:873 +#: src/libslic3r/PrintConfig.cpp:887 src/libslic3r/PrintConfig.cpp:924 +#: src/libslic3r/PrintConfig.cpp:1165 src/libslic3r/PrintConfig.cpp:1175 +#: src/libslic3r/PrintConfig.cpp:1242 src/libslic3r/PrintConfig.cpp:1261 +#: src/libslic3r/PrintConfig.cpp:1280 src/libslic3r/PrintConfig.cpp:2017 +#: src/libslic3r/PrintConfig.cpp:2034 msgid "Infill" msgstr "" -#: src/slic3r/GUI/ConfigManipulation.cpp:320 +#: src/slic3r/GUI/ConfigManipulation.cpp:322 msgid "Head penetration should not be greater than the head width." msgstr "" -#: src/slic3r/GUI/ConfigManipulation.cpp:322 +#: src/slic3r/GUI/ConfigManipulation.cpp:324 msgid "Invalid Head penetration" msgstr "" -#: src/slic3r/GUI/ConfigManipulation.cpp:333 +#: src/slic3r/GUI/ConfigManipulation.cpp:335 msgid "Pinhead diameter should be smaller than the pillar diameter." msgstr "" -#: src/slic3r/GUI/ConfigManipulation.cpp:335 +#: src/slic3r/GUI/ConfigManipulation.cpp:337 msgid "Invalid pinhead diameter" msgstr "" @@ -483,7 +485,7 @@ msgid "User" msgstr "" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:28 -#: src/slic3r/GUI/GUI_Preview.cpp:229 src/libslic3r/ExtrusionEntity.cpp:309 +#: src/slic3r/GUI/GUI_Preview.cpp:226 src/libslic3r/ExtrusionEntity.cpp:309 msgid "Unknown" msgstr "" @@ -495,7 +497,7 @@ msgstr "" msgid "PrusaSlicer version" msgstr "" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:55 src/libslic3r/Preset.cpp:1298 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:55 src/libslic3r/Preset.cpp:1303 msgid "print" msgstr "" @@ -503,16 +505,16 @@ msgstr "" msgid "filaments" msgstr "" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:59 src/libslic3r/Preset.cpp:1300 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:59 src/libslic3r/Preset.cpp:1305 msgid "SLA print" msgstr "" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:60 src/slic3r/GUI/Plater.cpp:696 -#: src/libslic3r/Preset.cpp:1301 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:60 src/slic3r/GUI/Plater.cpp:693 +#: src/libslic3r/Preset.cpp:1306 msgid "SLA material" msgstr "" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:62 src/libslic3r/Preset.cpp:1302 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:62 src/libslic3r/Preset.cpp:1307 msgid "printer" msgstr "" @@ -570,13 +572,13 @@ msgid "Standard" msgstr "" #: src/slic3r/GUI/ConfigWizard.cpp:311 src/slic3r/GUI/ConfigWizard.cpp:605 -#: src/slic3r/GUI/Tab.cpp:3565 src/slic3r/GUI/UnsavedChangesDialog.cpp:933 +#: src/slic3r/GUI/Tab.cpp:3583 src/slic3r/GUI/UnsavedChangesDialog.cpp:933 msgid "All" msgstr "" #: src/slic3r/GUI/ConfigWizard.cpp:312 src/slic3r/GUI/ConfigWizard.cpp:606 -#: src/slic3r/GUI/DoubleSlider.cpp:1859 src/slic3r/GUI/Plater.cpp:361 -#: src/slic3r/GUI/Plater.cpp:504 +#: src/slic3r/GUI/DoubleSlider.cpp:1879 src/slic3r/GUI/Plater.cpp:361 +#: src/slic3r/GUI/Plater.cpp:504 src/libslic3r/PrintConfig.cpp:1045 msgid "None" msgstr "" @@ -643,35 +645,35 @@ msgid "" "filament:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1107 +#: src/slic3r/GUI/ConfigWizard.cpp:1105 msgid "Custom Printer Setup" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1107 +#: src/slic3r/GUI/ConfigWizard.cpp:1105 msgid "Custom Printer" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1109 +#: src/slic3r/GUI/ConfigWizard.cpp:1107 msgid "Define a custom printer profile" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1111 +#: src/slic3r/GUI/ConfigWizard.cpp:1109 msgid "Custom profile name:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1136 +#: src/slic3r/GUI/ConfigWizard.cpp:1134 msgid "Automatic updates" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1136 +#: src/slic3r/GUI/ConfigWizard.cpp:1134 msgid "Updates" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1144 src/slic3r/GUI/Preferences.cpp:94 +#: src/slic3r/GUI/ConfigWizard.cpp:1142 src/slic3r/GUI/Preferences.cpp:94 msgid "Check for application updates" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1148 +#: src/slic3r/GUI/ConfigWizard.cpp:1146 #, possible-c-format msgid "" "If enabled, %s checks for new application versions online. When a new " @@ -680,11 +682,11 @@ msgid "" "notification mechanisms, no automatic installation is done." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1154 src/slic3r/GUI/Preferences.cpp:129 +#: src/slic3r/GUI/ConfigWizard.cpp:1152 src/slic3r/GUI/Preferences.cpp:129 msgid "Update built-in Presets automatically" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1158 +#: src/slic3r/GUI/ConfigWizard.cpp:1156 #, possible-c-format msgid "" "If enabled, %s downloads updates of built-in system presets in the " @@ -693,30 +695,30 @@ msgid "" "startup." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1161 +#: src/slic3r/GUI/ConfigWizard.cpp:1159 msgid "" "Updates are never applied without user's consent and never overwrite user's " "customized settings." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1166 +#: src/slic3r/GUI/ConfigWizard.cpp:1164 msgid "" "Additionally a backup snapshot of the whole configuration is created before " "an update is applied." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1173 src/slic3r/GUI/GUI_ObjectList.cpp:1825 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4567 src/slic3r/GUI/Plater.cpp:3116 -#: src/slic3r/GUI/Plater.cpp:4001 src/slic3r/GUI/Plater.cpp:4032 +#: src/slic3r/GUI/ConfigWizard.cpp:1171 src/slic3r/GUI/GUI_ObjectList.cpp:1843 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4601 src/slic3r/GUI/Plater.cpp:3130 +#: src/slic3r/GUI/Plater.cpp:4022 src/slic3r/GUI/Plater.cpp:4053 msgid "Reload from disk" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1176 +#: src/slic3r/GUI/ConfigWizard.cpp:1174 msgid "" "Export full pathnames of models and parts sources into 3mf and amf files" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1180 +#: src/slic3r/GUI/ConfigWizard.cpp:1178 msgid "" "If enabled, allows the Reload from disk command to automatically find and " "load the files when invoked.\n" @@ -724,23 +726,23 @@ msgid "" "using an open file dialog." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1190 +#: src/slic3r/GUI/ConfigWizard.cpp:1188 msgid "Files association" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1192 src/slic3r/GUI/Preferences.cpp:112 +#: src/slic3r/GUI/ConfigWizard.cpp:1190 src/slic3r/GUI/Preferences.cpp:112 msgid "Associate .3mf files to PrusaSlicer" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1193 src/slic3r/GUI/Preferences.cpp:119 +#: src/slic3r/GUI/ConfigWizard.cpp:1191 src/slic3r/GUI/Preferences.cpp:119 msgid "Associate .stl files to PrusaSlicer" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1204 +#: src/slic3r/GUI/ConfigWizard.cpp:1202 msgid "View mode" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1206 +#: src/slic3r/GUI/ConfigWizard.cpp:1204 msgid "" "PrusaSlicer's user interfaces comes in three variants:\n" "Simple, Advanced, and Expert.\n" @@ -749,221 +751,221 @@ msgid "" "fine-tuning, they are suitable for advanced and expert users, respectively." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1211 +#: src/slic3r/GUI/ConfigWizard.cpp:1209 msgid "Simple mode" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1212 +#: src/slic3r/GUI/ConfigWizard.cpp:1210 msgid "Advanced mode" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1213 +#: src/slic3r/GUI/ConfigWizard.cpp:1211 msgid "Expert mode" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1219 +#: src/slic3r/GUI/ConfigWizard.cpp:1217 msgid "The size of the object can be specified in inches" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1220 +#: src/slic3r/GUI/ConfigWizard.cpp:1218 msgid "Use inches" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1254 +#: src/slic3r/GUI/ConfigWizard.cpp:1252 msgid "Other Vendors" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1258 +#: src/slic3r/GUI/ConfigWizard.cpp:1256 #, possible-c-format msgid "Pick another vendor supported by %s" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1289 +#: src/slic3r/GUI/ConfigWizard.cpp:1287 msgid "Firmware Type" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1289 src/slic3r/GUI/Tab.cpp:2172 +#: src/slic3r/GUI/ConfigWizard.cpp:1287 src/slic3r/GUI/Tab.cpp:2186 msgid "Firmware" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1293 +#: src/slic3r/GUI/ConfigWizard.cpp:1291 msgid "Choose the type of firmware used by your printer." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1327 +#: src/slic3r/GUI/ConfigWizard.cpp:1325 msgid "Bed Shape and Size" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1330 +#: src/slic3r/GUI/ConfigWizard.cpp:1328 msgid "Set the shape of your printer's bed." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1350 +#: src/slic3r/GUI/ConfigWizard.cpp:1348 msgid "Filament and Nozzle Diameters" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1350 +#: src/slic3r/GUI/ConfigWizard.cpp:1348 msgid "Print Diameters" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1364 +#: src/slic3r/GUI/ConfigWizard.cpp:1362 msgid "Enter the diameter of your printer's hot end nozzle." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1367 +#: src/slic3r/GUI/ConfigWizard.cpp:1365 msgid "Nozzle Diameter:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1377 +#: src/slic3r/GUI/ConfigWizard.cpp:1375 msgid "Enter the diameter of your filament." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1378 +#: src/slic3r/GUI/ConfigWizard.cpp:1376 msgid "" "Good precision is required, so use a caliper and do multiple measurements " "along the filament, then compute the average." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1381 +#: src/slic3r/GUI/ConfigWizard.cpp:1379 msgid "Filament Diameter:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1415 +#: src/slic3r/GUI/ConfigWizard.cpp:1413 msgid "Nozzle and Bed Temperatures" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1415 +#: src/slic3r/GUI/ConfigWizard.cpp:1413 msgid "Temperatures" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1431 +#: src/slic3r/GUI/ConfigWizard.cpp:1429 msgid "Enter the temperature needed for extruding your filament." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1432 +#: src/slic3r/GUI/ConfigWizard.cpp:1430 msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1435 +#: src/slic3r/GUI/ConfigWizard.cpp:1433 msgid "Extrusion Temperature:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1436 src/slic3r/GUI/ConfigWizard.cpp:1450 -#: src/libslic3r/PrintConfig.cpp:202 src/libslic3r/PrintConfig.cpp:950 -#: src/libslic3r/PrintConfig.cpp:994 src/libslic3r/PrintConfig.cpp:2294 +#: src/slic3r/GUI/ConfigWizard.cpp:1434 src/slic3r/GUI/ConfigWizard.cpp:1448 +#: src/libslic3r/PrintConfig.cpp:202 src/libslic3r/PrintConfig.cpp:975 +#: src/libslic3r/PrintConfig.cpp:1019 src/libslic3r/PrintConfig.cpp:2383 msgid "°C" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1445 +#: src/slic3r/GUI/ConfigWizard.cpp:1443 msgid "" "Enter the bed temperature needed for getting your filament to stick to your " "heated bed." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1446 +#: src/slic3r/GUI/ConfigWizard.cpp:1444 msgid "" "A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have " "no heated bed." msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1449 +#: src/slic3r/GUI/ConfigWizard.cpp:1447 msgid "Bed Temperature:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1909 src/slic3r/GUI/ConfigWizard.cpp:2582 +#: src/slic3r/GUI/ConfigWizard.cpp:1907 src/slic3r/GUI/ConfigWizard.cpp:2580 msgid "Filaments" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1909 src/slic3r/GUI/ConfigWizard.cpp:2584 +#: src/slic3r/GUI/ConfigWizard.cpp:1907 src/slic3r/GUI/ConfigWizard.cpp:2582 msgid "SLA Materials" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1963 +#: src/slic3r/GUI/ConfigWizard.cpp:1961 msgid "FFF Technology Printers" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1968 +#: src/slic3r/GUI/ConfigWizard.cpp:1966 msgid "SLA Technology Printers" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2274 src/slic3r/GUI/DoubleSlider.cpp:2245 -#: src/slic3r/GUI/DoubleSlider.cpp:2265 src/slic3r/GUI/GUI.cpp:244 +#: src/slic3r/GUI/ConfigWizard.cpp:2272 src/slic3r/GUI/DoubleSlider.cpp:2265 +#: src/slic3r/GUI/DoubleSlider.cpp:2285 src/slic3r/GUI/GUI.cpp:250 msgid "Notice" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2295 +#: src/slic3r/GUI/ConfigWizard.cpp:2293 msgid "The following FFF printer models have no filament selected:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2299 +#: src/slic3r/GUI/ConfigWizard.cpp:2297 msgid "Do you want to select default filaments for these FFF printer models?" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2313 +#: src/slic3r/GUI/ConfigWizard.cpp:2311 msgid "The following SLA printer models have no materials selected:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2317 +#: src/slic3r/GUI/ConfigWizard.cpp:2315 msgid "Do you want to select default SLA materials for these printer models?" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2545 +#: src/slic3r/GUI/ConfigWizard.cpp:2543 msgid "Select all standard printers" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2548 +#: src/slic3r/GUI/ConfigWizard.cpp:2546 msgid "< &Back" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2549 +#: src/slic3r/GUI/ConfigWizard.cpp:2547 msgid "&Next >" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2550 +#: src/slic3r/GUI/ConfigWizard.cpp:2548 msgid "&Finish" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2551 src/slic3r/GUI/FirmwareDialog.cpp:151 +#: src/slic3r/GUI/ConfigWizard.cpp:2549 src/slic3r/GUI/FirmwareDialog.cpp:151 #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:248 #: src/slic3r/GUI/ProgressStatusBar.cpp:26 #: src/slic3r/GUI/UnsavedChangesDialog.cpp:656 msgid "Cancel" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2564 +#: src/slic3r/GUI/ConfigWizard.cpp:2562 msgid "Prusa FFF Technology Printers" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2567 +#: src/slic3r/GUI/ConfigWizard.cpp:2565 msgid "Prusa MSLA Technology Printers" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2582 +#: src/slic3r/GUI/ConfigWizard.cpp:2580 msgid "Filament Profiles Selection" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2582 src/slic3r/GUI/ConfigWizard.cpp:2584 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4144 +#: src/slic3r/GUI/ConfigWizard.cpp:2580 src/slic3r/GUI/ConfigWizard.cpp:2582 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4178 msgid "Type:" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2584 +#: src/slic3r/GUI/ConfigWizard.cpp:2582 msgid "SLA Material Profiles Selection" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2701 +#: src/slic3r/GUI/ConfigWizard.cpp:2699 msgid "Configuration Assistant" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2702 +#: src/slic3r/GUI/ConfigWizard.cpp:2700 msgid "Configuration &Assistant" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2704 +#: src/slic3r/GUI/ConfigWizard.cpp:2702 msgid "Configuration Wizard" msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:2705 +#: src/slic3r/GUI/ConfigWizard.cpp:2703 msgid "Configuration &Wizard" msgstr "" @@ -971,19 +973,19 @@ msgstr "" msgid "Place bearings in slots and resume printing" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1224 +#: src/slic3r/GUI/DoubleSlider.cpp:1244 msgid "One layer mode" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1226 +#: src/slic3r/GUI/DoubleSlider.cpp:1246 msgid "Discard all custom changes" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1230 src/slic3r/GUI/DoubleSlider.cpp:1995 +#: src/slic3r/GUI/DoubleSlider.cpp:1250 src/slic3r/GUI/DoubleSlider.cpp:2015 msgid "Jump to move" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1233 +#: src/slic3r/GUI/DoubleSlider.cpp:1253 #, possible-c-format msgid "" "Jump to height %s\n" @@ -991,48 +993,48 @@ msgid "" "or Set extruder sequence for the entire print" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1236 +#: src/slic3r/GUI/DoubleSlider.cpp:1256 #, possible-c-format msgid "" "Jump to height %s\n" "or Set ruler mode" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1241 +#: src/slic3r/GUI/DoubleSlider.cpp:1261 msgid "Edit current color - Right click the colored slider segment" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1251 +#: src/slic3r/GUI/DoubleSlider.cpp:1271 msgid "Print mode" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1265 +#: src/slic3r/GUI/DoubleSlider.cpp:1285 msgid "Add extruder change - Left click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1267 +#: src/slic3r/GUI/DoubleSlider.cpp:1287 msgid "" "Add color change - Left click for predefined color or Shift + Left click for " "custom color selection" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1269 +#: src/slic3r/GUI/DoubleSlider.cpp:1289 msgid "Add color change - Left click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1270 +#: src/slic3r/GUI/DoubleSlider.cpp:1290 msgid "or press \"+\" key" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1272 +#: src/slic3r/GUI/DoubleSlider.cpp:1292 msgid "Add another code - Ctrl + Left click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1273 +#: src/slic3r/GUI/DoubleSlider.cpp:1293 msgid "Add another code - Right click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1279 +#: src/slic3r/GUI/DoubleSlider.cpp:1299 msgid "" "The sequential print is on.\n" "It's impossible to apply any custom G-code for objects printing " @@ -1040,255 +1042,255 @@ msgid "" "This code won't be processed during G-code generation." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1288 +#: src/slic3r/GUI/DoubleSlider.cpp:1308 msgid "Color change (\"%1%\")" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1289 +#: src/slic3r/GUI/DoubleSlider.cpp:1309 msgid "Color change (\"%1%\") for Extruder %2%" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1291 +#: src/slic3r/GUI/DoubleSlider.cpp:1311 msgid "Pause print (\"%1%\")" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1293 +#: src/slic3r/GUI/DoubleSlider.cpp:1313 msgid "Custom template (\"%1%\")" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1295 +#: src/slic3r/GUI/DoubleSlider.cpp:1315 msgid "Extruder (tool) is changed to Extruder \"%1%\"" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1302 +#: src/slic3r/GUI/DoubleSlider.cpp:1322 msgid "Note" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1304 +#: src/slic3r/GUI/DoubleSlider.cpp:1324 msgid "" "G-code associated to this tick mark is in a conflict with print mode.\n" "Editing it will cause changes of Slider data." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1307 +#: src/slic3r/GUI/DoubleSlider.cpp:1327 msgid "" "There is a color change for extruder that won't be used till the end of " "print job.\n" "This code won't be processed during G-code generation." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1310 +#: src/slic3r/GUI/DoubleSlider.cpp:1330 msgid "" "There is an extruder change set to the same extruder.\n" "This code won't be processed during G-code generation." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1313 +#: src/slic3r/GUI/DoubleSlider.cpp:1333 msgid "" "There is a color change for extruder that has not been used before.\n" "Check your settings to avoid redundant color changes." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1318 +#: src/slic3r/GUI/DoubleSlider.cpp:1338 msgid "Delete tick mark - Left click or press \"-\" key" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1320 +#: src/slic3r/GUI/DoubleSlider.cpp:1340 msgid "Edit tick mark - Ctrl + Left click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1321 +#: src/slic3r/GUI/DoubleSlider.cpp:1341 msgid "Edit tick mark - Right click" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1417 src/slic3r/GUI/DoubleSlider.cpp:1451 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1864 +#: src/slic3r/GUI/DoubleSlider.cpp:1437 src/slic3r/GUI/DoubleSlider.cpp:1471 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1882 #, possible-c-format msgid "Extruder %d" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1418 src/slic3r/GUI/GUI_ObjectList.cpp:1865 +#: src/slic3r/GUI/DoubleSlider.cpp:1438 src/slic3r/GUI/GUI_ObjectList.cpp:1883 msgid "active" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1427 +#: src/slic3r/GUI/DoubleSlider.cpp:1447 msgid "Switch code to Change extruder" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1427 src/slic3r/GUI/GUI_ObjectList.cpp:1832 +#: src/slic3r/GUI/DoubleSlider.cpp:1447 src/slic3r/GUI/GUI_ObjectList.cpp:1850 msgid "Change extruder" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1428 +#: src/slic3r/GUI/DoubleSlider.cpp:1448 msgid "Change extruder (N/A)" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1430 +#: src/slic3r/GUI/DoubleSlider.cpp:1450 msgid "Use another extruder" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1452 +#: src/slic3r/GUI/DoubleSlider.cpp:1472 msgid "used" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1460 +#: src/slic3r/GUI/DoubleSlider.cpp:1480 msgid "Switch code to Color change (%1%) for:" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1461 +#: src/slic3r/GUI/DoubleSlider.cpp:1481 msgid "Add color change (%1%) for:" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1797 +#: src/slic3r/GUI/DoubleSlider.cpp:1817 msgid "Add color change" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1808 +#: src/slic3r/GUI/DoubleSlider.cpp:1828 msgid "Add pause print" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1812 +#: src/slic3r/GUI/DoubleSlider.cpp:1832 msgid "Add custom template" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1815 +#: src/slic3r/GUI/DoubleSlider.cpp:1835 msgid "Add custom G-code" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1833 +#: src/slic3r/GUI/DoubleSlider.cpp:1853 msgid "Edit color" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1834 +#: src/slic3r/GUI/DoubleSlider.cpp:1854 msgid "Edit pause print message" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1835 +#: src/slic3r/GUI/DoubleSlider.cpp:1855 msgid "Edit custom G-code" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1841 +#: src/slic3r/GUI/DoubleSlider.cpp:1861 msgid "Delete color change" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1842 +#: src/slic3r/GUI/DoubleSlider.cpp:1862 msgid "Delete tool change" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1843 +#: src/slic3r/GUI/DoubleSlider.cpp:1863 msgid "Delete pause print" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1844 +#: src/slic3r/GUI/DoubleSlider.cpp:1864 msgid "Delete custom G-code" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1854 src/slic3r/GUI/DoubleSlider.cpp:1995 +#: src/slic3r/GUI/DoubleSlider.cpp:1874 src/slic3r/GUI/DoubleSlider.cpp:2015 msgid "Jump to height" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1859 +#: src/slic3r/GUI/DoubleSlider.cpp:1879 msgid "Hide ruler" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1863 +#: src/slic3r/GUI/DoubleSlider.cpp:1883 msgid "Show object height" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1863 +#: src/slic3r/GUI/DoubleSlider.cpp:1883 msgid "Show object height on the ruler" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1867 +#: src/slic3r/GUI/DoubleSlider.cpp:1887 msgid "Show estimated print time" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1867 +#: src/slic3r/GUI/DoubleSlider.cpp:1887 msgid "Show estimated print time on the ruler" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1871 +#: src/slic3r/GUI/DoubleSlider.cpp:1891 msgid "Ruler mode" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1871 +#: src/slic3r/GUI/DoubleSlider.cpp:1891 msgid "Set ruler mode" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1876 +#: src/slic3r/GUI/DoubleSlider.cpp:1896 msgid "Set extruder sequence for the entire print" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1962 +#: src/slic3r/GUI/DoubleSlider.cpp:1982 msgid "Enter custom G-code used on current layer" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1963 +#: src/slic3r/GUI/DoubleSlider.cpp:1983 msgid "Custom G-code on current layer (%1% mm)." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1978 +#: src/slic3r/GUI/DoubleSlider.cpp:1998 msgid "Enter short message shown on Printer display when a print is paused" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1979 +#: src/slic3r/GUI/DoubleSlider.cpp:1999 msgid "Message for pause print on current layer (%1% mm)." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1994 +#: src/slic3r/GUI/DoubleSlider.cpp:2014 msgid "Enter the move you want to jump to" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:1994 +#: src/slic3r/GUI/DoubleSlider.cpp:2014 msgid "Enter the height you want to jump to" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2239 +#: src/slic3r/GUI/DoubleSlider.cpp:2259 msgid "The last color change data was saved for a single extruder printing." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2240 src/slic3r/GUI/DoubleSlider.cpp:2255 +#: src/slic3r/GUI/DoubleSlider.cpp:2260 src/slic3r/GUI/DoubleSlider.cpp:2275 msgid "The last color change data was saved for a multi extruder printing." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2242 +#: src/slic3r/GUI/DoubleSlider.cpp:2262 msgid "Your current changes will delete all saved color changes." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2243 src/slic3r/GUI/DoubleSlider.cpp:2263 +#: src/slic3r/GUI/DoubleSlider.cpp:2263 src/slic3r/GUI/DoubleSlider.cpp:2283 msgid "Are you sure you want to continue?" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2256 +#: src/slic3r/GUI/DoubleSlider.cpp:2276 msgid "" "Select YES if you want to delete all saved tool changes, \n" "NO if you want all tool changes switch to color changes, \n" "or CANCEL to leave it unchanged." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2259 +#: src/slic3r/GUI/DoubleSlider.cpp:2279 msgid "Do you want to delete all saved tool changes?" msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2261 +#: src/slic3r/GUI/DoubleSlider.cpp:2281 msgid "" "The last color change data was saved for a multi extruder printing with tool " "changes for whole print." msgstr "" -#: src/slic3r/GUI/DoubleSlider.cpp:2262 +#: src/slic3r/GUI/DoubleSlider.cpp:2282 msgid "Your current changes will delete all saved extruder (tool) changes." msgstr "" -#: src/slic3r/GUI/ExtraRenderers.cpp:297 src/slic3r/GUI/GUI_ObjectList.cpp:512 -#: src/slic3r/GUI/GUI_ObjectList.cpp:524 src/slic3r/GUI/GUI_ObjectList.cpp:1033 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4582 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4592 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4627 +#: src/slic3r/GUI/ExtraRenderers.cpp:296 src/slic3r/GUI/GUI_ObjectList.cpp:526 +#: src/slic3r/GUI/GUI_ObjectList.cpp:538 src/slic3r/GUI/GUI_ObjectList.cpp:1047 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4616 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4626 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4661 #: src/slic3r/GUI/ObjectDataViewModel.cpp:209 #: src/slic3r/GUI/ObjectDataViewModel.cpp:266 #: src/slic3r/GUI/ObjectDataViewModel.cpp:291 -#: src/slic3r/GUI/ObjectDataViewModel.cpp:499 src/libslic3r/PrintConfig.cpp:552 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:499 src/libslic3r/PrintConfig.cpp:577 msgid "default" msgstr "" @@ -1301,10 +1303,10 @@ msgid "Set extruder change for every" msgstr "" #: src/slic3r/GUI/ExtruderSequenceDialog.cpp:53 -#: src/libslic3r/PrintConfig.cpp:418 src/libslic3r/PrintConfig.cpp:1089 -#: src/libslic3r/PrintConfig.cpp:1718 src/libslic3r/PrintConfig.cpp:1883 -#: src/libslic3r/PrintConfig.cpp:1950 src/libslic3r/PrintConfig.cpp:2157 -#: src/libslic3r/PrintConfig.cpp:2203 +#: src/libslic3r/PrintConfig.cpp:443 src/libslic3r/PrintConfig.cpp:1178 +#: src/libslic3r/PrintConfig.cpp:1807 src/libslic3r/PrintConfig.cpp:1972 +#: src/libslic3r/PrintConfig.cpp:2039 src/libslic3r/PrintConfig.cpp:2246 +#: src/libslic3r/PrintConfig.cpp:2292 msgid "layers" msgstr "" @@ -1328,7 +1330,7 @@ msgstr "" msgid "parameter name" msgstr "" -#: src/slic3r/GUI/Field.cpp:211 src/slic3r/GUI/OptionsGroup.cpp:781 +#: src/slic3r/GUI/Field.cpp:211 src/slic3r/GUI/OptionsGroup.cpp:780 #: src/slic3r/GUI/UnsavedChangesDialog.cpp:886 msgid "N/A" msgstr "" @@ -1339,7 +1341,7 @@ msgid "%s doesn't support percentage" msgstr "" #: src/slic3r/GUI/Field.cpp:253 src/slic3r/GUI/Field.cpp:307 -#: src/slic3r/GUI/Field.cpp:1520 src/slic3r/GUI/GUI_ObjectLayers.cpp:413 +#: src/slic3r/GUI/Field.cpp:1507 src/slic3r/GUI/GUI_ObjectLayers.cpp:413 msgid "Invalid numeric input." msgstr "" @@ -1355,7 +1357,7 @@ msgid "Parameter validation" msgstr "" #: src/slic3r/GUI/Field.cpp:279 src/slic3r/GUI/Field.cpp:373 -#: src/slic3r/GUI/Field.cpp:1532 +#: src/slic3r/GUI/Field.cpp:1519 msgid "Input value is out of range" msgstr "" @@ -1481,7 +1483,7 @@ msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:852 #: src/slic3r/GUI/Mouse3DController.cpp:551 -#: src/slic3r/GUI/PrintHostDialogs.cpp:189 +#: src/slic3r/GUI/PrintHostDialogs.cpp:200 msgid "Close" msgstr "" @@ -1499,222 +1501,222 @@ msgstr "" msgid "Cancelling..." msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:239 +#: src/slic3r/GUI/GCodeViewer.cpp:289 msgid "Tool position" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:1016 +#: src/slic3r/GUI/GCodeViewer.cpp:1418 src/slic3r/GUI/GCodeViewer.cpp:1918 msgid "Generating toolpaths" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:1405 +#: src/slic3r/GUI/GCodeViewer.cpp:1456 src/slic3r/GUI/GCodeViewer.cpp:2302 msgid "Generating vertex buffer" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:1496 +#: src/slic3r/GUI/GCodeViewer.cpp:1719 src/slic3r/GUI/GCodeViewer.cpp:2390 msgid "Generating index buffers" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2225 +#: src/slic3r/GUI/GCodeViewer.cpp:3535 msgid "Click to hide" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2225 +#: src/slic3r/GUI/GCodeViewer.cpp:3535 msgid "Click to show" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2337 +#: src/slic3r/GUI/GCodeViewer.cpp:3647 msgid "up to" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2343 +#: src/slic3r/GUI/GCodeViewer.cpp:3653 msgid "above" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2351 +#: src/slic3r/GUI/GCodeViewer.cpp:3661 msgid "from" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2351 +#: src/slic3r/GUI/GCodeViewer.cpp:3661 msgid "to" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2379 src/slic3r/GUI/GCodeViewer.cpp:2387 -#: src/slic3r/GUI/GUI_Preview.cpp:214 src/slic3r/GUI/GUI_Preview.cpp:533 -#: src/slic3r/GUI/GUI_Preview.cpp:942 +#: src/slic3r/GUI/GCodeViewer.cpp:3689 src/slic3r/GUI/GCodeViewer.cpp:3697 +#: src/slic3r/GUI/GUI_Preview.cpp:211 src/slic3r/GUI/GUI_Preview.cpp:536 +#: src/slic3r/GUI/GUI_Preview.cpp:945 msgid "Feature type" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2379 src/slic3r/GUI/GCodeViewer.cpp:2387 +#: src/slic3r/GUI/GCodeViewer.cpp:3689 src/slic3r/GUI/GCodeViewer.cpp:3697 #: src/slic3r/GUI/RammingChart.cpp:76 msgid "Time" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2387 +#: src/slic3r/GUI/GCodeViewer.cpp:3697 msgid "Percentage" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2390 +#: src/slic3r/GUI/GCodeViewer.cpp:3700 msgid "Height (mm)" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2391 +#: src/slic3r/GUI/GCodeViewer.cpp:3701 msgid "Width (mm)" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2392 +#: src/slic3r/GUI/GCodeViewer.cpp:3702 msgid "Speed (mm/s)" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2393 +#: src/slic3r/GUI/GCodeViewer.cpp:3703 msgid "Fan Speed (%)" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2394 +#: src/slic3r/GUI/GCodeViewer.cpp:3704 msgid "Volumetric flow rate (mm³/s)" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2395 src/slic3r/GUI/GUI_Preview.cpp:220 -#: src/slic3r/GUI/GUI_Preview.cpp:326 src/slic3r/GUI/GUI_Preview.cpp:471 -#: src/slic3r/GUI/GUI_Preview.cpp:532 src/slic3r/GUI/GUI_Preview.cpp:878 -#: src/slic3r/GUI/GUI_Preview.cpp:942 +#: src/slic3r/GUI/GCodeViewer.cpp:3705 src/slic3r/GUI/GUI_Preview.cpp:217 +#: src/slic3r/GUI/GUI_Preview.cpp:323 src/slic3r/GUI/GUI_Preview.cpp:474 +#: src/slic3r/GUI/GUI_Preview.cpp:535 src/slic3r/GUI/GUI_Preview.cpp:881 +#: src/slic3r/GUI/GUI_Preview.cpp:945 msgid "Tool" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2396 src/slic3r/GUI/GUI_Preview.cpp:221 -#: src/slic3r/GUI/GUI_Preview.cpp:530 src/slic3r/GUI/GUI_Preview.cpp:941 +#: src/slic3r/GUI/GCodeViewer.cpp:3706 src/slic3r/GUI/GUI_Preview.cpp:218 +#: src/slic3r/GUI/GUI_Preview.cpp:533 src/slic3r/GUI/GUI_Preview.cpp:944 msgid "Color Print" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2432 src/slic3r/GUI/GCodeViewer.cpp:2467 -#: src/slic3r/GUI/GCodeViewer.cpp:2472 src/slic3r/GUI/GUI_ObjectList.cpp:312 -#: src/slic3r/GUI/wxExtensions.cpp:519 src/libslic3r/PrintConfig.cpp:547 +#: src/slic3r/GUI/GCodeViewer.cpp:3742 src/slic3r/GUI/GCodeViewer.cpp:3777 +#: src/slic3r/GUI/GCodeViewer.cpp:3782 src/slic3r/GUI/GUI_ObjectList.cpp:326 +#: src/slic3r/GUI/wxExtensions.cpp:519 src/libslic3r/PrintConfig.cpp:572 msgid "Extruder" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2443 +#: src/slic3r/GUI/GCodeViewer.cpp:3753 msgid "Default color" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2467 +#: src/slic3r/GUI/GCodeViewer.cpp:3777 msgid "default color" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2562 src/slic3r/GUI/GCodeViewer.cpp:2608 +#: src/slic3r/GUI/GCodeViewer.cpp:3872 src/slic3r/GUI/GCodeViewer.cpp:3918 msgid "Color change" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2581 src/slic3r/GUI/GCodeViewer.cpp:2606 +#: src/slic3r/GUI/GCodeViewer.cpp:3891 src/slic3r/GUI/GCodeViewer.cpp:3916 msgid "Print" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2607 src/slic3r/GUI/GCodeViewer.cpp:2624 +#: src/slic3r/GUI/GCodeViewer.cpp:3917 src/slic3r/GUI/GCodeViewer.cpp:3934 msgid "Pause" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2612 src/slic3r/GUI/GCodeViewer.cpp:2615 +#: src/slic3r/GUI/GCodeViewer.cpp:3922 src/slic3r/GUI/GCodeViewer.cpp:3925 msgid "Event" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2612 src/slic3r/GUI/GCodeViewer.cpp:2615 +#: src/slic3r/GUI/GCodeViewer.cpp:3922 src/slic3r/GUI/GCodeViewer.cpp:3925 msgid "Remaining time" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2615 +#: src/slic3r/GUI/GCodeViewer.cpp:3925 msgid "Duration" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2650 src/slic3r/GUI/GUI_Preview.cpp:1023 -#: src/libslic3r/PrintConfig.cpp:2380 +#: src/slic3r/GUI/GCodeViewer.cpp:3960 src/slic3r/GUI/GUI_Preview.cpp:1026 +#: src/libslic3r/PrintConfig.cpp:2469 msgid "Travel" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2653 +#: src/slic3r/GUI/GCodeViewer.cpp:3963 msgid "Movement" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2654 +#: src/slic3r/GUI/GCodeViewer.cpp:3964 msgid "Extrusion" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2655 src/slic3r/GUI/Tab.cpp:1694 -#: src/slic3r/GUI/Tab.cpp:2582 +#: src/slic3r/GUI/GCodeViewer.cpp:3965 src/slic3r/GUI/Tab.cpp:1708 +#: src/slic3r/GUI/Tab.cpp:2596 msgid "Retraction" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2672 src/slic3r/GUI/GCodeViewer.cpp:2675 -#: src/slic3r/GUI/GUI_Preview.cpp:1024 +#: src/slic3r/GUI/GCodeViewer.cpp:3982 src/slic3r/GUI/GCodeViewer.cpp:3985 +#: src/slic3r/GUI/GUI_Preview.cpp:1027 msgid "Wipe" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2706 src/slic3r/GUI/GUI_Preview.cpp:248 -#: src/slic3r/GUI/GUI_Preview.cpp:262 +#: src/slic3r/GUI/GCodeViewer.cpp:4016 src/slic3r/GUI/GUI_Preview.cpp:245 +#: src/slic3r/GUI/GUI_Preview.cpp:259 msgid "Options" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2709 src/slic3r/GUI/GUI_Preview.cpp:1025 +#: src/slic3r/GUI/GCodeViewer.cpp:4019 src/slic3r/GUI/GUI_Preview.cpp:1028 msgid "Retractions" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2710 src/slic3r/GUI/GUI_Preview.cpp:1026 +#: src/slic3r/GUI/GCodeViewer.cpp:4020 src/slic3r/GUI/GUI_Preview.cpp:1029 msgid "Deretractions" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2711 src/slic3r/GUI/GUI_Preview.cpp:1027 +#: src/slic3r/GUI/GCodeViewer.cpp:4021 src/slic3r/GUI/GUI_Preview.cpp:1030 msgid "Tool changes" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2712 src/slic3r/GUI/GUI_Preview.cpp:1028 +#: src/slic3r/GUI/GCodeViewer.cpp:4022 src/slic3r/GUI/GUI_Preview.cpp:1031 msgid "Color changes" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2713 src/slic3r/GUI/GUI_Preview.cpp:1029 +#: src/slic3r/GUI/GCodeViewer.cpp:4023 src/slic3r/GUI/GUI_Preview.cpp:1032 msgid "Print pauses" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2714 src/slic3r/GUI/GUI_Preview.cpp:1030 +#: src/slic3r/GUI/GCodeViewer.cpp:4024 src/slic3r/GUI/GUI_Preview.cpp:1033 msgid "Custom G-codes" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2725 src/slic3r/GUI/GCodeViewer.cpp:2749 -#: src/slic3r/GUI/Plater.cpp:697 src/libslic3r/PrintConfig.cpp:117 +#: src/slic3r/GUI/GCodeViewer.cpp:4035 src/slic3r/GUI/GCodeViewer.cpp:4059 +#: src/slic3r/GUI/Plater.cpp:694 src/libslic3r/PrintConfig.cpp:117 msgid "Printer" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2727 src/slic3r/GUI/GCodeViewer.cpp:2754 -#: src/slic3r/GUI/Plater.cpp:693 +#: src/slic3r/GUI/GCodeViewer.cpp:4037 src/slic3r/GUI/GCodeViewer.cpp:4064 +#: src/slic3r/GUI/Plater.cpp:690 msgid "Print settings" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2730 src/slic3r/GUI/GCodeViewer.cpp:2760 -#: src/slic3r/GUI/Plater.cpp:694 src/slic3r/GUI/Tab.cpp:1794 -#: src/slic3r/GUI/Tab.cpp:1795 +#: src/slic3r/GUI/GCodeViewer.cpp:4040 src/slic3r/GUI/GCodeViewer.cpp:4070 +#: src/slic3r/GUI/Plater.cpp:691 src/slic3r/GUI/Tab.cpp:1808 +#: src/slic3r/GUI/Tab.cpp:1809 msgid "Filament" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2785 src/slic3r/GUI/GCodeViewer.cpp:2790 -#: src/slic3r/GUI/Plater.cpp:242 src/slic3r/GUI/Plater.cpp:1135 -#: src/slic3r/GUI/Plater.cpp:1220 +#: src/slic3r/GUI/GCodeViewer.cpp:4095 src/slic3r/GUI/GCodeViewer.cpp:4100 +#: src/slic3r/GUI/Plater.cpp:242 src/slic3r/GUI/Plater.cpp:1143 +#: src/slic3r/GUI/Plater.cpp:1228 msgid "Estimated printing time" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2785 +#: src/slic3r/GUI/GCodeViewer.cpp:4095 msgid "Normal mode" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2790 +#: src/slic3r/GUI/GCodeViewer.cpp:4100 msgid "Stealth mode" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2817 +#: src/slic3r/GUI/GCodeViewer.cpp:4128 msgid "Show stealth mode" msgstr "" -#: src/slic3r/GUI/GCodeViewer.cpp:2821 +#: src/slic3r/GUI/GCodeViewer.cpp:4132 msgid "Show normal mode" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:236 src/slic3r/GUI/GLCanvas3D.cpp:4610 +#: src/slic3r/GUI/GLCanvas3D.cpp:236 src/slic3r/GUI/GLCanvas3D.cpp:4619 msgid "Variable layer height" msgstr "" @@ -1774,7 +1776,7 @@ msgstr "" msgid "Smooth" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:285 src/libslic3r/PrintConfig.cpp:571 +#: src/slic3r/GUI/GLCanvas3D.cpp:285 src/libslic3r/PrintConfig.cpp:596 msgid "Radius" msgstr "" @@ -1782,7 +1784,7 @@ msgstr "" msgid "Keep min" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:304 src/slic3r/GUI/GLCanvas3D.cpp:4050 +#: src/slic3r/GUI/GLCanvas3D.cpp:304 src/slic3r/GUI/GLCanvas3D.cpp:4055 msgid "Reset" msgstr "" @@ -1842,171 +1844,171 @@ msgstr "" msgid "Gizmo-Rotate" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3388 +#: src/slic3r/GUI/GLCanvas3D.cpp:3389 msgid "Move Object" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3858 src/slic3r/GUI/GLCanvas3D.cpp:4571 +#: src/slic3r/GUI/GLCanvas3D.cpp:3859 src/slic3r/GUI/GLCanvas3D.cpp:4580 msgid "Switch to Settings" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3859 src/slic3r/GUI/GLCanvas3D.cpp:4571 +#: src/slic3r/GUI/GLCanvas3D.cpp:3860 src/slic3r/GUI/GLCanvas3D.cpp:4580 msgid "Print Settings Tab" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3860 src/slic3r/GUI/GLCanvas3D.cpp:4572 +#: src/slic3r/GUI/GLCanvas3D.cpp:3861 src/slic3r/GUI/GLCanvas3D.cpp:4581 msgid "Filament Settings Tab" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3860 src/slic3r/GUI/GLCanvas3D.cpp:4572 +#: src/slic3r/GUI/GLCanvas3D.cpp:3861 src/slic3r/GUI/GLCanvas3D.cpp:4581 msgid "Material Settings Tab" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3861 src/slic3r/GUI/GLCanvas3D.cpp:4573 +#: src/slic3r/GUI/GLCanvas3D.cpp:3862 src/slic3r/GUI/GLCanvas3D.cpp:4582 msgid "Printer Settings Tab" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3909 +#: src/slic3r/GUI/GLCanvas3D.cpp:3914 msgid "Undo History" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3909 +#: src/slic3r/GUI/GLCanvas3D.cpp:3914 msgid "Redo History" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3930 +#: src/slic3r/GUI/GLCanvas3D.cpp:3935 #, possible-c-format msgid "Undo %1$d Action" msgid_plural "Undo %1$d Actions" msgstr[0] "" msgstr[1] "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3930 +#: src/slic3r/GUI/GLCanvas3D.cpp:3935 #, possible-c-format msgid "Redo %1$d Action" msgid_plural "Redo %1$d Actions" msgstr[0] "" msgstr[1] "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3950 src/slic3r/GUI/GLCanvas3D.cpp:4589 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:98 src/slic3r/GUI/Search.cpp:351 +#: src/slic3r/GUI/GLCanvas3D.cpp:3955 src/slic3r/GUI/GLCanvas3D.cpp:4598 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:98 src/slic3r/GUI/Search.cpp:348 msgid "Search" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:3964 src/slic3r/GUI/GLCanvas3D.cpp:3972 -#: src/slic3r/GUI/Search.cpp:358 +#: src/slic3r/GUI/GLCanvas3D.cpp:3969 src/slic3r/GUI/GLCanvas3D.cpp:3977 +#: src/slic3r/GUI/Search.cpp:355 msgid "Enter a search term" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4003 +#: src/slic3r/GUI/GLCanvas3D.cpp:4008 msgid "Arrange options" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4033 +#: src/slic3r/GUI/GLCanvas3D.cpp:4038 msgid "Press %1%left mouse button to enter the exact value" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4035 +#: src/slic3r/GUI/GLCanvas3D.cpp:4040 msgid "Spacing" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4042 +#: src/slic3r/GUI/GLCanvas3D.cpp:4047 msgid "Enable rotations (slow)" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4060 src/slic3r/GUI/GLCanvas3D.cpp:4481 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:120 src/slic3r/GUI/Plater.cpp:1648 +#: src/slic3r/GUI/GLCanvas3D.cpp:4065 src/slic3r/GUI/GLCanvas3D.cpp:4490 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:120 src/slic3r/GUI/Plater.cpp:1656 msgid "Arrange" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4455 +#: src/slic3r/GUI/GLCanvas3D.cpp:4464 msgid "Add..." msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4463 src/slic3r/GUI/GUI_ObjectList.cpp:1878 -#: src/slic3r/GUI/Plater.cpp:3998 src/slic3r/GUI/Plater.cpp:4022 -#: src/slic3r/GUI/Tab.cpp:3484 +#: src/slic3r/GUI/GLCanvas3D.cpp:4472 src/slic3r/GUI/GUI_ObjectList.cpp:1896 +#: src/slic3r/GUI/Plater.cpp:4019 src/slic3r/GUI/Plater.cpp:4043 +#: src/slic3r/GUI/Tab.cpp:3502 msgid "Delete" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4472 src/slic3r/GUI/KBShortcutsDialog.cpp:88 -#: src/slic3r/GUI/Plater.cpp:5107 +#: src/slic3r/GUI/GLCanvas3D.cpp:4481 src/slic3r/GUI/KBShortcutsDialog.cpp:88 +#: src/slic3r/GUI/Plater.cpp:5130 msgid "Delete all" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4481 src/slic3r/GUI/KBShortcutsDialog.cpp:121 +#: src/slic3r/GUI/GLCanvas3D.cpp:4490 src/slic3r/GUI/KBShortcutsDialog.cpp:121 msgid "Arrange selection" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4481 +#: src/slic3r/GUI/GLCanvas3D.cpp:4490 msgid "Click right mouse button to show arrangement options" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4503 +#: src/slic3r/GUI/GLCanvas3D.cpp:4512 msgid "Copy" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4512 +#: src/slic3r/GUI/GLCanvas3D.cpp:4521 msgid "Paste" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4524 src/slic3r/GUI/Plater.cpp:3857 -#: src/slic3r/GUI/Plater.cpp:3869 src/slic3r/GUI/Plater.cpp:4007 +#: src/slic3r/GUI/GLCanvas3D.cpp:4533 src/slic3r/GUI/Plater.cpp:3878 +#: src/slic3r/GUI/Plater.cpp:3890 src/slic3r/GUI/Plater.cpp:4028 msgid "Add instance" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4535 src/slic3r/GUI/Plater.cpp:4009 +#: src/slic3r/GUI/GLCanvas3D.cpp:4544 src/slic3r/GUI/Plater.cpp:4030 msgid "Remove instance" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4548 +#: src/slic3r/GUI/GLCanvas3D.cpp:4557 msgid "Split to objects" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4558 src/slic3r/GUI/GUI_ObjectList.cpp:1650 +#: src/slic3r/GUI/GLCanvas3D.cpp:4567 src/slic3r/GUI/GUI_ObjectList.cpp:1668 msgid "Split to parts" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4660 src/slic3r/GUI/KBShortcutsDialog.cpp:89 +#: src/slic3r/GUI/GLCanvas3D.cpp:4669 src/slic3r/GUI/KBShortcutsDialog.cpp:89 #: src/slic3r/GUI/MainFrame.cpp:1125 msgid "Undo" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4660 src/slic3r/GUI/GLCanvas3D.cpp:4699 +#: src/slic3r/GUI/GLCanvas3D.cpp:4669 src/slic3r/GUI/GLCanvas3D.cpp:4708 msgid "Click right mouse button to open/close History" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4683 +#: src/slic3r/GUI/GLCanvas3D.cpp:4692 msgid "Next Undo action: %1%" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4699 src/slic3r/GUI/KBShortcutsDialog.cpp:90 +#: src/slic3r/GUI/GLCanvas3D.cpp:4708 src/slic3r/GUI/KBShortcutsDialog.cpp:90 #: src/slic3r/GUI/MainFrame.cpp:1128 msgid "Redo" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:4721 +#: src/slic3r/GUI/GLCanvas3D.cpp:4730 msgid "Next Redo action: %1%" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:6345 +#: src/slic3r/GUI/GLCanvas3D.cpp:6354 msgid "Selection-Add from rectangle" msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:6364 +#: src/slic3r/GUI/GLCanvas3D.cpp:6373 msgid "Selection-Remove from rectangle" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:54 -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:151 src/libslic3r/PrintConfig.cpp:3690 +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:151 src/libslic3r/PrintConfig.cpp:3771 msgid "Cut" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:179 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:341 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:418 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:486 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:487 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:322 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:399 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:467 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:468 msgid "in" msgstr "" @@ -2097,7 +2099,7 @@ msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:54 #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:37 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1613 msgid "Sphere" msgstr "" @@ -2176,7 +2178,7 @@ msgid "Quality" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:44 -#: src/libslic3r/PrintConfig.cpp:3183 +#: src/libslic3r/PrintConfig.cpp:3272 msgid "Closing distance" msgstr "" @@ -2229,18 +2231,18 @@ msgid "Move" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:461 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:508 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:527 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:546 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:562 -#: src/libslic3r/PrintConfig.cpp:3739 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:543 +#: src/libslic3r/PrintConfig.cpp:3820 msgid "Rotate" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:78 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:238 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:547 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:563 -#: src/libslic3r/PrintConfig.cpp:3754 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:219 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:528 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:544 +#: src/libslic3r/PrintConfig.cpp:3835 msgid "Scale" msgstr "" @@ -2290,7 +2292,7 @@ msgid "Minimal points distance" msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:54 -#: src/libslic3r/PrintConfig.cpp:3013 +#: src/libslic3r/PrintConfig.cpp:3102 msgid "Support points density" msgstr "" @@ -2355,9 +2357,9 @@ msgstr "" msgid "Are you sure you want to do it?" msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1129 src/slic3r/GUI/GUI.cpp:256 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1129 src/slic3r/GUI/GUI.cpp:262 #: src/slic3r/GUI/PhysicalPrinterDialog.cpp:557 -#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:581 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:586 #: src/slic3r/GUI/WipeTowerDialog.cpp:45 src/slic3r/GUI/WipeTowerDialog.cpp:366 msgid "Warning" msgstr "" @@ -2466,21 +2468,21 @@ msgstr "" msgid "Add supports" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:239 +#: src/slic3r/GUI/GUI_App.cpp:247 msgid "is based on Slic3r by Alessandro Ranellucci and the RepRap community." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:241 +#: src/slic3r/GUI/GUI_App.cpp:249 msgid "" "Contributions by Vojtech Bubnik, Enrico Turri, Oleksandra Iushchenko, Tamas " "Meszaros, Lukas Matena, Vojtech Kral, David Kocik and numerous others." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:242 +#: src/slic3r/GUI/GUI_App.cpp:250 msgid "Artwork model by Nora Al-Badri and Jan Nikolai Nelles" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:382 +#: src/slic3r/GUI/GUI_App.cpp:391 msgid "" "Starting with %1% 2.3, configuration directory on Linux has changed " "(according to XDG Base Directory Specification) to \n" @@ -2499,20 +2501,20 @@ msgid "" "What do you want to do now?" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:390 +#: src/slic3r/GUI/GUI_App.cpp:399 #, possible-c-format msgid "%s - BREAKING CHANGE" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:392 +#: src/slic3r/GUI/GUI_App.cpp:401 msgid "Quit, I will move my data now" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:392 +#: src/slic3r/GUI/GUI_App.cpp:401 msgid "Start the application" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:580 +#: src/slic3r/GUI/GUI_App.cpp:589 #, possible-c-format msgid "" "%s has encountered an error. It was likely caused by running out of memory. " @@ -2522,11 +2524,11 @@ msgid "" "The application will now terminate." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:583 +#: src/slic3r/GUI/GUI_App.cpp:592 msgid "Fatal error" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:587 +#: src/slic3r/GUI/GUI_App.cpp:596 msgid "" "PrusaSlicer has encountered a localization error. Please report to " "PrusaSlicer team, what language was active and in which scenario this issue " @@ -2535,256 +2537,258 @@ msgid "" "The application will now terminate." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:590 +#: src/slic3r/GUI/GUI_App.cpp:599 msgid "Critical error" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:711 +#: src/slic3r/GUI/GUI_App.cpp:726 msgid "" "Error parsing PrusaSlicer config file, it is probably corrupted. Try to " "manually delete the file to recover from the error. Your user profiles will " "not be affected." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:717 +#: src/slic3r/GUI/GUI_App.cpp:732 msgid "" "Error parsing PrusaGCodeViewer config file, it is probably corrupted. Try to " "manually delete the file to recover from the error." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:771 +#: src/slic3r/GUI/GUI_App.cpp:787 #, possible-c-format msgid "" "%s\n" "Do you want to continue?" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:773 src/slic3r/GUI/UnsavedChangesDialog.cpp:665 +#: src/slic3r/GUI/GUI_App.cpp:789 src/slic3r/GUI/UnsavedChangesDialog.cpp:665 msgid "Remember my choice" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:808 +#: src/slic3r/GUI/GUI_App.cpp:827 msgid "Loading configuration" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:876 +#: src/slic3r/GUI/GUI_App.cpp:892 msgid "Preparing settings tabs" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1115 +#: src/slic3r/GUI/GUI_App.cpp:1149 msgid "" "You have the following presets with saved options for \"Print Host upload\"" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1119 +#: src/slic3r/GUI/GUI_App.cpp:1153 msgid "" "But since this version of PrusaSlicer we don't show this information in " "Printer Settings anymore.\n" "Settings will be available in physical printers settings." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1121 +#: src/slic3r/GUI/GUI_App.cpp:1155 msgid "" "By default new Printer devices will be named as \"Printer N\" during its " "creation.\n" "Note: This name can be changed later from the physical printers settings" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1124 src/slic3r/GUI/PhysicalPrinterDialog.cpp:626 +#: src/slic3r/GUI/GUI_App.cpp:1158 src/slic3r/GUI/PhysicalPrinterDialog.cpp:631 msgid "Information" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1137 src/slic3r/GUI/GUI_App.cpp:1148 +#: src/slic3r/GUI/GUI_App.cpp:1171 src/slic3r/GUI/GUI_App.cpp:1182 msgid "Recreating" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1153 +#: src/slic3r/GUI/GUI_App.cpp:1187 msgid "Loading of current presets" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1158 +#: src/slic3r/GUI/GUI_App.cpp:1192 msgid "Loading of a mode view" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1234 +#: src/slic3r/GUI/GUI_App.cpp:1269 msgid "Choose one file (3MF/AMF):" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1246 +#: src/slic3r/GUI/GUI_App.cpp:1281 msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1258 +#: src/slic3r/GUI/GUI_App.cpp:1293 msgid "Choose one file (GCODE/.GCO/.G/.ngc/NGC):" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1269 +#: src/slic3r/GUI/GUI_App.cpp:1304 msgid "Changing of an application language" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1392 +#: src/slic3r/GUI/GUI_App.cpp:1427 msgid "Select the language" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1392 +#: src/slic3r/GUI/GUI_App.cpp:1427 msgid "Language" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1541 +#: src/slic3r/GUI/GUI_App.cpp:1576 msgid "modified" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1590 +#: src/slic3r/GUI/GUI_App.cpp:1625 #, possible-c-format msgid "Run %s" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1594 +#: src/slic3r/GUI/GUI_App.cpp:1629 msgid "&Configuration Snapshots" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1594 +#: src/slic3r/GUI/GUI_App.cpp:1629 msgid "Inspect / activate configuration snapshots" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1595 +#: src/slic3r/GUI/GUI_App.cpp:1630 msgid "Take Configuration &Snapshot" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1595 +#: src/slic3r/GUI/GUI_App.cpp:1630 msgid "Capture a configuration snapshot" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1596 +#: src/slic3r/GUI/GUI_App.cpp:1631 msgid "Check for updates" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1596 +#: src/slic3r/GUI/GUI_App.cpp:1631 msgid "Check for configuration updates" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1599 +#: src/slic3r/GUI/GUI_App.cpp:1634 msgid "&Preferences" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1605 +#: src/slic3r/GUI/GUI_App.cpp:1640 msgid "Application preferences" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1610 src/slic3r/GUI/wxExtensions.cpp:685 +#: src/slic3r/GUI/GUI_App.cpp:1645 src/slic3r/GUI/wxExtensions.cpp:685 msgid "Simple" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1610 +#: src/slic3r/GUI/GUI_App.cpp:1645 msgid "Simple View Mode" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1612 src/slic3r/GUI/wxExtensions.cpp:687 +#: src/slic3r/GUI/GUI_App.cpp:1647 src/slic3r/GUI/wxExtensions.cpp:687 msgctxt "Mode" msgid "Advanced" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1612 +#: src/slic3r/GUI/GUI_App.cpp:1647 msgid "Advanced View Mode" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1613 src/slic3r/GUI/wxExtensions.cpp:688 +#: src/slic3r/GUI/GUI_App.cpp:1648 src/slic3r/GUI/wxExtensions.cpp:688 msgid "Expert" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1613 +#: src/slic3r/GUI/GUI_App.cpp:1648 msgid "Expert View Mode" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1618 +#: src/slic3r/GUI/GUI_App.cpp:1653 msgid "Mode" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1618 +#: src/slic3r/GUI/GUI_App.cpp:1653 #, possible-c-format msgid "%s View Mode" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1621 +#: src/slic3r/GUI/GUI_App.cpp:1656 msgid "&Language" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1624 +#: src/slic3r/GUI/GUI_App.cpp:1659 msgid "Flash printer &firmware" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1624 +#: src/slic3r/GUI/GUI_App.cpp:1659 msgid "Upload a firmware image into an Arduino based printer" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1640 +#: src/slic3r/GUI/GUI_App.cpp:1675 msgid "Taking configuration snapshot" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1640 +#: src/slic3r/GUI/GUI_App.cpp:1675 msgid "Snapshot name" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1669 +#: src/slic3r/GUI/GUI_App.cpp:1704 msgid "Failed to activate configuration snapshot." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1719 +#: src/slic3r/GUI/GUI_App.cpp:1754 msgid "Language selection" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1721 +#: src/slic3r/GUI/GUI_App.cpp:1756 msgid "" "Switching the language will trigger application restart.\n" "You will lose content of the plater." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1723 +#: src/slic3r/GUI/GUI_App.cpp:1758 msgid "Do you want to proceed?" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1750 +#: src/slic3r/GUI/GUI_App.cpp:1785 msgid "&Configuration" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1781 -msgid "The preset(s) modifications are successfully saved" -msgstr "" +#: src/slic3r/GUI/GUI_App.cpp:1816 +msgid "The preset modifications are successfully saved" +msgid_plural "The presets modifications are successfully saved" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_App.cpp:1802 +#: src/slic3r/GUI/GUI_App.cpp:1838 msgid "The uploads are still ongoing" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1802 +#: src/slic3r/GUI/GUI_App.cpp:1838 msgid "Stop them and continue anyway?" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:1805 +#: src/slic3r/GUI/GUI_App.cpp:1841 msgid "Ongoing uploads" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:2019 src/slic3r/GUI/Tab.cpp:3242 +#: src/slic3r/GUI/GUI_App.cpp:2052 src/slic3r/GUI/Tab.cpp:3256 msgid "It's impossible to print multi-part object(s) with SLA technology." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:2020 +#: src/slic3r/GUI/GUI_App.cpp:2053 msgid "Please check and fix your object list." msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:2021 src/slic3r/GUI/Jobs/SLAImportJob.cpp:210 -#: src/slic3r/GUI/Plater.cpp:2359 src/slic3r/GUI/Tab.cpp:3244 +#: src/slic3r/GUI/GUI_App.cpp:2054 src/slic3r/GUI/Jobs/SLAImportJob.cpp:210 +#: src/slic3r/GUI/Plater.cpp:2367 src/slic3r/GUI/Tab.cpp:3258 msgid "Attention!" msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:2038 +#: src/slic3r/GUI/GUI_App.cpp:2071 msgid "Select a gcode file:" msgstr "" -#: src/slic3r/GUI/GUI_Init.cpp:73 src/slic3r/GUI/GUI_Init.cpp:76 +#: src/slic3r/GUI/GUI_Init.cpp:88 src/slic3r/GUI/GUI_Init.cpp:91 msgid "PrusaSlicer GUI initialization failed" msgstr "" -#: src/slic3r/GUI/GUI_Init.cpp:76 +#: src/slic3r/GUI/GUI_Init.cpp:91 msgid "Fatal error, exception catched: %1%" msgstr "" @@ -2805,38 +2809,38 @@ msgid "Add layer range" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:34 src/slic3r/GUI/GUI_ObjectList.cpp:92 -#: src/slic3r/GUI/GUI_ObjectList.cpp:667 src/libslic3r/PrintConfig.cpp:74 +#: src/slic3r/GUI/GUI_ObjectList.cpp:681 src/libslic3r/PrintConfig.cpp:74 #: src/libslic3r/PrintConfig.cpp:189 src/libslic3r/PrintConfig.cpp:231 -#: src/libslic3r/PrintConfig.cpp:240 src/libslic3r/PrintConfig.cpp:464 -#: src/libslic3r/PrintConfig.cpp:530 src/libslic3r/PrintConfig.cpp:538 -#: src/libslic3r/PrintConfig.cpp:970 src/libslic3r/PrintConfig.cpp:1219 -#: src/libslic3r/PrintConfig.cpp:1584 src/libslic3r/PrintConfig.cpp:1650 -#: src/libslic3r/PrintConfig.cpp:1835 src/libslic3r/PrintConfig.cpp:2302 -#: src/libslic3r/PrintConfig.cpp:2361 src/libslic3r/PrintConfig.cpp:2370 +#: src/libslic3r/PrintConfig.cpp:240 src/libslic3r/PrintConfig.cpp:489 +#: src/libslic3r/PrintConfig.cpp:555 src/libslic3r/PrintConfig.cpp:563 +#: src/libslic3r/PrintConfig.cpp:995 src/libslic3r/PrintConfig.cpp:1308 +#: src/libslic3r/PrintConfig.cpp:1673 src/libslic3r/PrintConfig.cpp:1739 +#: src/libslic3r/PrintConfig.cpp:1924 src/libslic3r/PrintConfig.cpp:2391 +#: src/libslic3r/PrintConfig.cpp:2450 src/libslic3r/PrintConfig.cpp:2459 msgid "Layers and Perimeters" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:36 src/slic3r/GUI/GUI_ObjectList.cpp:95 -#: src/slic3r/GUI/GUI_ObjectList.cpp:670 src/slic3r/GUI/GUI_Preview.cpp:240 -#: src/slic3r/GUI/Tab.cpp:1472 src/slic3r/GUI/Tab.cpp:1474 +#: src/slic3r/GUI/GUI_ObjectList.cpp:684 src/slic3r/GUI/GUI_Preview.cpp:237 +#: src/slic3r/GUI/Tab.cpp:1486 src/slic3r/GUI/Tab.cpp:1488 #: src/libslic3r/ExtrusionEntity.cpp:320 src/libslic3r/ExtrusionEntity.cpp:352 -#: src/libslic3r/PrintConfig.cpp:426 src/libslic3r/PrintConfig.cpp:1715 -#: src/libslic3r/PrintConfig.cpp:2093 src/libslic3r/PrintConfig.cpp:2099 -#: src/libslic3r/PrintConfig.cpp:2107 src/libslic3r/PrintConfig.cpp:2119 -#: src/libslic3r/PrintConfig.cpp:2129 src/libslic3r/PrintConfig.cpp:2137 -#: src/libslic3r/PrintConfig.cpp:2152 src/libslic3r/PrintConfig.cpp:2173 -#: src/libslic3r/PrintConfig.cpp:2185 src/libslic3r/PrintConfig.cpp:2201 -#: src/libslic3r/PrintConfig.cpp:2210 src/libslic3r/PrintConfig.cpp:2219 -#: src/libslic3r/PrintConfig.cpp:2230 src/libslic3r/PrintConfig.cpp:2244 -#: src/libslic3r/PrintConfig.cpp:2252 src/libslic3r/PrintConfig.cpp:2253 -#: src/libslic3r/PrintConfig.cpp:2262 src/libslic3r/PrintConfig.cpp:2270 -#: src/libslic3r/PrintConfig.cpp:2284 +#: src/libslic3r/PrintConfig.cpp:451 src/libslic3r/PrintConfig.cpp:1804 +#: src/libslic3r/PrintConfig.cpp:2182 src/libslic3r/PrintConfig.cpp:2188 +#: src/libslic3r/PrintConfig.cpp:2196 src/libslic3r/PrintConfig.cpp:2208 +#: src/libslic3r/PrintConfig.cpp:2218 src/libslic3r/PrintConfig.cpp:2226 +#: src/libslic3r/PrintConfig.cpp:2241 src/libslic3r/PrintConfig.cpp:2262 +#: src/libslic3r/PrintConfig.cpp:2274 src/libslic3r/PrintConfig.cpp:2290 +#: src/libslic3r/PrintConfig.cpp:2299 src/libslic3r/PrintConfig.cpp:2308 +#: src/libslic3r/PrintConfig.cpp:2319 src/libslic3r/PrintConfig.cpp:2333 +#: src/libslic3r/PrintConfig.cpp:2341 src/libslic3r/PrintConfig.cpp:2342 +#: src/libslic3r/PrintConfig.cpp:2351 src/libslic3r/PrintConfig.cpp:2359 +#: src/libslic3r/PrintConfig.cpp:2373 msgid "Support material" msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:39 src/slic3r/GUI/GUI_ObjectList.cpp:99 -#: src/slic3r/GUI/GUI_ObjectList.cpp:674 src/libslic3r/PrintConfig.cpp:2480 -#: src/libslic3r/PrintConfig.cpp:2488 +#: src/slic3r/GUI/GUI_ObjectList.cpp:688 src/libslic3r/PrintConfig.cpp:2569 +#: src/libslic3r/PrintConfig.cpp:2577 msgid "Wipe options" msgstr "" @@ -2860,432 +2864,458 @@ msgstr "" msgid "Add support blocker" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:94 src/slic3r/GUI/GUI_ObjectList.cpp:669 -#: src/slic3r/GUI/GUI_Preview.cpp:236 src/slic3r/GUI/Tab.cpp:1442 +#: src/slic3r/GUI/GUI_ObjectList.cpp:94 src/slic3r/GUI/GUI_ObjectList.cpp:683 +#: src/slic3r/GUI/GUI_Preview.cpp:233 src/slic3r/GUI/Tab.cpp:1454 #: src/libslic3r/ExtrusionEntity.cpp:316 src/libslic3r/ExtrusionEntity.cpp:344 -#: src/libslic3r/PrintConfig.cpp:1226 src/libslic3r/PrintConfig.cpp:1232 -#: src/libslic3r/PrintConfig.cpp:1246 src/libslic3r/PrintConfig.cpp:1256 -#: src/libslic3r/PrintConfig.cpp:1264 src/libslic3r/PrintConfig.cpp:1266 +#: src/libslic3r/PrintConfig.cpp:1315 src/libslic3r/PrintConfig.cpp:1321 +#: src/libslic3r/PrintConfig.cpp:1335 src/libslic3r/PrintConfig.cpp:1345 +#: src/libslic3r/PrintConfig.cpp:1353 src/libslic3r/PrintConfig.cpp:1355 msgid "Ironing" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:96 src/slic3r/GUI/GUI_ObjectList.cpp:671 -#: src/slic3r/GUI/GUI_Preview.cpp:217 src/slic3r/GUI/Tab.cpp:1498 -#: src/libslic3r/PrintConfig.cpp:291 src/libslic3r/PrintConfig.cpp:518 -#: src/libslic3r/PrintConfig.cpp:1012 src/libslic3r/PrintConfig.cpp:1192 -#: src/libslic3r/PrintConfig.cpp:1265 src/libslic3r/PrintConfig.cpp:1640 -#: src/libslic3r/PrintConfig.cpp:1916 src/libslic3r/PrintConfig.cpp:1968 -#: src/libslic3r/PrintConfig.cpp:2346 +#: src/slic3r/GUI/GUI_ObjectList.cpp:96 src/slic3r/GUI/GUI_ObjectList.cpp:685 +#: src/slic3r/GUI/GUI_Preview.cpp:214 src/slic3r/GUI/Tab.cpp:1512 +#: src/libslic3r/PrintConfig.cpp:291 src/libslic3r/PrintConfig.cpp:543 +#: src/libslic3r/PrintConfig.cpp:1101 src/libslic3r/PrintConfig.cpp:1281 +#: src/libslic3r/PrintConfig.cpp:1354 src/libslic3r/PrintConfig.cpp:1729 +#: src/libslic3r/PrintConfig.cpp:2005 src/libslic3r/PrintConfig.cpp:2057 +#: src/libslic3r/PrintConfig.cpp:2435 msgid "Speed" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:97 src/slic3r/GUI/GUI_ObjectList.cpp:672 -#: src/slic3r/GUI/Tab.cpp:1534 src/slic3r/GUI/Tab.cpp:2112 -#: src/libslic3r/PrintConfig.cpp:548 src/libslic3r/PrintConfig.cpp:1146 -#: src/libslic3r/PrintConfig.cpp:1618 src/libslic3r/PrintConfig.cpp:1937 -#: src/libslic3r/PrintConfig.cpp:2165 src/libslic3r/PrintConfig.cpp:2192 +#: src/slic3r/GUI/GUI_ObjectList.cpp:97 src/slic3r/GUI/GUI_ObjectList.cpp:686 +#: src/slic3r/GUI/Tab.cpp:1548 src/slic3r/GUI/Tab.cpp:2126 +#: src/libslic3r/PrintConfig.cpp:573 src/libslic3r/PrintConfig.cpp:1235 +#: src/libslic3r/PrintConfig.cpp:1707 src/libslic3r/PrintConfig.cpp:2026 +#: src/libslic3r/PrintConfig.cpp:2254 src/libslic3r/PrintConfig.cpp:2281 msgid "Extruders" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:98 src/slic3r/GUI/GUI_ObjectList.cpp:673 -#: src/libslic3r/PrintConfig.cpp:507 src/libslic3r/PrintConfig.cpp:616 -#: src/libslic3r/PrintConfig.cpp:957 src/libslic3r/PrintConfig.cpp:1154 -#: src/libslic3r/PrintConfig.cpp:1627 src/libslic3r/PrintConfig.cpp:1957 -#: src/libslic3r/PrintConfig.cpp:2174 src/libslic3r/PrintConfig.cpp:2334 +#: src/slic3r/GUI/GUI_ObjectList.cpp:98 src/slic3r/GUI/GUI_ObjectList.cpp:687 +#: src/libslic3r/PrintConfig.cpp:532 src/libslic3r/PrintConfig.cpp:641 +#: src/libslic3r/PrintConfig.cpp:982 src/libslic3r/PrintConfig.cpp:1243 +#: src/libslic3r/PrintConfig.cpp:1716 src/libslic3r/PrintConfig.cpp:2046 +#: src/libslic3r/PrintConfig.cpp:2263 src/libslic3r/PrintConfig.cpp:2423 msgid "Extrusion Width" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:102 src/slic3r/GUI/GUI_ObjectList.cpp:677 -#: src/slic3r/GUI/Tab.cpp:1428 src/slic3r/GUI/Tab.cpp:1452 -#: src/slic3r/GUI/Tab.cpp:1555 src/slic3r/GUI/Tab.cpp:1558 -#: src/slic3r/GUI/Tab.cpp:1855 src/slic3r/GUI/Tab.cpp:2197 -#: src/slic3r/GUI/Tab.cpp:4114 src/libslic3r/PrintConfig.cpp:92 +#: src/slic3r/GUI/GUI_ObjectList.cpp:100 src/slic3r/GUI/GUI_ObjectList.cpp:689 +#: src/slic3r/GUI/Tab.cpp:1472 src/libslic3r/PrintConfig.cpp:301 +#: src/libslic3r/PrintConfig.cpp:310 src/libslic3r/PrintConfig.cpp:326 +msgid "Skirt and brim" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:102 src/slic3r/GUI/GUI_ObjectList.cpp:691 +#: src/slic3r/GUI/Tab.cpp:1428 src/slic3r/GUI/Tab.cpp:1464 +#: src/slic3r/GUI/Tab.cpp:1569 src/slic3r/GUI/Tab.cpp:1572 +#: src/slic3r/GUI/Tab.cpp:1869 src/slic3r/GUI/Tab.cpp:2211 +#: src/slic3r/GUI/Tab.cpp:4132 src/libslic3r/PrintConfig.cpp:92 #: src/libslic3r/PrintConfig.cpp:132 src/libslic3r/PrintConfig.cpp:279 -#: src/libslic3r/PrintConfig.cpp:1097 src/libslic3r/PrintConfig.cpp:1181 -#: src/libslic3r/PrintConfig.cpp:2504 src/libslic3r/PrintConfig.cpp:2676 +#: src/libslic3r/PrintConfig.cpp:1186 src/libslic3r/PrintConfig.cpp:1270 +#: src/libslic3r/PrintConfig.cpp:2593 src/libslic3r/PrintConfig.cpp:2765 msgid "Advanced" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:104 src/slic3r/GUI/GUI_ObjectList.cpp:679 -#: src/slic3r/GUI/Plater.cpp:357 src/slic3r/GUI/Tab.cpp:4048 -#: src/slic3r/GUI/Tab.cpp:4049 src/libslic3r/PrintConfig.cpp:2842 -#: src/libslic3r/PrintConfig.cpp:2849 src/libslic3r/PrintConfig.cpp:2858 -#: src/libslic3r/PrintConfig.cpp:2867 src/libslic3r/PrintConfig.cpp:2877 -#: src/libslic3r/PrintConfig.cpp:2887 src/libslic3r/PrintConfig.cpp:2924 -#: src/libslic3r/PrintConfig.cpp:2931 src/libslic3r/PrintConfig.cpp:2942 -#: src/libslic3r/PrintConfig.cpp:2952 src/libslic3r/PrintConfig.cpp:2961 -#: src/libslic3r/PrintConfig.cpp:2974 src/libslic3r/PrintConfig.cpp:2984 -#: src/libslic3r/PrintConfig.cpp:2993 src/libslic3r/PrintConfig.cpp:3003 -#: src/libslic3r/PrintConfig.cpp:3014 src/libslic3r/PrintConfig.cpp:3022 +#: src/slic3r/GUI/GUI_ObjectList.cpp:104 src/slic3r/GUI/GUI_ObjectList.cpp:693 +#: src/slic3r/GUI/Plater.cpp:357 src/slic3r/GUI/Tab.cpp:4066 +#: src/slic3r/GUI/Tab.cpp:4067 src/libslic3r/PrintConfig.cpp:2931 +#: src/libslic3r/PrintConfig.cpp:2938 src/libslic3r/PrintConfig.cpp:2947 +#: src/libslic3r/PrintConfig.cpp:2956 src/libslic3r/PrintConfig.cpp:2966 +#: src/libslic3r/PrintConfig.cpp:2976 src/libslic3r/PrintConfig.cpp:3013 +#: src/libslic3r/PrintConfig.cpp:3020 src/libslic3r/PrintConfig.cpp:3031 +#: src/libslic3r/PrintConfig.cpp:3041 src/libslic3r/PrintConfig.cpp:3050 +#: src/libslic3r/PrintConfig.cpp:3063 src/libslic3r/PrintConfig.cpp:3073 +#: src/libslic3r/PrintConfig.cpp:3082 src/libslic3r/PrintConfig.cpp:3092 +#: src/libslic3r/PrintConfig.cpp:3103 src/libslic3r/PrintConfig.cpp:3111 msgid "Supports" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:105 src/slic3r/GUI/GUI_ObjectList.cpp:680 -#: src/slic3r/GUI/Plater.cpp:500 src/slic3r/GUI/Tab.cpp:4089 -#: src/slic3r/GUI/Tab.cpp:4090 src/slic3r/GUI/Tab.cpp:4161 -#: src/libslic3r/PrintConfig.cpp:3030 src/libslic3r/PrintConfig.cpp:3037 -#: src/libslic3r/PrintConfig.cpp:3051 src/libslic3r/PrintConfig.cpp:3062 -#: src/libslic3r/PrintConfig.cpp:3072 src/libslic3r/PrintConfig.cpp:3094 -#: src/libslic3r/PrintConfig.cpp:3105 src/libslic3r/PrintConfig.cpp:3112 -#: src/libslic3r/PrintConfig.cpp:3119 src/libslic3r/PrintConfig.cpp:3130 -#: src/libslic3r/PrintConfig.cpp:3139 src/libslic3r/PrintConfig.cpp:3148 +#: src/slic3r/GUI/GUI_ObjectList.cpp:105 src/slic3r/GUI/GUI_ObjectList.cpp:694 +#: src/slic3r/GUI/Plater.cpp:500 src/slic3r/GUI/Tab.cpp:4107 +#: src/slic3r/GUI/Tab.cpp:4108 src/slic3r/GUI/Tab.cpp:4179 +#: src/libslic3r/PrintConfig.cpp:3119 src/libslic3r/PrintConfig.cpp:3126 +#: src/libslic3r/PrintConfig.cpp:3140 src/libslic3r/PrintConfig.cpp:3151 +#: src/libslic3r/PrintConfig.cpp:3161 src/libslic3r/PrintConfig.cpp:3183 +#: src/libslic3r/PrintConfig.cpp:3194 src/libslic3r/PrintConfig.cpp:3201 +#: src/libslic3r/PrintConfig.cpp:3208 src/libslic3r/PrintConfig.cpp:3219 +#: src/libslic3r/PrintConfig.cpp:3228 src/libslic3r/PrintConfig.cpp:3237 msgid "Pad" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:106 src/slic3r/GUI/Tab.cpp:4107 -#: src/slic3r/GUI/Tab.cpp:4108 src/libslic3r/SLA/Hollowing.cpp:45 +#: src/slic3r/GUI/GUI_ObjectList.cpp:106 src/slic3r/GUI/Tab.cpp:4125 +#: src/slic3r/GUI/Tab.cpp:4126 src/libslic3r/SLA/Hollowing.cpp:45 #: src/libslic3r/SLA/Hollowing.cpp:57 src/libslic3r/SLA/Hollowing.cpp:66 -#: src/libslic3r/SLA/Hollowing.cpp:75 src/libslic3r/PrintConfig.cpp:3158 -#: src/libslic3r/PrintConfig.cpp:3165 src/libslic3r/PrintConfig.cpp:3175 -#: src/libslic3r/PrintConfig.cpp:3184 +#: src/libslic3r/SLA/Hollowing.cpp:75 src/libslic3r/PrintConfig.cpp:3247 +#: src/libslic3r/PrintConfig.cpp:3254 src/libslic3r/PrintConfig.cpp:3264 +#: src/libslic3r/PrintConfig.cpp:3273 msgid "Hollowing" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:300 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:161 +#: src/slic3r/GUI/GUI_ObjectList.cpp:314 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:142 msgid "Name" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:316 src/slic3r/GUI/GUI_ObjectList.cpp:457 +#: src/slic3r/GUI/GUI_ObjectList.cpp:330 src/slic3r/GUI/GUI_ObjectList.cpp:471 msgid "Editing" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:402 +#: src/slic3r/GUI/GUI_ObjectList.cpp:416 src/slic3r/GUI/Plater.cpp:1074 #, possible-c-format -msgid "Auto-repaired (%d errors):" -msgstr "" +msgid "Auto-repaired %1$d error" +msgid_plural "Auto-repaired %1$d errors" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:409 -msgid "degenerate facets" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:423 src/slic3r/GUI/Plater.cpp:1079 +#, possible-c-format +msgid "%1$d degenerate facet" +msgid_plural "%1$d degenerate facets" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:410 -msgid "edges fixed" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:425 src/slic3r/GUI/Plater.cpp:1081 +#, possible-c-format +msgid "%1$d edge fixed" +msgid_plural "%1$d edges fixed" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:411 -msgid "facets removed" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:427 src/slic3r/GUI/Plater.cpp:1083 +#, possible-c-format +msgid "%1$d facet removed" +msgid_plural "%1$d facets removed" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:412 -msgid "facets added" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:429 src/slic3r/GUI/Plater.cpp:1085 +#, possible-c-format +msgid "%1$d facet added" +msgid_plural "%1$d facets added" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:413 -msgid "facets reversed" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:431 src/slic3r/GUI/Plater.cpp:1087 +#, possible-c-format +msgid "%1$d facet reversed" +msgid_plural "%1$d facets reversed" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:414 -msgid "backwards edges" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:433 src/slic3r/GUI/Plater.cpp:1089 +#, possible-c-format +msgid "%1$d backwards edge" +msgid_plural "%1$d backwards edges" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:422 +#: src/slic3r/GUI/GUI_ObjectList.cpp:436 msgid "Right button click the icon to fix STL through Netfabb" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:459 +#: src/slic3r/GUI/GUI_ObjectList.cpp:473 msgid "Right button click the icon to change the object settings" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:461 +#: src/slic3r/GUI/GUI_ObjectList.cpp:475 msgid "Click the icon to change the object settings" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:465 +#: src/slic3r/GUI/GUI_ObjectList.cpp:479 msgid "Right button click the icon to change the object printable property" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:467 +#: src/slic3r/GUI/GUI_ObjectList.cpp:481 msgid "Click the icon to change the object printable property" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:590 +#: src/slic3r/GUI/GUI_ObjectList.cpp:604 msgid "Change Extruder" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:605 +#: src/slic3r/GUI/GUI_ObjectList.cpp:619 msgid "Rename Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:605 +#: src/slic3r/GUI/GUI_ObjectList.cpp:619 msgid "Rename Sub-object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1247 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4372 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1265 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4406 msgid "Instances to Separated Objects" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1262 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1280 msgid "Volumes in Object reordered" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1262 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1280 msgid "Object reordered" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1338 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1693 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1699 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2081 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1356 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1711 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1717 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2099 #, possible-c-format msgid "Quick Add Settings (%s)" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1428 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1446 msgid "Select showing settings" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1477 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1495 msgid "Add Settings for Layers" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1478 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1496 msgid "Add Settings for Sub-object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1479 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1497 msgid "Add Settings for Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1549 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1567 msgid "Add Settings Bundle for Height range" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1550 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1568 msgid "Add Settings Bundle for Sub-object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1551 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1569 msgid "Add Settings Bundle for Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1590 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1608 msgid "Load" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1627 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1631 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1613 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1645 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1649 msgid "Box" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1613 msgid "Cylinder" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1613 msgid "Slab" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1663 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1681 msgid "Height range Modifier" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1672 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1690 msgid "Add settings" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1750 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1768 msgid "Change type" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1760 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1772 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1778 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1790 msgid "Set as a Separated Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1772 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1790 msgid "Set as a Separated Objects" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1782 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1800 msgid "Printable" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1797 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1815 msgid "Rename" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1808 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1826 msgid "Fix through the Netfabb" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1818 src/slic3r/GUI/Plater.cpp:4035 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1836 src/slic3r/GUI/Plater.cpp:4056 msgid "Export as STL" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1825 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4567 src/slic3r/GUI/Plater.cpp:4001 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1843 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4601 src/slic3r/GUI/Plater.cpp:4022 msgid "Reload the selected volumes from disk" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1832 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1850 msgid "Set extruder for selected items" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1864 src/libslic3r/PrintConfig.cpp:391 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1882 src/libslic3r/PrintConfig.cpp:416 msgid "Default" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1884 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1902 msgid "Scale to print volume" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1884 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1902 msgid "Scale the selected object to fit the print volume" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1913 src/slic3r/GUI/Plater.cpp:5224 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1931 src/slic3r/GUI/Plater.cpp:5247 msgid "Convert from imperial units" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1915 src/slic3r/GUI/Plater.cpp:5224 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1933 src/slic3r/GUI/Plater.cpp:5247 msgid "Revert conversion from imperial units" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1944 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1952 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2630 src/libslic3r/PrintConfig.cpp:3730 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1962 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1970 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2650 src/libslic3r/PrintConfig.cpp:3811 msgid "Merge" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1944 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1962 msgid "Merge objects to the one multipart object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1952 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1970 msgid "Merge objects to the one single object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2026 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2283 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2044 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2301 msgid "Add Shape" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2111 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2129 msgid "Load Part" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2150 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2168 msgid "Error!" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2225 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2243 msgid "Add Generic Subobject" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2254 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2272 msgid "Generic" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2380 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2398 msgid "Delete Settings" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2402 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2422 msgid "Delete All Instances from Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2418 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2438 msgid "Delete Height Range" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2450 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2470 msgid "From Object List You can't delete the last solid part from object." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2454 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2474 msgid "Delete Subobject" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2469 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2489 msgid "Last instance of an object cannot be deleted." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2473 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2493 msgid "Delete Instance" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2497 src/slic3r/GUI/Plater.cpp:2865 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2517 src/slic3r/GUI/Plater.cpp:2879 msgid "" "The selected object couldn't be split because it contains only one part." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2501 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2521 msgid "Split to Parts" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2637 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2657 msgid "Merged" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2721 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2741 msgid "Merge all parts to the one single object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2753 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2773 msgid "Add Layers" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2907 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2927 msgid "Group manipulation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2919 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2939 msgid "Object manipulation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2932 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2952 msgid "Object Settings to modify" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2936 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2956 msgid "Part Settings to modify" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2941 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2961 msgid "Layer range Settings to modify" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2947 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2967 msgid "Part manipulation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2953 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2973 msgid "Instance manipulation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2960 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2980 msgid "Height ranges" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2960 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2980 msgid "Settings for height range" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3144 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3166 msgid "Delete Selected Item" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3332 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3354 msgid "Delete Selected" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3408 -#: src/slic3r/GUI/GUI_ObjectList.cpp:3436 -#: src/slic3r/GUI/GUI_ObjectList.cpp:3456 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3430 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3458 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3478 msgid "Add Height Range" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3502 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3524 msgid "" "Cannot insert a new layer range after the current layer range.\n" "The next layer range is too thin to be split to two\n" "without violating the minimum layer height." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3506 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3528 msgid "" "Cannot insert a new layer range between the current and the next layer " "range.\n" @@ -3293,212 +3323,212 @@ msgid "" "is thinner than the minimum layer height allowed." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3511 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3533 msgid "" "Cannot insert a new layer range after the current layer range.\n" "Current layer range overlaps with the next layer range." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3570 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3592 msgid "Edit Height Range" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3865 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3899 msgid "Selection-Remove from list" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:3873 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3907 msgid "Selection-Add from list" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4008 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4042 msgid "Object or Instance" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4009 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4043 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4176 msgid "Part" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4009 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4043 msgid "Layer" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4011 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4045 msgid "Unsupported selection" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4012 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4046 #, possible-c-format msgid "You started your selection with %s Item." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4013 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4047 #, possible-c-format msgid "In this mode you can select only other %s Items%s" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4016 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4050 msgid "of a current Object" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4021 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4096 src/slic3r/GUI/Plater.cpp:143 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4055 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4130 src/slic3r/GUI/Plater.cpp:143 msgid "Info" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4137 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4171 msgid "You can't change a type of the last solid part of the object." msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4176 msgid "Modifier" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4176 msgid "Support Enforcer" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4176 msgid "Support Blocker" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4144 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4178 msgid "Select type of part" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4149 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4183 msgid "Change Part Type" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4394 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4428 msgid "Enter new name" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4394 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4428 msgid "Renaming" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4410 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4537 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4444 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4571 #: src/slic3r/GUI/SavePresetDialog.cpp:101 #: src/slic3r/GUI/SavePresetDialog.cpp:109 msgid "The supplied name is not valid;" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4411 -#: src/slic3r/GUI/GUI_ObjectList.cpp:4538 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4445 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4572 #: src/slic3r/GUI/SavePresetDialog.cpp:102 msgid "the following characters are not allowed:" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4586 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4620 msgid "Select extruder number:" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4587 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4621 msgid "This extruder will be set for selected items" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4612 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4646 msgid "Change Extruders" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4709 src/slic3r/GUI/Selection.cpp:1485 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4743 src/slic3r/GUI/Selection.cpp:1485 msgid "Set Printable" msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:4709 src/slic3r/GUI/Selection.cpp:1485 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4743 src/slic3r/GUI/Selection.cpp:1485 msgid "Set Unprintable" msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:68 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:111 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:96 msgid "World coordinates" msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:69 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:112 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:97 msgid "Local coordinates" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:88 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:73 msgid "Select coordinate space, in which the transformation will be performed." msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:163 src/libslic3r/GCode.cpp:537 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:144 src/libslic3r/GCode.cpp:537 msgid "Object name" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:223 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:505 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:204 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:486 msgid "Position" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:224 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:506 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:205 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:487 #: src/slic3r/GUI/Mouse3DController.cpp:486 #: src/slic3r/GUI/Mouse3DController.cpp:507 msgid "Rotation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:271 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:252 #, possible-c-format msgid "Toggle %c axis mirroring" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:305 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:286 msgid "Set Mirror" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:345 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:357 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:326 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:338 msgid "Drop to bed" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:372 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:353 msgid "Reset rotation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:394 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:375 msgid "Reset Rotation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:407 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:409 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:388 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:390 msgid "Reset scale" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:423 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:404 msgid "Inches" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:507 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:488 msgid "Scale factors" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:561 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:542 msgid "Translate" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:625 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:606 msgid "" "You cannot use non-uniform scaling mode for multiple objects/parts selection" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:797 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:778 msgid "Set Position" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:828 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:809 msgid "Set Orientation" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:893 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:874 msgid "Set Scale" msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:925 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:906 msgid "" "The currently manipulated object is tilted (rotation angles are not " "multiples of 90°).\n" @@ -3507,7 +3537,7 @@ msgid "" "once the rotation is embedded into the object coordinates." msgstr "" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:928 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:909 msgid "" "This operation is irreversible.\n" "Do you want to proceed?" @@ -3531,132 +3561,132 @@ msgstr "" msgid "Change Option %s" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:212 +#: src/slic3r/GUI/GUI_Preview.cpp:209 msgid "View" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:215 src/libslic3r/PrintConfig.cpp:560 +#: src/slic3r/GUI/GUI_Preview.cpp:212 src/libslic3r/PrintConfig.cpp:585 msgid "Height" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:216 src/libslic3r/PrintConfig.cpp:2466 +#: src/slic3r/GUI/GUI_Preview.cpp:213 src/libslic3r/PrintConfig.cpp:2555 msgid "Width" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:218 src/slic3r/GUI/Tab.cpp:1840 +#: src/slic3r/GUI/GUI_Preview.cpp:215 src/slic3r/GUI/Tab.cpp:1854 msgid "Fan speed" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:219 +#: src/slic3r/GUI/GUI_Preview.cpp:216 msgid "Volumetric flow rate" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:224 +#: src/slic3r/GUI/GUI_Preview.cpp:221 msgid "Show" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:227 src/slic3r/GUI/GUI_Preview.cpp:245 +#: src/slic3r/GUI/GUI_Preview.cpp:224 src/slic3r/GUI/GUI_Preview.cpp:242 msgid "Feature types" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:230 src/libslic3r/ExtrusionEntity.cpp:310 +#: src/slic3r/GUI/GUI_Preview.cpp:227 src/libslic3r/ExtrusionEntity.cpp:310 #: src/libslic3r/ExtrusionEntity.cpp:332 msgid "Perimeter" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:231 src/libslic3r/ExtrusionEntity.cpp:311 +#: src/slic3r/GUI/GUI_Preview.cpp:228 src/libslic3r/ExtrusionEntity.cpp:311 #: src/libslic3r/ExtrusionEntity.cpp:334 msgid "External perimeter" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:232 src/libslic3r/ExtrusionEntity.cpp:312 +#: src/slic3r/GUI/GUI_Preview.cpp:229 src/libslic3r/ExtrusionEntity.cpp:312 #: src/libslic3r/ExtrusionEntity.cpp:336 msgid "Overhang perimeter" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:233 src/libslic3r/ExtrusionEntity.cpp:313 +#: src/slic3r/GUI/GUI_Preview.cpp:230 src/libslic3r/ExtrusionEntity.cpp:313 #: src/libslic3r/ExtrusionEntity.cpp:338 msgid "Internal infill" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:234 src/libslic3r/ExtrusionEntity.cpp:314 -#: src/libslic3r/ExtrusionEntity.cpp:340 src/libslic3r/PrintConfig.cpp:1956 -#: src/libslic3r/PrintConfig.cpp:1967 +#: src/slic3r/GUI/GUI_Preview.cpp:231 src/libslic3r/ExtrusionEntity.cpp:314 +#: src/libslic3r/ExtrusionEntity.cpp:340 src/libslic3r/PrintConfig.cpp:2045 +#: src/libslic3r/PrintConfig.cpp:2056 msgid "Solid infill" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:235 src/libslic3r/ExtrusionEntity.cpp:315 -#: src/libslic3r/ExtrusionEntity.cpp:342 src/libslic3r/PrintConfig.cpp:2333 -#: src/libslic3r/PrintConfig.cpp:2345 +#: src/slic3r/GUI/GUI_Preview.cpp:232 src/libslic3r/ExtrusionEntity.cpp:315 +#: src/libslic3r/ExtrusionEntity.cpp:342 src/libslic3r/PrintConfig.cpp:2422 +#: src/libslic3r/PrintConfig.cpp:2434 msgid "Top solid infill" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:237 src/libslic3r/ExtrusionEntity.cpp:317 +#: src/slic3r/GUI/GUI_Preview.cpp:234 src/libslic3r/ExtrusionEntity.cpp:317 #: src/libslic3r/ExtrusionEntity.cpp:346 msgid "Bridge infill" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:238 src/libslic3r/ExtrusionEntity.cpp:318 -#: src/libslic3r/ExtrusionEntity.cpp:348 src/libslic3r/PrintConfig.cpp:1011 +#: src/slic3r/GUI/GUI_Preview.cpp:235 src/libslic3r/ExtrusionEntity.cpp:318 +#: src/libslic3r/ExtrusionEntity.cpp:348 src/libslic3r/PrintConfig.cpp:1100 msgid "Gap fill" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:239 src/slic3r/GUI/Tab.cpp:1462 +#: src/slic3r/GUI/GUI_Preview.cpp:236 src/slic3r/GUI/Tab.cpp:1474 #: src/libslic3r/ExtrusionEntity.cpp:319 src/libslic3r/ExtrusionEntity.cpp:350 msgid "Skirt" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:241 src/libslic3r/ExtrusionEntity.cpp:321 -#: src/libslic3r/ExtrusionEntity.cpp:354 src/libslic3r/PrintConfig.cpp:2218 +#: src/slic3r/GUI/GUI_Preview.cpp:238 src/libslic3r/ExtrusionEntity.cpp:321 +#: src/libslic3r/ExtrusionEntity.cpp:354 src/libslic3r/PrintConfig.cpp:2307 msgid "Support material interface" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:242 src/slic3r/GUI/Tab.cpp:1545 +#: src/slic3r/GUI/GUI_Preview.cpp:239 src/slic3r/GUI/Tab.cpp:1559 #: src/libslic3r/ExtrusionEntity.cpp:322 src/libslic3r/ExtrusionEntity.cpp:356 msgid "Wipe tower" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:1031 +#: src/slic3r/GUI/GUI_Preview.cpp:1034 msgid "Shells" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:1032 +#: src/slic3r/GUI/GUI_Preview.cpp:1035 msgid "Tool marker" msgstr "" -#: src/slic3r/GUI/GUI_Preview.cpp:1033 +#: src/slic3r/GUI/GUI_Preview.cpp:1036 msgid "Legend/Estimated printing time" msgstr "" -#: src/slic3r/GUI/ImGuiWrapper.cpp:804 src/slic3r/GUI/Search.cpp:389 +#: src/slic3r/GUI/ImGuiWrapper.cpp:804 src/slic3r/GUI/Search.cpp:386 msgid "Use for search" msgstr "" -#: src/slic3r/GUI/ImGuiWrapper.cpp:805 src/slic3r/GUI/Search.cpp:383 +#: src/slic3r/GUI/ImGuiWrapper.cpp:805 src/slic3r/GUI/Search.cpp:380 msgid "Category" msgstr "" -#: src/slic3r/GUI/ImGuiWrapper.cpp:807 src/slic3r/GUI/Search.cpp:385 +#: src/slic3r/GUI/ImGuiWrapper.cpp:807 src/slic3r/GUI/Search.cpp:382 msgid "Search in English" msgstr "" -#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:145 -msgid "Arranging" -msgstr "" - -#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:175 +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:153 msgid "Could not arrange model objects! Some geometries may be invalid." msgstr "" -#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:181 +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:162 +msgid "Arranging" +msgstr "" + +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:191 msgid "Arranging canceled." msgstr "" -#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:182 +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:192 msgid "Arranging done." msgstr "" -#: src/slic3r/GUI/Jobs/Job.cpp:75 +#: src/slic3r/GUI/Jobs/Job.cpp:89 msgid "ERROR: not enough resources to execute a new job." msgstr "" @@ -3716,12 +3746,12 @@ msgstr "" msgid "Importing done." msgstr "" -#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:208 src/slic3r/GUI/Plater.cpp:2357 +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:208 src/slic3r/GUI/Plater.cpp:2365 msgid "You cannot load SLA project with a multi-part object on the bed" msgstr "" -#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:209 src/slic3r/GUI/Plater.cpp:2358 -#: src/slic3r/GUI/Tab.cpp:3243 +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:209 src/slic3r/GUI/Plater.cpp:2366 +#: src/slic3r/GUI/Tab.cpp:3257 msgid "Please check your object list before preset changing." msgstr "" @@ -3761,12 +3791,12 @@ msgstr "" msgid "Load Config from ini/amf/3mf/gcode and merge" msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:79 src/slic3r/GUI/Plater.cpp:770 -#: src/slic3r/GUI/Plater.cpp:6054 src/libslic3r/PrintConfig.cpp:3635 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:79 src/slic3r/GUI/Plater.cpp:767 +#: src/slic3r/GUI/Plater.cpp:6081 src/libslic3r/PrintConfig.cpp:3716 msgid "Export G-code" msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:80 src/slic3r/GUI/Plater.cpp:6055 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:80 src/slic3r/GUI/Plater.cpp:6082 msgid "Send G-code" msgstr "" @@ -3774,7 +3804,7 @@ msgstr "" msgid "Export config" msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:82 src/slic3r/GUI/Plater.cpp:758 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:82 src/slic3r/GUI/Plater.cpp:755 msgid "Export to SD card / Flash drive" msgstr "" @@ -3833,7 +3863,7 @@ msgid "Switch to Preview" msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:106 -#: src/slic3r/GUI/PrintHostDialogs.cpp:165 +#: src/slic3r/GUI/PrintHostDialogs.cpp:176 msgid "Print host upload queue" msgstr "" @@ -4137,8 +4167,8 @@ msgstr "" msgid "Show/Hide Legend & Estimated printing time" msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:215 src/slic3r/GUI/Plater.cpp:4200 -#: src/slic3r/GUI/Tab.cpp:2602 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:215 src/slic3r/GUI/Plater.cpp:4221 +#: src/slic3r/GUI/Tab.cpp:2616 msgid "Preview" msgstr "" @@ -4346,8 +4376,8 @@ msgstr "" #. TRN To be shown in the main menu View->Top #. TRN To be shown in Print Settings "Top solid layers" -#: src/slic3r/GUI/MainFrame.cpp:912 src/libslic3r/PrintConfig.cpp:2360 -#: src/libslic3r/PrintConfig.cpp:2369 +#: src/slic3r/GUI/MainFrame.cpp:912 src/libslic3r/PrintConfig.cpp:2449 +#: src/libslic3r/PrintConfig.cpp:2458 msgid "Top" msgstr "" @@ -4375,7 +4405,7 @@ msgstr "" msgid "Front View" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:919 src/libslic3r/PrintConfig.cpp:1845 +#: src/slic3r/GUI/MainFrame.cpp:919 src/libslic3r/PrintConfig.cpp:1934 msgid "Rear" msgstr "" @@ -4426,7 +4456,7 @@ msgid "" msgstr "" #: src/slic3r/GUI/MainFrame.cpp:953 src/slic3r/GUI/MainFrame.cpp:1343 -#: src/slic3r/GUI/PrintHostDialogs.cpp:263 +#: src/slic3r/GUI/PrintHostDialogs.cpp:274 msgid "Error" msgstr "" @@ -4780,7 +4810,7 @@ msgstr "" msgid "&Collapse sidebar" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:1204 src/slic3r/GUI/Plater.cpp:2247 +#: src/slic3r/GUI/MainFrame.cpp:1204 src/slic3r/GUI/Plater.cpp:2255 msgid "Collapse sidebar" msgstr "" @@ -4861,9 +4891,9 @@ msgstr "" msgid "Save zip file as:" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:1405 src/slic3r/GUI/Plater.cpp:3009 -#: src/slic3r/GUI/Plater.cpp:5581 src/slic3r/GUI/Tab.cpp:1575 -#: src/slic3r/GUI/Tab.cpp:4115 +#: src/slic3r/GUI/MainFrame.cpp:1405 src/slic3r/GUI/Plater.cpp:3023 +#: src/slic3r/GUI/Plater.cpp:5604 src/slic3r/GUI/Tab.cpp:1589 +#: src/slic3r/GUI/Tab.cpp:4133 msgid "Slicing" msgstr "" @@ -4893,7 +4923,7 @@ msgstr "" msgid "Your file was repaired." msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:1469 src/libslic3r/PrintConfig.cpp:3735 +#: src/slic3r/GUI/MainFrame.cpp:1469 src/libslic3r/PrintConfig.cpp:3816 msgid "Repair" msgstr "" @@ -4970,56 +5000,56 @@ msgstr "" msgid "See more." msgstr "" -#: src/slic3r/GUI/NotificationManager.hpp:476 +#: src/slic3r/GUI/NotificationManager.hpp:481 msgid "New version is available." msgstr "" -#: src/slic3r/GUI/NotificationManager.hpp:476 +#: src/slic3r/GUI/NotificationManager.hpp:481 msgid "See Releases page." msgstr "" -#: src/slic3r/GUI/NotificationManager.hpp:479 +#: src/slic3r/GUI/NotificationManager.hpp:484 msgid "" "You have just added a G-code for color change, but its value is empty.\n" "To export the G-code correctly, check the \"Color Change G-code\" in " "\"Printer Settings > Custom G-code\"" msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:490 -#: src/slic3r/GUI/NotificationManager.cpp:500 +#: src/slic3r/GUI/NotificationManager.cpp:493 +#: src/slic3r/GUI/NotificationManager.cpp:503 msgid "More" msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:864 -#: src/slic3r/GUI/NotificationManager.cpp:1141 +#: src/slic3r/GUI/NotificationManager.cpp:863 +#: src/slic3r/GUI/NotificationManager.cpp:1134 msgid "Export G-Code." msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:908 +#: src/slic3r/GUI/NotificationManager.cpp:904 msgid "Open Folder." msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:946 +#: src/slic3r/GUI/NotificationManager.cpp:940 msgid "Eject drive" msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:1060 -#: src/slic3r/GUI/NotificationManager.cpp:1076 -#: src/slic3r/GUI/NotificationManager.cpp:1087 +#: src/slic3r/GUI/NotificationManager.cpp:1053 +#: src/slic3r/GUI/NotificationManager.cpp:1069 +#: src/slic3r/GUI/NotificationManager.cpp:1080 msgid "ERROR:" msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:1065 -#: src/slic3r/GUI/NotificationManager.cpp:1080 -#: src/slic3r/GUI/NotificationManager.cpp:1095 +#: src/slic3r/GUI/NotificationManager.cpp:1058 +#: src/slic3r/GUI/NotificationManager.cpp:1073 +#: src/slic3r/GUI/NotificationManager.cpp:1088 msgid "WARNING:" msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:1144 +#: src/slic3r/GUI/NotificationManager.cpp:1137 msgid "Slicing finished." msgstr "" -#: src/slic3r/GUI/NotificationManager.cpp:1186 +#: src/slic3r/GUI/NotificationManager.cpp:1184 msgid "Exporting finished." msgstr "" @@ -5033,8 +5063,8 @@ msgstr "" msgid "Instance %d" msgstr "" -#: src/slic3r/GUI/ObjectDataViewModel.cpp:69 src/slic3r/GUI/Tab.cpp:3962 -#: src/slic3r/GUI/Tab.cpp:4044 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:69 src/slic3r/GUI/Tab.cpp:3980 +#: src/slic3r/GUI/Tab.cpp:4062 msgid "Layers" msgstr "" @@ -5074,12 +5104,12 @@ msgstr "" msgid "Error loading shaders" msgstr "" -#: src/slic3r/GUI/OptionsGroup.cpp:335 +#: src/slic3r/GUI/OptionsGroup.cpp:334 msgctxt "Layers" msgid "Top" msgstr "" -#: src/slic3r/GUI/OptionsGroup.cpp:335 +#: src/slic3r/GUI/OptionsGroup.cpp:334 msgctxt "Layers" msgid "Bottom" msgstr "" @@ -5108,7 +5138,7 @@ msgstr "" msgid "Add preset for this printer device" msgstr "" -#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:205 src/slic3r/GUI/Tab.cpp:2064 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:205 src/slic3r/GUI/Tab.cpp:2078 msgid "Print Host upload" msgstr "" @@ -5180,13 +5210,17 @@ msgstr "" msgid "Replace?" msgstr "" -#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:579 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:582 msgid "" -"Following printer preset(s) is duplicated:%1%The above preset for printer " +"Following printer preset is duplicated:%1%The above preset for printer \"%2%" +"\" will be used just once." +msgid_plural "" +"Following printer presets are duplicated:%1%The above presets for printer " "\"%2%\" will be used just once." -msgstr "" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:625 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:630 msgid "It's not possible to delete the last related preset for the printer." msgstr "" @@ -5210,15 +5244,15 @@ msgstr "" msgid "Sliced Info" msgstr "" -#: src/slic3r/GUI/Plater.cpp:237 src/slic3r/GUI/Plater.cpp:1151 +#: src/slic3r/GUI/Plater.cpp:237 src/slic3r/GUI/Plater.cpp:1159 msgid "Used Filament (m)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:238 src/slic3r/GUI/Plater.cpp:1163 +#: src/slic3r/GUI/Plater.cpp:238 src/slic3r/GUI/Plater.cpp:1171 msgid "Used Filament (mm³)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:239 src/slic3r/GUI/Plater.cpp:1170 +#: src/slic3r/GUI/Plater.cpp:239 src/slic3r/GUI/Plater.cpp:1178 msgid "Used Filament (g)" msgstr "" @@ -5238,8 +5272,8 @@ msgstr "" msgid "Select what kind of support do you need" msgstr "" -#: src/slic3r/GUI/Plater.cpp:362 src/libslic3r/PrintConfig.cpp:2128 -#: src/libslic3r/PrintConfig.cpp:2923 +#: src/slic3r/GUI/Plater.cpp:362 src/libslic3r/PrintConfig.cpp:2217 +#: src/libslic3r/PrintConfig.cpp:3012 msgid "Support on build plate only" msgstr "" @@ -5251,7 +5285,7 @@ msgstr "" msgid "Everywhere" msgstr "" -#: src/slic3r/GUI/Plater.cpp:396 src/slic3r/GUI/Tab.cpp:1469 +#: src/slic3r/GUI/Plater.cpp:396 src/slic3r/GUI/Tab.cpp:1481 msgid "Brim" msgstr "" @@ -5277,555 +5311,550 @@ msgstr "" msgid "Around object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:695 +#: src/slic3r/GUI/Plater.cpp:692 msgid "SLA print settings" msgstr "" -#: src/slic3r/GUI/Plater.cpp:756 src/slic3r/GUI/Plater.cpp:6055 +#: src/slic3r/GUI/Plater.cpp:753 src/slic3r/GUI/Plater.cpp:6082 msgid "Send to printer" msgstr "" -#: src/slic3r/GUI/Plater.cpp:771 src/slic3r/GUI/Plater.cpp:3009 -#: src/slic3r/GUI/Plater.cpp:5584 +#: src/slic3r/GUI/Plater.cpp:768 src/slic3r/GUI/Plater.cpp:3023 +#: src/slic3r/GUI/Plater.cpp:5607 msgid "Slice now" msgstr "" -#: src/slic3r/GUI/Plater.cpp:926 +#: src/slic3r/GUI/Plater.cpp:923 msgid "Hold Shift to Slice & Export G-code" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1071 -#, possible-c-format -msgid "%d (%d shells)" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:1068 +msgid "%1% (%2$d shell)" +msgid_plural "%1% (%2$d shells)" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/Plater.cpp:1076 -#, possible-c-format -msgid "Auto-repaired (%d errors)" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:1079 -#, possible-c-format -msgid "" -"%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d " -"facets reversed, %d backwards edges" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:1089 +#: src/slic3r/GUI/Plater.cpp:1097 msgid "Yes" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1110 +#: src/slic3r/GUI/Plater.cpp:1118 msgid "Used Material (ml)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1113 -msgid "object(s)" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:1121 +msgid "object" +msgid_plural "objects" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/Plater.cpp:1113 +#: src/slic3r/GUI/Plater.cpp:1121 msgid "supports and pad" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1151 +#: src/slic3r/GUI/Plater.cpp:1159 msgid "Used Filament (in)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1153 src/slic3r/GUI/Plater.cpp:1206 +#: src/slic3r/GUI/Plater.cpp:1161 src/slic3r/GUI/Plater.cpp:1214 msgid "objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1153 src/slic3r/GUI/Plater.cpp:1206 +#: src/slic3r/GUI/Plater.cpp:1161 src/slic3r/GUI/Plater.cpp:1214 msgid "wipe tower" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1163 +#: src/slic3r/GUI/Plater.cpp:1171 msgid "Used Filament (in³)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1189 +#: src/slic3r/GUI/Plater.cpp:1197 msgid "Filament at extruder %1%" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1195 +#: src/slic3r/GUI/Plater.cpp:1203 msgid "(including spool)" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1204 src/libslic3r/PrintConfig.cpp:822 -#: src/libslic3r/PrintConfig.cpp:2738 src/libslic3r/PrintConfig.cpp:2739 +#: src/slic3r/GUI/Plater.cpp:1212 src/libslic3r/PrintConfig.cpp:847 +#: src/libslic3r/PrintConfig.cpp:2827 src/libslic3r/PrintConfig.cpp:2828 msgid "Cost" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1222 +#: src/slic3r/GUI/Plater.cpp:1230 msgid "normal mode" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1232 +#: src/slic3r/GUI/Plater.cpp:1240 msgid "stealth mode" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1403 src/slic3r/GUI/Plater.cpp:4923 +#: src/slic3r/GUI/Plater.cpp:1411 src/slic3r/GUI/Plater.cpp:4942 #, possible-c-format msgid "%s - Drop project file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1410 src/slic3r/GUI/Plater.cpp:4930 +#: src/slic3r/GUI/Plater.cpp:1418 src/slic3r/GUI/Plater.cpp:4949 msgid "Open as project" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1411 src/slic3r/GUI/Plater.cpp:4931 +#: src/slic3r/GUI/Plater.cpp:1419 src/slic3r/GUI/Plater.cpp:4950 msgid "Import geometry only" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1412 src/slic3r/GUI/Plater.cpp:4932 +#: src/slic3r/GUI/Plater.cpp:1420 src/slic3r/GUI/Plater.cpp:4951 msgid "Import config only" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1415 src/slic3r/GUI/Plater.cpp:4935 +#: src/slic3r/GUI/Plater.cpp:1423 src/slic3r/GUI/Plater.cpp:4954 msgid "Select an action to apply to the file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1416 src/slic3r/GUI/Plater.cpp:4936 +#: src/slic3r/GUI/Plater.cpp:1424 src/slic3r/GUI/Plater.cpp:4955 msgid "Action" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1424 src/slic3r/GUI/Plater.cpp:4944 +#: src/slic3r/GUI/Plater.cpp:1432 src/slic3r/GUI/Plater.cpp:4963 msgid "Don't show again" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1469 src/slic3r/GUI/Plater.cpp:4981 +#: src/slic3r/GUI/Plater.cpp:1477 src/slic3r/GUI/Plater.cpp:5000 msgid "You can open only one .gcode file at a time." msgstr "" -#: src/slic3r/GUI/Plater.cpp:1470 src/slic3r/GUI/Plater.cpp:4982 +#: src/slic3r/GUI/Plater.cpp:1478 src/slic3r/GUI/Plater.cpp:5001 msgid "Drag and drop G-code file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1524 src/slic3r/GUI/Plater.cpp:4796 -#: src/slic3r/GUI/Plater.cpp:5036 +#: src/slic3r/GUI/Plater.cpp:1532 src/slic3r/GUI/Plater.cpp:4817 +#: src/slic3r/GUI/Plater.cpp:5055 msgid "Import Object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1546 src/slic3r/GUI/Plater.cpp:5058 +#: src/slic3r/GUI/Plater.cpp:1554 src/slic3r/GUI/Plater.cpp:5081 msgid "Load File" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1551 src/slic3r/GUI/Plater.cpp:5063 +#: src/slic3r/GUI/Plater.cpp:1559 src/slic3r/GUI/Plater.cpp:5086 msgid "Load Files" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1654 +#: src/slic3r/GUI/Plater.cpp:1662 msgid "Fill bed" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1660 +#: src/slic3r/GUI/Plater.cpp:1668 msgid "Optimize Rotation" msgstr "" -#: src/slic3r/GUI/Plater.cpp:1666 +#: src/slic3r/GUI/Plater.cpp:1674 msgid "Import SLA archive" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2129 +#: src/slic3r/GUI/Plater.cpp:2137 #, possible-c-format msgid "" "Successfully unmounted. The device %s(%s) can now be safely removed from the " "computer." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2134 +#: src/slic3r/GUI/Plater.cpp:2142 #, possible-c-format msgid "Ejecting of device %s(%s) has failed." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2153 +#: src/slic3r/GUI/Plater.cpp:2161 msgid "New Project" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2246 +#: src/slic3r/GUI/Plater.cpp:2254 msgid "Expand sidebar" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2319 +#: src/slic3r/GUI/Plater.cpp:2327 msgid "Loading" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2329 +#: src/slic3r/GUI/Plater.cpp:2337 msgid "Loading file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2415 +#: src/slic3r/GUI/Plater.cpp:2427 #, possible-c-format msgid "" -"Some object(s) in file %s looks like saved in inches.\n" +"The object in file %s looks like saved in inches.\n" +"Should I consider it as a saved in inches and convert it?" +msgid_plural "" +"Some objects in file %s look like saved in inches.\n" "Should I consider them as a saved in inches and convert them?" -msgstr "" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/Plater.cpp:2417 +#: src/slic3r/GUI/Plater.cpp:2431 msgid "The object appears to be saved in inches" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2425 +#: src/slic3r/GUI/Plater.cpp:2439 msgid "" "This file contains several objects positioned at multiple heights.\n" "Instead of considering them as multiple objects, should I consider\n" "this file as a single object having multiple parts?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2428 src/slic3r/GUI/Plater.cpp:2481 +#: src/slic3r/GUI/Plater.cpp:2442 src/slic3r/GUI/Plater.cpp:2495 msgid "Multi-part object detected" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2435 +#: src/slic3r/GUI/Plater.cpp:2449 msgid "" "This file cannot be loaded in a simple mode. Do you want to switch to an " "advanced mode?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2436 +#: src/slic3r/GUI/Plater.cpp:2450 msgid "Detected advanced data" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2458 +#: src/slic3r/GUI/Plater.cpp:2472 #, possible-c-format msgid "" "You can't to add the object(s) from %s because of one or some of them " "is(are) multi-part" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2478 +#: src/slic3r/GUI/Plater.cpp:2492 msgid "" "Multiple objects were loaded for a multi-material printer.\n" "Instead of considering them as multiple objects, should I consider\n" "these files to represent a single object having multiple parts?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2494 +#: src/slic3r/GUI/Plater.cpp:2508 msgid "Loaded" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2596 +#: src/slic3r/GUI/Plater.cpp:2610 msgid "" "Your object appears to be too large, so it was automatically scaled down to " "fit your print bed." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2597 +#: src/slic3r/GUI/Plater.cpp:2611 msgid "Object too large?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2659 +#: src/slic3r/GUI/Plater.cpp:2673 msgid "Export STL file:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2666 +#: src/slic3r/GUI/Plater.cpp:2680 msgid "Export AMF file:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2672 +#: src/slic3r/GUI/Plater.cpp:2686 msgid "Save file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2678 +#: src/slic3r/GUI/Plater.cpp:2692 msgid "Export OBJ file:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2774 +#: src/slic3r/GUI/Plater.cpp:2788 msgid "Delete Object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2785 +#: src/slic3r/GUI/Plater.cpp:2799 msgid "Reset Project" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2857 +#: src/slic3r/GUI/Plater.cpp:2871 msgid "" "The selected object can't be split because it contains more than one volume/" "material." msgstr "" -#: src/slic3r/GUI/Plater.cpp:2868 +#: src/slic3r/GUI/Plater.cpp:2882 msgid "Split to Objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:2993 src/slic3r/GUI/Plater.cpp:3723 +#: src/slic3r/GUI/Plater.cpp:3007 src/slic3r/GUI/Plater.cpp:3744 msgid "Invalid data" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3003 +#: src/slic3r/GUI/Plater.cpp:3017 msgid "Ready to slice" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3041 src/slic3r/GUI/PrintHostDialogs.cpp:264 +#: src/slic3r/GUI/Plater.cpp:3055 src/slic3r/GUI/PrintHostDialogs.cpp:275 msgid "Cancelling" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3060 +#: src/slic3r/GUI/Plater.cpp:3074 msgid "Another export job is currently running." msgstr "" -#: src/slic3r/GUI/Plater.cpp:3177 +#: src/slic3r/GUI/Plater.cpp:3191 msgid "Please select the file to reload" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3212 +#: src/slic3r/GUI/Plater.cpp:3226 msgid "It is not allowed to change the file to reload" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3212 +#: src/slic3r/GUI/Plater.cpp:3226 msgid "Do you want to retry" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3230 +#: src/slic3r/GUI/Plater.cpp:3244 msgid "Reload from:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3323 +#: src/slic3r/GUI/Plater.cpp:3337 msgid "Unable to reload:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3328 +#: src/slic3r/GUI/Plater.cpp:3342 msgid "Error during reload" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3347 +#: src/slic3r/GUI/Plater.cpp:3361 msgid "Reload all from disk" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3374 +#: src/slic3r/GUI/Plater.cpp:3388 msgid "" "ERROR: Please close all manipulators available from the left toolbar before " "fixing the mesh." msgstr "" -#: src/slic3r/GUI/Plater.cpp:3380 +#: src/slic3r/GUI/Plater.cpp:3394 msgid "Fix through NetFabb" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3397 +#: src/slic3r/GUI/Plater.cpp:3411 msgid "Custom supports and seams were removed after repairing the mesh." msgstr "" -#: src/slic3r/GUI/Plater.cpp:3680 +#: src/slic3r/GUI/Plater.cpp:3702 msgid "There are active warnings concerning sliced models:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3691 +#: src/slic3r/GUI/Plater.cpp:3712 msgid "generated warnings" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3731 src/slic3r/GUI/PrintHostDialogs.cpp:265 +#: src/slic3r/GUI/Plater.cpp:3752 src/slic3r/GUI/PrintHostDialogs.cpp:276 msgid "Cancelled" msgstr "" -#: src/slic3r/GUI/Plater.cpp:3998 src/slic3r/GUI/Plater.cpp:4022 +#: src/slic3r/GUI/Plater.cpp:4019 src/slic3r/GUI/Plater.cpp:4043 msgid "Remove the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4007 +#: src/slic3r/GUI/Plater.cpp:4028 msgid "Add one more instance of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4009 +#: src/slic3r/GUI/Plater.cpp:4030 msgid "Remove one instance of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4011 +#: src/slic3r/GUI/Plater.cpp:4032 msgid "Set number of instances" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4011 +#: src/slic3r/GUI/Plater.cpp:4032 msgid "Change the number of instances of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4013 +#: src/slic3r/GUI/Plater.cpp:4034 msgid "Fill bed with instances" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4013 +#: src/slic3r/GUI/Plater.cpp:4034 msgid "Fill the remaining area of bed with instances of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4032 +#: src/slic3r/GUI/Plater.cpp:4053 msgid "Reload the selected object from disk" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4035 +#: src/slic3r/GUI/Plater.cpp:4056 msgid "Export the selected object as STL file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4065 +#: src/slic3r/GUI/Plater.cpp:4086 msgid "Along X axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4065 +#: src/slic3r/GUI/Plater.cpp:4086 msgid "Mirror the selected object along the X axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4067 +#: src/slic3r/GUI/Plater.cpp:4088 msgid "Along Y axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4067 +#: src/slic3r/GUI/Plater.cpp:4088 msgid "Mirror the selected object along the Y axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4069 +#: src/slic3r/GUI/Plater.cpp:4090 msgid "Along Z axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4069 +#: src/slic3r/GUI/Plater.cpp:4090 msgid "Mirror the selected object along the Z axis" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4072 +#: src/slic3r/GUI/Plater.cpp:4093 msgid "Mirror" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4072 +#: src/slic3r/GUI/Plater.cpp:4093 msgid "Mirror the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4084 +#: src/slic3r/GUI/Plater.cpp:4105 msgid "To objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4084 src/slic3r/GUI/Plater.cpp:4104 +#: src/slic3r/GUI/Plater.cpp:4105 src/slic3r/GUI/Plater.cpp:4125 msgid "Split the selected object into individual objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4086 +#: src/slic3r/GUI/Plater.cpp:4107 msgid "To parts" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4086 src/slic3r/GUI/Plater.cpp:4122 +#: src/slic3r/GUI/Plater.cpp:4107 src/slic3r/GUI/Plater.cpp:4143 msgid "Split the selected object into individual sub-parts" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4089 src/slic3r/GUI/Plater.cpp:4104 -#: src/slic3r/GUI/Plater.cpp:4122 src/libslic3r/PrintConfig.cpp:3759 +#: src/slic3r/GUI/Plater.cpp:4110 src/slic3r/GUI/Plater.cpp:4125 +#: src/slic3r/GUI/Plater.cpp:4143 src/libslic3r/PrintConfig.cpp:3840 msgid "Split" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4089 +#: src/slic3r/GUI/Plater.cpp:4110 msgid "Split the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4111 +#: src/slic3r/GUI/Plater.cpp:4132 msgid "Optimize orientation" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4112 +#: src/slic3r/GUI/Plater.cpp:4133 msgid "Optimize the rotation of the object for better print results." msgstr "" -#: src/slic3r/GUI/Plater.cpp:4192 +#: src/slic3r/GUI/Plater.cpp:4213 msgid "3D editor view" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4564 +#: src/slic3r/GUI/Plater.cpp:4585 msgid "" "%1% printer was active at the time the target Undo / Redo snapshot was " "taken. Switching to %1% printer requires reloading of %1% presets." msgstr "" -#: src/slic3r/GUI/Plater.cpp:4768 +#: src/slic3r/GUI/Plater.cpp:4789 msgid "Load Project" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4800 +#: src/slic3r/GUI/Plater.cpp:4821 msgid "Import Objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4868 +#: src/slic3r/GUI/Plater.cpp:4887 msgid "The selected file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:4868 +#: src/slic3r/GUI/Plater.cpp:4887 msgid "does not contain valid gcode." msgstr "" -#: src/slic3r/GUI/Plater.cpp:4869 +#: src/slic3r/GUI/Plater.cpp:4888 msgid "Error while loading .gcode file" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5107 +#: src/slic3r/GUI/Plater.cpp:5130 msgid "All objects will be removed, continue?" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5115 +#: src/slic3r/GUI/Plater.cpp:5138 msgid "Delete Selected Objects" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5123 +#: src/slic3r/GUI/Plater.cpp:5146 msgid "Increase Instances" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5157 +#: src/slic3r/GUI/Plater.cpp:5180 msgid "Decrease Instances" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5188 +#: src/slic3r/GUI/Plater.cpp:5211 msgid "Enter the number of copies:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5189 +#: src/slic3r/GUI/Plater.cpp:5212 msgid "Copies of the selected object" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5193 +#: src/slic3r/GUI/Plater.cpp:5216 #, possible-c-format msgid "Set numbers of copies to %d" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5259 +#: src/slic3r/GUI/Plater.cpp:5282 msgid "Cut by Plane" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5316 +#: src/slic3r/GUI/Plater.cpp:5339 msgid "Save G-code file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5316 +#: src/slic3r/GUI/Plater.cpp:5339 msgid "Save SL1 file as:" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5463 +#: src/slic3r/GUI/Plater.cpp:5486 #, possible-c-format msgid "STL file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5480 +#: src/slic3r/GUI/Plater.cpp:5503 #, possible-c-format msgid "AMF file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5483 +#: src/slic3r/GUI/Plater.cpp:5506 #, possible-c-format msgid "Error exporting AMF file %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5512 +#: src/slic3r/GUI/Plater.cpp:5535 #, possible-c-format msgid "3MF file exported to %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:5517 +#: src/slic3r/GUI/Plater.cpp:5540 #, possible-c-format msgid "Error exporting 3MF file %s" msgstr "" -#: src/slic3r/GUI/Plater.cpp:6054 +#: src/slic3r/GUI/Plater.cpp:6081 msgid "Export" msgstr "" -#: src/slic3r/GUI/Plater.cpp:6149 +#: src/slic3r/GUI/Plater.cpp:6178 msgid "Paste From Clipboard" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:56 src/slic3r/GUI/Tab.cpp:2098 -#: src/slic3r/GUI/Tab.cpp:2285 src/slic3r/GUI/Tab.cpp:2393 -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1080 +#: src/slic3r/GUI/Preferences.cpp:56 src/slic3r/GUI/Tab.cpp:2112 +#: src/slic3r/GUI/Tab.cpp:2299 src/slic3r/GUI/Tab.cpp:2407 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1082 msgid "General" msgstr "" @@ -6067,115 +6096,119 @@ msgstr "" msgid "If enabled, you can change size of toolbar icons manually." msgstr "" -#: src/slic3r/GUI/Preferences.cpp:320 +#: src/slic3r/GUI/Preferences.cpp:321 msgid "Render" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:325 +#: src/slic3r/GUI/Preferences.cpp:326 msgid "Use environment map" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:327 +#: src/slic3r/GUI/Preferences.cpp:328 msgid "If enabled, renders object using the environment map." msgstr "" -#: src/slic3r/GUI/Preferences.cpp:352 +#: src/slic3r/GUI/Preferences.cpp:353 #, possible-c-format msgid "You need to restart %s to make the changes effective." msgstr "" -#: src/slic3r/GUI/Preferences.cpp:427 +#: src/slic3r/GUI/Preferences.cpp:432 msgid "Icon size in a respect to the default size" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:442 +#: src/slic3r/GUI/Preferences.cpp:447 msgid "Select toolbar icon size in respect to the default one." msgstr "" -#: src/slic3r/GUI/Preferences.cpp:473 +#: src/slic3r/GUI/Preferences.cpp:478 msgid "Old regular layout with the tab bar" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:474 +#: src/slic3r/GUI/Preferences.cpp:479 msgid "New layout, access via settings button in the top menu" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:475 +#: src/slic3r/GUI/Preferences.cpp:480 msgid "Settings in non-modal window" msgstr "" -#: src/slic3r/GUI/Preferences.cpp:484 +#: src/slic3r/GUI/Preferences.cpp:489 msgid "Layout Options" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:197 -#: src/slic3r/GUI/PresetComboBoxes.cpp:235 -#: src/slic3r/GUI/PresetComboBoxes.cpp:761 -#: src/slic3r/GUI/PresetComboBoxes.cpp:811 -#: src/slic3r/GUI/PresetComboBoxes.cpp:925 -#: src/slic3r/GUI/PresetComboBoxes.cpp:969 +#: src/slic3r/GUI/Preferences.cpp:510 +msgid "Text color Settings" +msgstr "" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:224 +#: src/slic3r/GUI/PresetComboBoxes.cpp:262 +#: src/slic3r/GUI/PresetComboBoxes.cpp:788 +#: src/slic3r/GUI/PresetComboBoxes.cpp:838 +#: src/slic3r/GUI/PresetComboBoxes.cpp:963 +#: src/slic3r/GUI/PresetComboBoxes.cpp:1007 msgid "System presets" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:239 -#: src/slic3r/GUI/PresetComboBoxes.cpp:815 -#: src/slic3r/GUI/PresetComboBoxes.cpp:973 +#: src/slic3r/GUI/PresetComboBoxes.cpp:266 +#: src/slic3r/GUI/PresetComboBoxes.cpp:842 +#: src/slic3r/GUI/PresetComboBoxes.cpp:1011 msgid "User presets" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:250 +#: src/slic3r/GUI/PresetComboBoxes.cpp:277 msgid "Incompatible presets" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:285 +#: src/slic3r/GUI/PresetComboBoxes.cpp:312 msgid "Are you sure you want to delete \"%1%\" printer?" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:287 +#: src/slic3r/GUI/PresetComboBoxes.cpp:314 msgid "Delete Physical Printer" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:624 +#: src/slic3r/GUI/PresetComboBoxes.cpp:651 msgid "Click to edit preset" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:680 -#: src/slic3r/GUI/PresetComboBoxes.cpp:710 +#: src/slic3r/GUI/PresetComboBoxes.cpp:707 +#: src/slic3r/GUI/PresetComboBoxes.cpp:737 msgid "Add/Remove presets" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:685 -#: src/slic3r/GUI/PresetComboBoxes.cpp:715 src/slic3r/GUI/Tab.cpp:2990 +#: src/slic3r/GUI/PresetComboBoxes.cpp:712 +#: src/slic3r/GUI/PresetComboBoxes.cpp:742 src/slic3r/GUI/Tab.cpp:3004 msgid "Add physical printer" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:699 +#: src/slic3r/GUI/PresetComboBoxes.cpp:726 msgid "Edit preset" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:703 src/slic3r/GUI/Tab.cpp:2990 +#: src/slic3r/GUI/PresetComboBoxes.cpp:730 src/slic3r/GUI/Tab.cpp:3004 msgid "Edit physical printer" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:706 +#: src/slic3r/GUI/PresetComboBoxes.cpp:733 msgid "Delete physical printer" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:826 -#: src/slic3r/GUI/PresetComboBoxes.cpp:987 +#: src/slic3r/GUI/PresetComboBoxes.cpp:853 +#: src/slic3r/GUI/PresetComboBoxes.cpp:1025 msgid "Physical printers" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:850 +#: src/slic3r/GUI/PresetComboBoxes.cpp:877 msgid "Add/Remove filaments" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:852 +#: src/slic3r/GUI/PresetComboBoxes.cpp:879 msgid "Add/Remove materials" msgstr "" -#: src/slic3r/GUI/PresetComboBoxes.cpp:854 -#: src/slic3r/GUI/PresetComboBoxes.cpp:1011 +#: src/slic3r/GUI/PresetComboBoxes.cpp:881 +#: src/slic3r/GUI/PresetComboBoxes.cpp:1049 msgid "Add/Remove printers" msgstr "" @@ -6352,52 +6385,52 @@ msgstr "" msgid "Group" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:176 +#: src/slic3r/GUI/PrintHostDialogs.cpp:187 msgid "ID" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:177 +#: src/slic3r/GUI/PrintHostDialogs.cpp:188 msgid "Progress" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:178 +#: src/slic3r/GUI/PrintHostDialogs.cpp:189 msgid "Status" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:179 +#: src/slic3r/GUI/PrintHostDialogs.cpp:190 msgid "Host" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:180 +#: src/slic3r/GUI/PrintHostDialogs.cpp:191 msgid "Filename" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:181 +#: src/slic3r/GUI/PrintHostDialogs.cpp:192 msgid "Error Message" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:184 +#: src/slic3r/GUI/PrintHostDialogs.cpp:195 msgid "Cancel selected" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:186 +#: src/slic3r/GUI/PrintHostDialogs.cpp:197 msgid "Show error message" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:228 -#: src/slic3r/GUI/PrintHostDialogs.cpp:261 +#: src/slic3r/GUI/PrintHostDialogs.cpp:239 +#: src/slic3r/GUI/PrintHostDialogs.cpp:272 msgid "Enqueued" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:262 +#: src/slic3r/GUI/PrintHostDialogs.cpp:273 msgid "Uploading" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:266 +#: src/slic3r/GUI/PrintHostDialogs.cpp:277 msgid "Completed" msgstr "" -#: src/slic3r/GUI/PrintHostDialogs.cpp:304 +#: src/slic3r/GUI/PrintHostDialogs.cpp:315 msgid "Error uploading to print host:" msgstr "" @@ -6406,12 +6439,12 @@ msgid "NO RAMMING AT ALL" msgstr "" #: src/slic3r/GUI/RammingChart.cpp:76 src/slic3r/GUI/WipeTowerDialog.cpp:83 -#: src/libslic3r/PrintConfig.cpp:706 src/libslic3r/PrintConfig.cpp:750 -#: src/libslic3r/PrintConfig.cpp:765 src/libslic3r/PrintConfig.cpp:2636 -#: src/libslic3r/PrintConfig.cpp:2645 src/libslic3r/PrintConfig.cpp:2755 -#: src/libslic3r/PrintConfig.cpp:2763 src/libslic3r/PrintConfig.cpp:2771 -#: src/libslic3r/PrintConfig.cpp:2778 src/libslic3r/PrintConfig.cpp:2786 -#: src/libslic3r/PrintConfig.cpp:2794 +#: src/libslic3r/PrintConfig.cpp:731 src/libslic3r/PrintConfig.cpp:775 +#: src/libslic3r/PrintConfig.cpp:790 src/libslic3r/PrintConfig.cpp:2725 +#: src/libslic3r/PrintConfig.cpp:2734 src/libslic3r/PrintConfig.cpp:2844 +#: src/libslic3r/PrintConfig.cpp:2852 src/libslic3r/PrintConfig.cpp:2860 +#: src/libslic3r/PrintConfig.cpp:2867 src/libslic3r/PrintConfig.cpp:2875 +#: src/libslic3r/PrintConfig.cpp:2883 msgid "s" msgstr "" @@ -6419,8 +6452,8 @@ msgstr "" msgid "Volumetric speed" msgstr "" -#: src/slic3r/GUI/RammingChart.cpp:81 src/libslic3r/PrintConfig.cpp:663 -#: src/libslic3r/PrintConfig.cpp:1458 +#: src/slic3r/GUI/RammingChart.cpp:81 src/libslic3r/PrintConfig.cpp:688 +#: src/libslic3r/PrintConfig.cpp:1547 msgid "mm³/s" msgstr "" @@ -6471,43 +6504,47 @@ msgstr "" msgid "The name cannot end with space character." msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:186 -#: src/slic3r/GUI/SavePresetDialog.cpp:192 +#: src/slic3r/GUI/SavePresetDialog.cpp:157 +msgid "The name cannot be the same as a preset alias name." +msgstr "" + +#: src/slic3r/GUI/SavePresetDialog.cpp:191 +#: src/slic3r/GUI/SavePresetDialog.cpp:197 msgid "Save preset" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:215 +#: src/slic3r/GUI/SavePresetDialog.cpp:220 msgctxt "PresetName" msgid "Copy" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:273 +#: src/slic3r/GUI/SavePresetDialog.cpp:278 msgid "" "You have selected physical printer \"%1%\" \n" "with related printer preset \"%2%\"" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:306 +#: src/slic3r/GUI/SavePresetDialog.cpp:311 msgid "What would you like to do with \"%1%\" preset after saving?" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:309 +#: src/slic3r/GUI/SavePresetDialog.cpp:314 msgid "Change \"%1%\" to \"%2%\" for this physical printer \"%3%\"" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:310 +#: src/slic3r/GUI/SavePresetDialog.cpp:315 msgid "Add \"%1%\" as a next preset for the the physical printer \"%2%\"" msgstr "" -#: src/slic3r/GUI/SavePresetDialog.cpp:311 +#: src/slic3r/GUI/SavePresetDialog.cpp:316 msgid "Just switch to \"%1%\" preset" msgstr "" -#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2421 +#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2435 msgid "Stealth" msgstr "" -#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2415 +#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2429 msgid "Normal" msgstr "" @@ -6555,15 +6592,15 @@ msgstr "" msgid "Set Unprintable Instance" msgstr "" -#: src/slic3r/GUI/SysInfoDialog.cpp:82 +#: src/slic3r/GUI/SysInfoDialog.cpp:83 msgid "System Information" msgstr "" -#: src/slic3r/GUI/SysInfoDialog.cpp:158 +#: src/slic3r/GUI/SysInfoDialog.cpp:164 msgid "Copy to Clipboard" msgstr "" -#: src/slic3r/GUI/Tab.cpp:109 src/libslic3r/PrintConfig.cpp:321 +#: src/slic3r/GUI/Tab.cpp:109 src/libslic3r/PrintConfig.cpp:346 msgid "Compatible printers" msgstr "" @@ -6571,7 +6608,7 @@ msgstr "" msgid "Select the printers this profile is compatible with." msgstr "" -#: src/slic3r/GUI/Tab.cpp:115 src/libslic3r/PrintConfig.cpp:336 +#: src/slic3r/GUI/Tab.cpp:115 src/libslic3r/PrintConfig.cpp:361 msgid "Compatible print profiles" msgstr "" @@ -6689,7 +6726,7 @@ msgstr "" msgid "symbolic profile name" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1385 src/slic3r/GUI/Tab.cpp:4042 +#: src/slic3r/GUI/Tab.cpp:1385 src/slic3r/GUI/Tab.cpp:4060 msgid "Layers and perimeters" msgstr "" @@ -6701,7 +6738,7 @@ msgstr "" msgid "Horizontal shells" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1404 src/libslic3r/PrintConfig.cpp:1980 +#: src/slic3r/GUI/Tab.cpp:1404 src/libslic3r/PrintConfig.cpp:2069 msgid "Solid layers" msgstr "" @@ -6713,179 +6750,179 @@ msgstr "" msgid "Quality (slower slicing)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1448 -msgid "Reducing printing time" +#: src/slic3r/GUI/Tab.cpp:1432 +msgid "Fuzzy skin (experimental)" msgstr "" #: src/slic3r/GUI/Tab.cpp:1460 -msgid "Skirt and brim" +msgid "Reducing printing time" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1480 +#: src/slic3r/GUI/Tab.cpp:1494 msgid "Raft" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1484 +#: src/slic3r/GUI/Tab.cpp:1498 msgid "Options for support material and raft" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1499 +#: src/slic3r/GUI/Tab.cpp:1513 msgid "Speed for print moves" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1512 +#: src/slic3r/GUI/Tab.cpp:1526 msgid "Speed for non-print moves" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1515 +#: src/slic3r/GUI/Tab.cpp:1529 msgid "Modifiers" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1518 +#: src/slic3r/GUI/Tab.cpp:1532 msgid "Acceleration control (advanced)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1525 +#: src/slic3r/GUI/Tab.cpp:1539 msgid "Autospeed (advanced)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1533 +#: src/slic3r/GUI/Tab.cpp:1547 msgid "Multiple Extruders" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1541 +#: src/slic3r/GUI/Tab.cpp:1555 msgid "Ooze prevention" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1559 +#: src/slic3r/GUI/Tab.cpp:1573 msgid "Extrusion width" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1569 +#: src/slic3r/GUI/Tab.cpp:1583 msgid "Overlap" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1572 +#: src/slic3r/GUI/Tab.cpp:1586 msgid "Flow" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1581 +#: src/slic3r/GUI/Tab.cpp:1595 msgid "Other" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1584 src/slic3r/GUI/Tab.cpp:4118 +#: src/slic3r/GUI/Tab.cpp:1598 src/slic3r/GUI/Tab.cpp:4136 msgid "Output options" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1585 +#: src/slic3r/GUI/Tab.cpp:1599 msgid "Sequential printing" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1587 +#: src/slic3r/GUI/Tab.cpp:1601 msgid "Extruder clearance" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1592 src/slic3r/GUI/Tab.cpp:4119 +#: src/slic3r/GUI/Tab.cpp:1606 src/slic3r/GUI/Tab.cpp:4137 msgid "Output file" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1599 src/libslic3r/PrintConfig.cpp:1662 +#: src/slic3r/GUI/Tab.cpp:1613 src/libslic3r/PrintConfig.cpp:1751 msgid "Post-processing scripts" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1605 src/slic3r/GUI/Tab.cpp:1606 -#: src/slic3r/GUI/Tab.cpp:1927 src/slic3r/GUI/Tab.cpp:1928 -#: src/slic3r/GUI/Tab.cpp:2266 src/slic3r/GUI/Tab.cpp:2267 -#: src/slic3r/GUI/Tab.cpp:2342 src/slic3r/GUI/Tab.cpp:2343 -#: src/slic3r/GUI/Tab.cpp:3985 src/slic3r/GUI/Tab.cpp:3986 +#: src/slic3r/GUI/Tab.cpp:1619 src/slic3r/GUI/Tab.cpp:1620 +#: src/slic3r/GUI/Tab.cpp:1941 src/slic3r/GUI/Tab.cpp:1942 +#: src/slic3r/GUI/Tab.cpp:2280 src/slic3r/GUI/Tab.cpp:2281 +#: src/slic3r/GUI/Tab.cpp:2356 src/slic3r/GUI/Tab.cpp:2357 +#: src/slic3r/GUI/Tab.cpp:4003 src/slic3r/GUI/Tab.cpp:4004 msgid "Notes" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1612 src/slic3r/GUI/Tab.cpp:1935 -#: src/slic3r/GUI/Tab.cpp:2273 src/slic3r/GUI/Tab.cpp:2349 -#: src/slic3r/GUI/Tab.cpp:3993 src/slic3r/GUI/Tab.cpp:4124 +#: src/slic3r/GUI/Tab.cpp:1626 src/slic3r/GUI/Tab.cpp:1949 +#: src/slic3r/GUI/Tab.cpp:2287 src/slic3r/GUI/Tab.cpp:2363 +#: src/slic3r/GUI/Tab.cpp:4011 src/slic3r/GUI/Tab.cpp:4142 msgid "Dependencies" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1613 src/slic3r/GUI/Tab.cpp:1936 -#: src/slic3r/GUI/Tab.cpp:2274 src/slic3r/GUI/Tab.cpp:2350 -#: src/slic3r/GUI/Tab.cpp:3994 src/slic3r/GUI/Tab.cpp:4125 +#: src/slic3r/GUI/Tab.cpp:1627 src/slic3r/GUI/Tab.cpp:1950 +#: src/slic3r/GUI/Tab.cpp:2288 src/slic3r/GUI/Tab.cpp:2364 +#: src/slic3r/GUI/Tab.cpp:4012 src/slic3r/GUI/Tab.cpp:4143 msgid "Profile dependencies" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1693 +#: src/slic3r/GUI/Tab.cpp:1707 msgid "Filament Overrides" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1815 +#: src/slic3r/GUI/Tab.cpp:1829 msgid "Temperature" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1816 +#: src/slic3r/GUI/Tab.cpp:1830 msgid "Nozzle" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1821 +#: src/slic3r/GUI/Tab.cpp:1835 msgid "Bed" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1826 +#: src/slic3r/GUI/Tab.cpp:1840 msgid "Cooling" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1828 src/libslic3r/PrintConfig.cpp:1565 -#: src/libslic3r/PrintConfig.cpp:2428 +#: src/slic3r/GUI/Tab.cpp:1842 src/libslic3r/PrintConfig.cpp:1654 +#: src/libslic3r/PrintConfig.cpp:2517 msgid "Enable" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1839 +#: src/slic3r/GUI/Tab.cpp:1853 msgid "Fan settings" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1850 +#: src/slic3r/GUI/Tab.cpp:1864 msgid "Cooling thresholds" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1856 +#: src/slic3r/GUI/Tab.cpp:1870 msgid "Filament properties" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1863 +#: src/slic3r/GUI/Tab.cpp:1877 msgid "Print speed override" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1873 +#: src/slic3r/GUI/Tab.cpp:1887 msgid "Wipe tower parameters" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1876 +#: src/slic3r/GUI/Tab.cpp:1890 msgid "Toolchange parameters with single extruder MM printers" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1889 +#: src/slic3r/GUI/Tab.cpp:1903 msgid "Ramming settings" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1912 src/slic3r/GUI/Tab.cpp:2205 -#: src/libslic3r/PrintConfig.cpp:2063 +#: src/slic3r/GUI/Tab.cpp:1926 src/slic3r/GUI/Tab.cpp:2219 +#: src/libslic3r/PrintConfig.cpp:2152 msgid "Custom G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1913 src/slic3r/GUI/Tab.cpp:2206 -#: src/libslic3r/PrintConfig.cpp:2013 src/libslic3r/PrintConfig.cpp:2028 +#: src/slic3r/GUI/Tab.cpp:1927 src/slic3r/GUI/Tab.cpp:2220 +#: src/libslic3r/PrintConfig.cpp:2102 src/libslic3r/PrintConfig.cpp:2117 msgid "Start G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1920 src/slic3r/GUI/Tab.cpp:2213 -#: src/libslic3r/PrintConfig.cpp:441 src/libslic3r/PrintConfig.cpp:451 +#: src/slic3r/GUI/Tab.cpp:1934 src/slic3r/GUI/Tab.cpp:2227 +#: src/libslic3r/PrintConfig.cpp:466 src/libslic3r/PrintConfig.cpp:476 msgid "End G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:1970 +#: src/slic3r/GUI/Tab.cpp:1984 msgid "Volumetric flow hints not available" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2066 +#: src/slic3r/GUI/Tab.cpp:2080 msgid "" "Note: All parameters from this group are moved to the Physical Printer " "settings (see changelog).\n" @@ -6898,19 +6935,19 @@ msgid "" "physical_printer directory." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2099 src/slic3r/GUI/Tab.cpp:2286 +#: src/slic3r/GUI/Tab.cpp:2113 src/slic3r/GUI/Tab.cpp:2300 msgid "Size and coordinates" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2108 src/slic3r/GUI/UnsavedChangesDialog.cpp:1080 +#: src/slic3r/GUI/Tab.cpp:2122 src/slic3r/GUI/UnsavedChangesDialog.cpp:1082 msgid "Capabilities" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2113 +#: src/slic3r/GUI/Tab.cpp:2127 msgid "Number of extruders of the printer." msgstr "" -#: src/slic3r/GUI/Tab.cpp:2141 +#: src/slic3r/GUI/Tab.cpp:2155 msgid "" "Single Extruder Multi Material is selected, \n" "and all extruders must have the same diameter.\n" @@ -6918,231 +6955,243 @@ msgid "" "nozzle diameter value?" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2144 src/slic3r/GUI/Tab.cpp:2552 -#: src/libslic3r/PrintConfig.cpp:1534 +#: src/slic3r/GUI/Tab.cpp:2158 src/slic3r/GUI/Tab.cpp:2566 +#: src/libslic3r/PrintConfig.cpp:1623 msgid "Nozzle diameter" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2220 src/libslic3r/PrintConfig.cpp:209 +#: src/slic3r/GUI/Tab.cpp:2234 src/libslic3r/PrintConfig.cpp:209 msgid "Before layer change G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2227 src/libslic3r/PrintConfig.cpp:1273 +#: src/slic3r/GUI/Tab.cpp:2241 src/libslic3r/PrintConfig.cpp:1362 msgid "After layer change G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2234 src/libslic3r/PrintConfig.cpp:2321 +#: src/slic3r/GUI/Tab.cpp:2248 src/libslic3r/PrintConfig.cpp:2410 msgid "Tool change G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2241 +#: src/slic3r/GUI/Tab.cpp:2255 msgid "Between objects G-code (for sequential printing)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2248 +#: src/slic3r/GUI/Tab.cpp:2262 msgid "Color Change G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2254 src/libslic3r/PrintConfig.cpp:2054 +#: src/slic3r/GUI/Tab.cpp:2268 src/libslic3r/PrintConfig.cpp:2143 msgid "Pause Print G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2260 +#: src/slic3r/GUI/Tab.cpp:2274 msgid "Template Custom G-code" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2293 +#: src/slic3r/GUI/Tab.cpp:2307 msgid "Display" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2308 +#: src/slic3r/GUI/Tab.cpp:2322 msgid "Tilt" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2309 +#: src/slic3r/GUI/Tab.cpp:2323 msgid "Tilt time" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2315 src/slic3r/GUI/Tab.cpp:3969 +#: src/slic3r/GUI/Tab.cpp:2329 src/slic3r/GUI/Tab.cpp:3987 msgid "Corrections" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2332 src/slic3r/GUI/Tab.cpp:3965 +#: src/slic3r/GUI/Tab.cpp:2346 src/slic3r/GUI/Tab.cpp:3983 msgid "Exposure" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2391 src/slic3r/GUI/Tab.cpp:2485 -#: src/libslic3r/PrintConfig.cpp:1302 src/libslic3r/PrintConfig.cpp:1337 -#: src/libslic3r/PrintConfig.cpp:1354 src/libslic3r/PrintConfig.cpp:1371 -#: src/libslic3r/PrintConfig.cpp:1387 src/libslic3r/PrintConfig.cpp:1397 -#: src/libslic3r/PrintConfig.cpp:1407 src/libslic3r/PrintConfig.cpp:1417 +#: src/slic3r/GUI/Tab.cpp:2405 src/slic3r/GUI/Tab.cpp:2499 +#: src/libslic3r/PrintConfig.cpp:1391 src/libslic3r/PrintConfig.cpp:1426 +#: src/libslic3r/PrintConfig.cpp:1443 src/libslic3r/PrintConfig.cpp:1460 +#: src/libslic3r/PrintConfig.cpp:1476 src/libslic3r/PrintConfig.cpp:1486 +#: src/libslic3r/PrintConfig.cpp:1496 src/libslic3r/PrintConfig.cpp:1506 msgid "Machine limits" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2414 +#: src/slic3r/GUI/Tab.cpp:2428 msgid "Values in this column are for Normal mode" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2420 +#: src/slic3r/GUI/Tab.cpp:2434 msgid "Values in this column are for Stealth mode" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2429 +#: src/slic3r/GUI/Tab.cpp:2443 msgid "Maximum feedrates" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2434 +#: src/slic3r/GUI/Tab.cpp:2448 msgid "Maximum accelerations" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2441 +#: src/slic3r/GUI/Tab.cpp:2455 msgid "Jerk limits" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2446 +#: src/slic3r/GUI/Tab.cpp:2460 msgid "Minimum feedrates" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2510 src/slic3r/GUI/Tab.cpp:2518 +#: src/slic3r/GUI/Tab.cpp:2524 src/slic3r/GUI/Tab.cpp:2532 msgid "Single extruder MM setup" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2519 +#: src/slic3r/GUI/Tab.cpp:2533 msgid "Single extruder multimaterial parameters" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2550 +#: src/slic3r/GUI/Tab.cpp:2564 msgid "" "This is a single extruder multimaterial printer, diameters of all extruders " "will be set to the new value. Do you want to proceed?" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2574 +#: src/slic3r/GUI/Tab.cpp:2588 msgid "Layer height limits" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2579 +#: src/slic3r/GUI/Tab.cpp:2593 msgid "Position (for multi-extruder printers)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2585 +#: src/slic3r/GUI/Tab.cpp:2599 msgid "Only lift Z" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2598 +#: src/slic3r/GUI/Tab.cpp:2612 msgid "" "Retraction when tool is disabled (advanced settings for multi-extruder " "setups)" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2605 +#: src/slic3r/GUI/Tab.cpp:2619 msgid "Reset to Filament Color" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2783 +#: src/slic3r/GUI/Tab.cpp:2797 msgid "" "The Wipe option is not available when using the Firmware Retraction mode.\n" "\n" "Shall I disable it in order to enable Firmware Retraction?" msgstr "" -#: src/slic3r/GUI/Tab.cpp:2785 +#: src/slic3r/GUI/Tab.cpp:2799 msgid "Firmware Retraction" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3376 +#: src/slic3r/GUI/Tab.cpp:3390 msgid "Detached" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3439 +#: src/slic3r/GUI/Tab.cpp:3453 msgid "remove" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3439 +#: src/slic3r/GUI/Tab.cpp:3453 msgid "delete" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3448 +#: src/slic3r/GUI/Tab.cpp:3462 msgid "It's a last preset for this physical printer." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3453 +#: src/slic3r/GUI/Tab.cpp:3467 msgid "" "Are you sure you want to delete \"%1%\" preset from the physical printer " "\"%2%\"?" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3465 +#: src/slic3r/GUI/Tab.cpp:3479 msgid "" -"The physical printer(s) below is based on the preset, you are going to " +"The physical printer below is based on the preset, you are going to delete." +msgid_plural "" +"The physical printers below are based on the preset, you are going to delete." +msgstr[0] "" +msgstr[1] "" + +#: src/slic3r/GUI/Tab.cpp:3484 +msgid "Note, that selected preset will be deleted from this printer too." +msgid_plural "" +"Note, that selected preset will be deleted from these printers too." +msgstr[0] "" +msgstr[1] "" + +#: src/slic3r/GUI/Tab.cpp:3489 +msgid "" +"The physical printer below is based only on the preset, you are going to " "delete." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:3469 -msgid "" -"Note, that selected preset will be deleted from this/those printer(s) too." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:3473 -msgid "" -"The physical printer(s) below is based only on the preset, you are going to " +msgid_plural "" +"The physical printers below are based only on the preset, you are going to " "delete." -msgstr "" +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/Tab.cpp:3477 +#: src/slic3r/GUI/Tab.cpp:3494 msgid "" -"Note, that this/those printer(s) will be deleted after deleting of the " -"selected preset." -msgstr "" +"Note, that this printer will be deleted after deleting of the selected " +"preset." +msgid_plural "" +"Note, that these printers will be deleted after deleting of the selected " +"preset." +msgstr[0] "" +msgstr[1] "" -#: src/slic3r/GUI/Tab.cpp:3481 +#: src/slic3r/GUI/Tab.cpp:3499 msgid "Are you sure you want to %1% the selected preset?" msgstr "" #. TRN Remove/Delete -#: src/slic3r/GUI/Tab.cpp:3486 +#: src/slic3r/GUI/Tab.cpp:3504 msgid "%1% Preset" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3567 src/slic3r/GUI/Tab.cpp:3639 +#: src/slic3r/GUI/Tab.cpp:3585 src/slic3r/GUI/Tab.cpp:3657 msgid "Set" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3703 +#: src/slic3r/GUI/Tab.cpp:3721 msgid "" "Machine limits will be emitted to G-code and used to estimate print time." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3706 +#: src/slic3r/GUI/Tab.cpp:3724 msgid "" "Machine limits will NOT be emitted to G-code, however they will be used to " "estimate print time, which may therefore not be accurate as the printer may " "apply a different set of machine limits." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3710 +#: src/slic3r/GUI/Tab.cpp:3728 msgid "" "Machine limits are not set, therefore the print time estimate may not be " "accurate." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3732 +#: src/slic3r/GUI/Tab.cpp:3750 msgid "LOCKED LOCK" msgstr "" #. TRN Description for "LOCKED LOCK" -#: src/slic3r/GUI/Tab.cpp:3734 +#: src/slic3r/GUI/Tab.cpp:3752 msgid "" "indicates that the settings are the same as the system (or default) values " "for the current option group" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3736 +#: src/slic3r/GUI/Tab.cpp:3754 msgid "UNLOCKED LOCK" msgstr "" #. TRN Description for "UNLOCKED LOCK" -#: src/slic3r/GUI/Tab.cpp:3738 +#: src/slic3r/GUI/Tab.cpp:3756 msgid "" "indicates that some settings were changed and are not equal to the system " "(or default) values for the current option group.\n" @@ -7150,23 +7199,23 @@ msgid "" "to the system (or default) values." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3743 +#: src/slic3r/GUI/Tab.cpp:3761 msgid "WHITE BULLET" msgstr "" #. TRN Description for "WHITE BULLET" -#: src/slic3r/GUI/Tab.cpp:3745 +#: src/slic3r/GUI/Tab.cpp:3763 msgid "" "for the left button: indicates a non-system (or non-default) preset,\n" "for the right button: indicates that the settings hasn't been modified." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3748 +#: src/slic3r/GUI/Tab.cpp:3766 msgid "BACK ARROW" msgstr "" #. TRN Description for "BACK ARROW" -#: src/slic3r/GUI/Tab.cpp:3750 +#: src/slic3r/GUI/Tab.cpp:3768 msgid "" "indicates that the settings were changed and are not equal to the last saved " "preset for the current option group.\n" @@ -7174,13 +7223,13 @@ msgid "" "to the last saved preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3760 +#: src/slic3r/GUI/Tab.cpp:3778 msgid "" "LOCKED LOCK icon indicates that the settings are the same as the system (or " "default) values for the current option group" msgstr "" -#: src/slic3r/GUI/Tab.cpp:3762 +#: src/slic3r/GUI/Tab.cpp:3780 msgid "" "UNLOCKED LOCK icon indicates that some settings were changed and are not " "equal to the system (or default) values for the current option group.\n" @@ -7188,17 +7237,17 @@ msgid "" "default) values." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3765 +#: src/slic3r/GUI/Tab.cpp:3783 msgid "WHITE BULLET icon indicates a non system (or non default) preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3768 +#: src/slic3r/GUI/Tab.cpp:3786 msgid "" "WHITE BULLET icon indicates that the settings are the same as in the last " "saved preset for the current option group." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3770 +#: src/slic3r/GUI/Tab.cpp:3788 msgid "" "BACK ARROW icon indicates that the settings were changed and are not equal " "to the last saved preset for the current option group.\n" @@ -7206,63 +7255,63 @@ msgid "" "preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3776 +#: src/slic3r/GUI/Tab.cpp:3794 msgid "" "LOCKED LOCK icon indicates that the value is the same as the system (or " "default) value." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3777 +#: src/slic3r/GUI/Tab.cpp:3795 msgid "" "UNLOCKED LOCK icon indicates that the value was changed and is not equal to " "the system (or default) value.\n" "Click to reset current value to the system (or default) value." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3783 +#: src/slic3r/GUI/Tab.cpp:3801 msgid "" "WHITE BULLET icon indicates that the value is the same as in the last saved " "preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3784 +#: src/slic3r/GUI/Tab.cpp:3802 msgid "" "BACK ARROW icon indicates that the value was changed and is not equal to the " "last saved preset.\n" "Click to reset current value to the last saved preset." msgstr "" -#: src/slic3r/GUI/Tab.cpp:3928 src/slic3r/GUI/Tab.cpp:3930 +#: src/slic3r/GUI/Tab.cpp:3946 src/slic3r/GUI/Tab.cpp:3948 msgid "Material" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4052 +#: src/slic3r/GUI/Tab.cpp:4070 msgid "Support head" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4057 +#: src/slic3r/GUI/Tab.cpp:4075 msgid "Support pillar" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4080 +#: src/slic3r/GUI/Tab.cpp:4098 msgid "Connection of the support sticks and junctions" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4085 +#: src/slic3r/GUI/Tab.cpp:4103 msgid "Automatic generation" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4159 +#: src/slic3r/GUI/Tab.cpp:4177 msgid "" "\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n" "To enable \"%1%\", please switch off \"%2%\"" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4161 src/libslic3r/PrintConfig.cpp:3002 +#: src/slic3r/GUI/Tab.cpp:4179 src/libslic3r/PrintConfig.cpp:3091 msgid "Object elevation" msgstr "" -#: src/slic3r/GUI/Tab.cpp:4161 src/libslic3r/PrintConfig.cpp:3104 +#: src/slic3r/GUI/Tab.cpp:4179 src/libslic3r/PrintConfig.cpp:3193 msgid "Pad around object" msgstr "" @@ -7367,35 +7416,35 @@ msgstr "" msgid "Transfer the selected options to the newly selected preset \"%1%\"." msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1019 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1021 msgid "The following presets were modified:" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1024 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1026 msgid "Preset \"%1%\" has the following unsaved changes:" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1028 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1030 msgid "" "Preset \"%1%\" is not compatible with the new printer profile and it has the " "following unsaved changes:" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1029 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1031 msgid "" "Preset \"%1%\" is not compatible with the new print profile and it has the " "following unsaved changes:" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1075 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1077 msgid "Extruders count" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1197 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1199 msgid "Old value" msgstr "" -#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1198 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1200 msgid "New value" msgstr "" @@ -7838,7 +7887,7 @@ msgid "" "connections. See logs for additional details." msgstr "" -#: src/slic3r/Utils/Process.cpp:151 +#: src/slic3r/Utils/Process.cpp:157 msgid "Open G-code file:" msgstr "" @@ -7860,7 +7909,7 @@ msgid "" "Try to repair the model or change its orientation on the bed." msgstr "" -#: src/libslic3r/GCode.cpp:1261 +#: src/libslic3r/GCode.cpp:1274 msgid "" "Your print is very close to the priming regions. Make sure there is no " "collision." @@ -7875,7 +7924,7 @@ msgid "" "Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible." msgstr "" -#: src/libslic3r/Format/3mf.cpp:1668 +#: src/libslic3r/Format/3mf.cpp:1641 msgid "" "The selected 3mf file has been saved with a newer version of %1% and is not " "compatible." @@ -8011,117 +8060,117 @@ msgstr "" msgid "write calledback failed" msgstr "" -#: src/libslic3r/Preset.cpp:1299 +#: src/libslic3r/Preset.cpp:1304 msgid "filament" msgstr "" -#: src/libslic3r/Print.cpp:1251 +#: src/libslic3r/Print.cpp:1257 msgid "All objects are outside of the print volume." msgstr "" -#: src/libslic3r/Print.cpp:1254 +#: src/libslic3r/Print.cpp:1260 msgid "The supplied settings will cause an empty print." msgstr "" -#: src/libslic3r/Print.cpp:1258 +#: src/libslic3r/Print.cpp:1264 msgid "Some objects are too close; your extruder will collide with them." msgstr "" -#: src/libslic3r/Print.cpp:1260 +#: src/libslic3r/Print.cpp:1266 msgid "" "Some objects are too tall and cannot be printed without extruder collisions." msgstr "" -#: src/libslic3r/Print.cpp:1269 +#: src/libslic3r/Print.cpp:1275 msgid "" "Only a single object may be printed at a time in Spiral Vase mode. Either " "remove all but the last object, or enable sequential mode by " "\"complete_objects\"." msgstr "" -#: src/libslic3r/Print.cpp:1277 +#: src/libslic3r/Print.cpp:1283 msgid "" "The Spiral Vase option can only be used when printing single material " "objects." msgstr "" -#: src/libslic3r/Print.cpp:1290 +#: src/libslic3r/Print.cpp:1296 msgid "" "The wipe tower is only supported if all extruders have the same nozzle " "diameter and use filaments of the same diameter." msgstr "" -#: src/libslic3r/Print.cpp:1296 +#: src/libslic3r/Print.cpp:1302 msgid "" "The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, " "RepRapFirmware and Repetier G-code flavors." msgstr "" -#: src/libslic3r/Print.cpp:1298 +#: src/libslic3r/Print.cpp:1304 msgid "" "The Wipe Tower is currently only supported with the relative extruder " "addressing (use_relative_e_distances=1)." msgstr "" -#: src/libslic3r/Print.cpp:1300 +#: src/libslic3r/Print.cpp:1306 msgid "Ooze prevention is currently not supported with the wipe tower enabled." msgstr "" -#: src/libslic3r/Print.cpp:1302 +#: src/libslic3r/Print.cpp:1308 msgid "" "The Wipe Tower currently does not support volumetric E (use_volumetric_e=0)." msgstr "" -#: src/libslic3r/Print.cpp:1304 +#: src/libslic3r/Print.cpp:1310 msgid "" "The Wipe Tower is currently not supported for multimaterial sequential " "prints." msgstr "" -#: src/libslic3r/Print.cpp:1325 +#: src/libslic3r/Print.cpp:1331 msgid "" "The Wipe Tower is only supported for multiple objects if they have equal " "layer heights" msgstr "" -#: src/libslic3r/Print.cpp:1327 +#: src/libslic3r/Print.cpp:1333 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "over an equal number of raft layers" msgstr "" -#: src/libslic3r/Print.cpp:1329 +#: src/libslic3r/Print.cpp:1335 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "with the same support_material_contact_distance" msgstr "" -#: src/libslic3r/Print.cpp:1331 +#: src/libslic3r/Print.cpp:1337 msgid "" "The Wipe Tower is only supported for multiple objects if they are sliced " "equally." msgstr "" -#: src/libslic3r/Print.cpp:1373 +#: src/libslic3r/Print.cpp:1379 msgid "" "The Wipe tower is only supported if all objects have the same variable layer " "height" msgstr "" -#: src/libslic3r/Print.cpp:1399 +#: src/libslic3r/Print.cpp:1405 msgid "" "One or more object were assigned an extruder that the printer does not have." msgstr "" -#: src/libslic3r/Print.cpp:1408 +#: src/libslic3r/Print.cpp:1418 msgid "%1%=%2% mm is too low to be printable at a layer height %3% mm" msgstr "" -#: src/libslic3r/Print.cpp:1411 +#: src/libslic3r/Print.cpp:1421 msgid "Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm" msgstr "" -#: src/libslic3r/Print.cpp:1422 +#: src/libslic3r/Print.cpp:1432 msgid "" "Printing with multiple extruders of differing nozzle diameters. If support " "is to be printed with the current extruder (support_material_extruder == 0 " @@ -8129,13 +8178,13 @@ msgid "" "same diameter." msgstr "" -#: src/libslic3r/Print.cpp:1430 +#: src/libslic3r/Print.cpp:1440 msgid "" "For the Wipe Tower to work with the soluble supports, the support layers " "need to be synchronized with the object layers." msgstr "" -#: src/libslic3r/Print.cpp:1434 +#: src/libslic3r/Print.cpp:1444 msgid "" "The Wipe Tower currently supports the non-soluble supports only if they are " "printed with the current extruder without triggering a tool change. (both " @@ -8143,31 +8192,31 @@ msgid "" "set to 0)." msgstr "" -#: src/libslic3r/Print.cpp:1456 +#: src/libslic3r/Print.cpp:1466 msgid "First layer height can't be greater than nozzle diameter" msgstr "" -#: src/libslic3r/Print.cpp:1461 +#: src/libslic3r/Print.cpp:1471 msgid "Layer height can't be greater than nozzle diameter" msgstr "" -#: src/libslic3r/Print.cpp:1620 +#: src/libslic3r/Print.cpp:1630 msgid "Infilling layers" msgstr "" -#: src/libslic3r/Print.cpp:1646 +#: src/libslic3r/Print.cpp:1656 msgid "Generating skirt" msgstr "" -#: src/libslic3r/Print.cpp:1655 +#: src/libslic3r/Print.cpp:1665 msgid "Generating brim" msgstr "" -#: src/libslic3r/Print.cpp:1678 +#: src/libslic3r/Print.cpp:1691 msgid "Exporting G-code" msgstr "" -#: src/libslic3r/Print.cpp:1682 +#: src/libslic3r/Print.cpp:1695 msgid "Generating G-code" msgstr "" @@ -8272,7 +8321,7 @@ msgid "" "objects printable." msgstr "" -#: src/libslic3r/PrintBase.cpp:72 +#: src/libslic3r/PrintBase.cpp:77 msgid "Failed processing of the output_filename_format template." msgstr "" @@ -8424,7 +8473,7 @@ msgstr "" msgid "mm or % (zero to disable)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:199 src/libslic3r/PrintConfig.cpp:2291 +#: src/libslic3r/PrintConfig.cpp:199 src/libslic3r/PrintConfig.cpp:2380 msgid "Other layers" msgstr "" @@ -8487,10 +8536,10 @@ msgid "" "disable acceleration control for bridges." msgstr "" -#: src/libslic3r/PrintConfig.cpp:252 src/libslic3r/PrintConfig.cpp:395 -#: src/libslic3r/PrintConfig.cpp:940 src/libslic3r/PrintConfig.cpp:1079 -#: src/libslic3r/PrintConfig.cpp:1360 src/libslic3r/PrintConfig.cpp:1409 -#: src/libslic3r/PrintConfig.cpp:1419 src/libslic3r/PrintConfig.cpp:1612 +#: src/libslic3r/PrintConfig.cpp:252 src/libslic3r/PrintConfig.cpp:420 +#: src/libslic3r/PrintConfig.cpp:965 src/libslic3r/PrintConfig.cpp:1168 +#: src/libslic3r/PrintConfig.cpp:1449 src/libslic3r/PrintConfig.cpp:1498 +#: src/libslic3r/PrintConfig.cpp:1508 src/libslic3r/PrintConfig.cpp:1701 msgid "mm/s²" msgstr "" @@ -8505,11 +8554,11 @@ msgid "" "bridges. Use 180° for zero angle." msgstr "" -#: src/libslic3r/PrintConfig.cpp:263 src/libslic3r/PrintConfig.cpp:852 -#: src/libslic3r/PrintConfig.cpp:1853 src/libslic3r/PrintConfig.cpp:1863 -#: src/libslic3r/PrintConfig.cpp:2121 src/libslic3r/PrintConfig.cpp:2276 -#: src/libslic3r/PrintConfig.cpp:2475 src/libslic3r/PrintConfig.cpp:2976 -#: src/libslic3r/PrintConfig.cpp:3097 +#: src/libslic3r/PrintConfig.cpp:263 src/libslic3r/PrintConfig.cpp:877 +#: src/libslic3r/PrintConfig.cpp:1942 src/libslic3r/PrintConfig.cpp:1952 +#: src/libslic3r/PrintConfig.cpp:2210 src/libslic3r/PrintConfig.cpp:2365 +#: src/libslic3r/PrintConfig.cpp:2564 src/libslic3r/PrintConfig.cpp:3065 +#: src/libslic3r/PrintConfig.cpp:3186 msgid "°" msgstr "" @@ -8521,11 +8570,11 @@ msgstr "" msgid "This fan speed is enforced during all bridges and overhangs." msgstr "" -#: src/libslic3r/PrintConfig.cpp:271 src/libslic3r/PrintConfig.cpp:864 -#: src/libslic3r/PrintConfig.cpp:1248 src/libslic3r/PrintConfig.cpp:1427 -#: src/libslic3r/PrintConfig.cpp:1490 src/libslic3r/PrintConfig.cpp:1745 -#: src/libslic3r/PrintConfig.cpp:2653 src/libslic3r/PrintConfig.cpp:2890 -#: src/libslic3r/PrintConfig.cpp:3016 +#: src/libslic3r/PrintConfig.cpp:271 src/libslic3r/PrintConfig.cpp:889 +#: src/libslic3r/PrintConfig.cpp:1337 src/libslic3r/PrintConfig.cpp:1516 +#: src/libslic3r/PrintConfig.cpp:1579 src/libslic3r/PrintConfig.cpp:1834 +#: src/libslic3r/PrintConfig.cpp:2742 src/libslic3r/PrintConfig.cpp:2979 +#: src/libslic3r/PrintConfig.cpp:3105 msgid "%" msgstr "" @@ -8549,17 +8598,17 @@ msgstr "" msgid "Speed for printing bridges." msgstr "" -#: src/libslic3r/PrintConfig.cpp:293 src/libslic3r/PrintConfig.cpp:671 -#: src/libslic3r/PrintConfig.cpp:679 src/libslic3r/PrintConfig.cpp:688 -#: src/libslic3r/PrintConfig.cpp:696 src/libslic3r/PrintConfig.cpp:723 -#: src/libslic3r/PrintConfig.cpp:742 src/libslic3r/PrintConfig.cpp:1015 -#: src/libslic3r/PrintConfig.cpp:1194 src/libslic3r/PrintConfig.cpp:1267 -#: src/libslic3r/PrintConfig.cpp:1343 src/libslic3r/PrintConfig.cpp:1377 -#: src/libslic3r/PrintConfig.cpp:1389 src/libslic3r/PrintConfig.cpp:1399 -#: src/libslic3r/PrintConfig.cpp:1449 src/libslic3r/PrintConfig.cpp:1508 -#: src/libslic3r/PrintConfig.cpp:1642 src/libslic3r/PrintConfig.cpp:1820 -#: src/libslic3r/PrintConfig.cpp:1829 src/libslic3r/PrintConfig.cpp:2255 -#: src/libslic3r/PrintConfig.cpp:2382 +#: src/libslic3r/PrintConfig.cpp:293 src/libslic3r/PrintConfig.cpp:696 +#: src/libslic3r/PrintConfig.cpp:704 src/libslic3r/PrintConfig.cpp:713 +#: src/libslic3r/PrintConfig.cpp:721 src/libslic3r/PrintConfig.cpp:748 +#: src/libslic3r/PrintConfig.cpp:767 src/libslic3r/PrintConfig.cpp:1104 +#: src/libslic3r/PrintConfig.cpp:1283 src/libslic3r/PrintConfig.cpp:1356 +#: src/libslic3r/PrintConfig.cpp:1432 src/libslic3r/PrintConfig.cpp:1466 +#: src/libslic3r/PrintConfig.cpp:1478 src/libslic3r/PrintConfig.cpp:1488 +#: src/libslic3r/PrintConfig.cpp:1538 src/libslic3r/PrintConfig.cpp:1597 +#: src/libslic3r/PrintConfig.cpp:1731 src/libslic3r/PrintConfig.cpp:1909 +#: src/libslic3r/PrintConfig.cpp:1918 src/libslic3r/PrintConfig.cpp:2344 +#: src/libslic3r/PrintConfig.cpp:2471 msgid "mm/s" msgstr "" @@ -8567,58 +8616,92 @@ msgstr "" msgid "Brim width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:301 +#: src/libslic3r/PrintConfig.cpp:302 msgid "" "Horizontal width of the brim that will be printed around each object on the " "first layer." msgstr "" -#: src/libslic3r/PrintConfig.cpp:308 +#: src/libslic3r/PrintConfig.cpp:309 +msgid "Brim type" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:311 +msgid "" +"The places where the brim will be printed around each object on the first " +"layer." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:317 +msgid "No brim" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:318 +msgid "Outer brim only" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:319 +msgid "Inner brim only" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:320 +msgid "Outer and inner brim" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:325 +msgid "Brim offset" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:327 +msgid "The offset of the brim from the printed object." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:333 msgid "Clip multi-part objects" msgstr "" -#: src/libslic3r/PrintConfig.cpp:309 +#: src/libslic3r/PrintConfig.cpp:334 msgid "" "When printing multi-material objects, this settings will make Slic3r to clip " "the overlapping object parts one by the other (2nd part will be clipped by " "the 1st, 3rd part will be clipped by the 1st and 2nd etc)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:316 +#: src/libslic3r/PrintConfig.cpp:341 msgid "Colorprint height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:317 +#: src/libslic3r/PrintConfig.cpp:342 msgid "Heights at which a filament change is to occur." msgstr "" -#: src/libslic3r/PrintConfig.cpp:327 +#: src/libslic3r/PrintConfig.cpp:352 msgid "Compatible printers condition" msgstr "" -#: src/libslic3r/PrintConfig.cpp:328 +#: src/libslic3r/PrintConfig.cpp:353 msgid "" "A boolean expression using the configuration values of an active printer " "profile. If this expression evaluates to true, this profile is considered " "compatible with the active printer profile." msgstr "" -#: src/libslic3r/PrintConfig.cpp:342 +#: src/libslic3r/PrintConfig.cpp:367 msgid "Compatible print profiles condition" msgstr "" -#: src/libslic3r/PrintConfig.cpp:343 +#: src/libslic3r/PrintConfig.cpp:368 msgid "" "A boolean expression using the configuration values of an active print " "profile. If this expression evaluates to true, this profile is considered " "compatible with the active print profile." msgstr "" -#: src/libslic3r/PrintConfig.cpp:360 +#: src/libslic3r/PrintConfig.cpp:385 msgid "Complete individual objects" msgstr "" -#: src/libslic3r/PrintConfig.cpp:361 +#: src/libslic3r/PrintConfig.cpp:386 msgid "" "When printing multiple objects or copies, this feature will complete each " "object before moving onto next one (and starting it from its bottom layer). " @@ -8626,97 +8709,97 @@ msgid "" "warn and prevent you from extruder collisions, but beware." msgstr "" -#: src/libslic3r/PrintConfig.cpp:369 +#: src/libslic3r/PrintConfig.cpp:394 msgid "Enable auto cooling" msgstr "" -#: src/libslic3r/PrintConfig.cpp:370 +#: src/libslic3r/PrintConfig.cpp:395 msgid "" "This flag enables the automatic cooling logic that adjusts print speed and " "fan speed according to layer printing time." msgstr "" -#: src/libslic3r/PrintConfig.cpp:375 +#: src/libslic3r/PrintConfig.cpp:400 msgid "Cooling tube position" msgstr "" -#: src/libslic3r/PrintConfig.cpp:376 +#: src/libslic3r/PrintConfig.cpp:401 msgid "Distance of the center-point of the cooling tube from the extruder tip." msgstr "" -#: src/libslic3r/PrintConfig.cpp:383 +#: src/libslic3r/PrintConfig.cpp:408 msgid "Cooling tube length" msgstr "" -#: src/libslic3r/PrintConfig.cpp:384 +#: src/libslic3r/PrintConfig.cpp:409 msgid "Length of the cooling tube to limit space for cooling moves inside it." msgstr "" -#: src/libslic3r/PrintConfig.cpp:392 +#: src/libslic3r/PrintConfig.cpp:417 msgid "" "This is the acceleration your printer will be reset to after the role-" "specific acceleration values are used (perimeter/infill). Set zero to " "prevent resetting acceleration at all." msgstr "" -#: src/libslic3r/PrintConfig.cpp:401 +#: src/libslic3r/PrintConfig.cpp:426 msgid "Default filament profile" msgstr "" -#: src/libslic3r/PrintConfig.cpp:402 +#: src/libslic3r/PrintConfig.cpp:427 msgid "" "Default filament profile associated with the current printer profile. On " "selection of the current printer profile, this filament profile will be " "activated." msgstr "" -#: src/libslic3r/PrintConfig.cpp:408 +#: src/libslic3r/PrintConfig.cpp:433 msgid "Default print profile" msgstr "" -#: src/libslic3r/PrintConfig.cpp:409 src/libslic3r/PrintConfig.cpp:2820 -#: src/libslic3r/PrintConfig.cpp:2831 +#: src/libslic3r/PrintConfig.cpp:434 src/libslic3r/PrintConfig.cpp:2909 +#: src/libslic3r/PrintConfig.cpp:2920 msgid "" "Default print profile associated with the current printer profile. On " "selection of the current printer profile, this print profile will be " "activated." msgstr "" -#: src/libslic3r/PrintConfig.cpp:415 +#: src/libslic3r/PrintConfig.cpp:440 msgid "Disable fan for the first" msgstr "" -#: src/libslic3r/PrintConfig.cpp:416 +#: src/libslic3r/PrintConfig.cpp:441 msgid "" "You can set this to a positive value to disable fan at all during the first " "layers, so that it does not make adhesion worse." msgstr "" -#: src/libslic3r/PrintConfig.cpp:425 +#: src/libslic3r/PrintConfig.cpp:450 msgid "Don't support bridges" msgstr "" -#: src/libslic3r/PrintConfig.cpp:427 +#: src/libslic3r/PrintConfig.cpp:452 msgid "" "Experimental option for preventing support material from being generated " "under bridged areas." msgstr "" -#: src/libslic3r/PrintConfig.cpp:433 +#: src/libslic3r/PrintConfig.cpp:458 msgid "Distance between copies" msgstr "" -#: src/libslic3r/PrintConfig.cpp:434 +#: src/libslic3r/PrintConfig.cpp:459 msgid "Distance used for the auto-arrange feature of the plater." msgstr "" -#: src/libslic3r/PrintConfig.cpp:442 +#: src/libslic3r/PrintConfig.cpp:467 msgid "" "This end procedure is inserted at the end of the output file. Note that you " "can use placeholder variables for all PrusaSlicer settings." msgstr "" -#: src/libslic3r/PrintConfig.cpp:452 +#: src/libslic3r/PrintConfig.cpp:477 msgid "" "This end procedure is inserted at the end of the output file, before the " "printer end gcode (and before any toolchange from this filament in case of " @@ -8725,70 +8808,70 @@ msgid "" "in extruder order." msgstr "" -#: src/libslic3r/PrintConfig.cpp:463 +#: src/libslic3r/PrintConfig.cpp:488 msgid "Ensure vertical shell thickness" msgstr "" -#: src/libslic3r/PrintConfig.cpp:465 +#: src/libslic3r/PrintConfig.cpp:490 msgid "" "Add solid infill near sloping surfaces to guarantee the vertical shell " "thickness (top+bottom solid layers)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:471 +#: src/libslic3r/PrintConfig.cpp:496 msgid "Top fill pattern" msgstr "" -#: src/libslic3r/PrintConfig.cpp:473 +#: src/libslic3r/PrintConfig.cpp:498 msgid "" "Fill pattern for top infill. This only affects the top visible layer, and " "not its adjacent solid shells." msgstr "" -#: src/libslic3r/PrintConfig.cpp:483 src/libslic3r/PrintConfig.cpp:918 -#: src/libslic3r/PrintConfig.cpp:2236 +#: src/libslic3r/PrintConfig.cpp:508 src/libslic3r/PrintConfig.cpp:943 +#: src/libslic3r/PrintConfig.cpp:2325 msgid "Rectilinear" msgstr "" -#: src/libslic3r/PrintConfig.cpp:484 +#: src/libslic3r/PrintConfig.cpp:509 msgid "Monotonic" msgstr "" -#: src/libslic3r/PrintConfig.cpp:485 src/libslic3r/PrintConfig.cpp:919 +#: src/libslic3r/PrintConfig.cpp:510 src/libslic3r/PrintConfig.cpp:944 msgid "Aligned Rectilinear" msgstr "" -#: src/libslic3r/PrintConfig.cpp:486 src/libslic3r/PrintConfig.cpp:925 +#: src/libslic3r/PrintConfig.cpp:511 src/libslic3r/PrintConfig.cpp:950 msgid "Concentric" msgstr "" -#: src/libslic3r/PrintConfig.cpp:487 src/libslic3r/PrintConfig.cpp:929 +#: src/libslic3r/PrintConfig.cpp:512 src/libslic3r/PrintConfig.cpp:954 msgid "Hilbert Curve" msgstr "" -#: src/libslic3r/PrintConfig.cpp:488 src/libslic3r/PrintConfig.cpp:930 +#: src/libslic3r/PrintConfig.cpp:513 src/libslic3r/PrintConfig.cpp:955 msgid "Archimedean Chords" msgstr "" -#: src/libslic3r/PrintConfig.cpp:489 src/libslic3r/PrintConfig.cpp:931 +#: src/libslic3r/PrintConfig.cpp:514 src/libslic3r/PrintConfig.cpp:956 msgid "Octagram Spiral" msgstr "" -#: src/libslic3r/PrintConfig.cpp:495 +#: src/libslic3r/PrintConfig.cpp:520 msgid "Bottom fill pattern" msgstr "" -#: src/libslic3r/PrintConfig.cpp:497 +#: src/libslic3r/PrintConfig.cpp:522 msgid "" "Fill pattern for bottom infill. This only affects the bottom external " "visible layer, and not its adjacent solid shells." msgstr "" -#: src/libslic3r/PrintConfig.cpp:506 src/libslic3r/PrintConfig.cpp:517 +#: src/libslic3r/PrintConfig.cpp:531 src/libslic3r/PrintConfig.cpp:542 msgid "External perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:508 +#: src/libslic3r/PrintConfig.cpp:533 msgid "" "Set this to a non-zero value to set a manual extrusion width for external " "perimeters. If left zero, default extrusion width will be used if set, " @@ -8796,43 +8879,43 @@ msgid "" "(for example 200%), it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:511 src/libslic3r/PrintConfig.cpp:621 -#: src/libslic3r/PrintConfig.cpp:962 src/libslic3r/PrintConfig.cpp:975 -#: src/libslic3r/PrintConfig.cpp:1104 src/libslic3r/PrintConfig.cpp:1159 -#: src/libslic3r/PrintConfig.cpp:1185 src/libslic3r/PrintConfig.cpp:1632 -#: src/libslic3r/PrintConfig.cpp:1961 src/libslic3r/PrintConfig.cpp:2110 -#: src/libslic3r/PrintConfig.cpp:2178 src/libslic3r/PrintConfig.cpp:2339 +#: src/libslic3r/PrintConfig.cpp:536 src/libslic3r/PrintConfig.cpp:646 +#: src/libslic3r/PrintConfig.cpp:987 src/libslic3r/PrintConfig.cpp:1000 +#: src/libslic3r/PrintConfig.cpp:1193 src/libslic3r/PrintConfig.cpp:1248 +#: src/libslic3r/PrintConfig.cpp:1274 src/libslic3r/PrintConfig.cpp:1721 +#: src/libslic3r/PrintConfig.cpp:2050 src/libslic3r/PrintConfig.cpp:2199 +#: src/libslic3r/PrintConfig.cpp:2267 src/libslic3r/PrintConfig.cpp:2428 msgid "mm or %" msgstr "" -#: src/libslic3r/PrintConfig.cpp:519 +#: src/libslic3r/PrintConfig.cpp:544 msgid "" "This separate setting will affect the speed of external perimeters (the " "visible ones). If expressed as percentage (for example: 80%) it will be " "calculated on the perimeters speed setting above. Set to zero for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:522 src/libslic3r/PrintConfig.cpp:984 -#: src/libslic3r/PrintConfig.cpp:1920 src/libslic3r/PrintConfig.cpp:1972 -#: src/libslic3r/PrintConfig.cpp:2222 src/libslic3r/PrintConfig.cpp:2352 +#: src/libslic3r/PrintConfig.cpp:547 src/libslic3r/PrintConfig.cpp:1009 +#: src/libslic3r/PrintConfig.cpp:2009 src/libslic3r/PrintConfig.cpp:2061 +#: src/libslic3r/PrintConfig.cpp:2311 src/libslic3r/PrintConfig.cpp:2441 msgid "mm/s or %" msgstr "" -#: src/libslic3r/PrintConfig.cpp:529 +#: src/libslic3r/PrintConfig.cpp:554 msgid "External perimeters first" msgstr "" -#: src/libslic3r/PrintConfig.cpp:531 +#: src/libslic3r/PrintConfig.cpp:556 msgid "" "Print contour perimeters from the outermost one to the innermost one instead " "of the default inverse order." msgstr "" -#: src/libslic3r/PrintConfig.cpp:537 +#: src/libslic3r/PrintConfig.cpp:562 msgid "Extra perimeters if needed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:539 +#: src/libslic3r/PrintConfig.cpp:564 #, possible-c-format msgid "" "Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r " @@ -8840,14 +8923,14 @@ msgid "" "is supported." msgstr "" -#: src/libslic3r/PrintConfig.cpp:549 +#: src/libslic3r/PrintConfig.cpp:574 msgid "" "The extruder to use (unless more specific extruder settings are specified). " "This value overrides perimeter and infill extruders, but not the support " "extruders." msgstr "" -#: src/libslic3r/PrintConfig.cpp:561 +#: src/libslic3r/PrintConfig.cpp:586 msgid "" "Set this to the vertical distance between your nozzle tip and (usually) the " "X carriage rods. In other words, this is the height of the clearance " @@ -8855,26 +8938,26 @@ msgid "" "extruder can peek before colliding with other printed objects." msgstr "" -#: src/libslic3r/PrintConfig.cpp:572 +#: src/libslic3r/PrintConfig.cpp:597 msgid "" "Set this to the clearance radius around your extruder. If the extruder is " "not centered, choose the largest value for safety. This setting is used to " "check for collisions and to display the graphical preview in the plater." msgstr "" -#: src/libslic3r/PrintConfig.cpp:582 +#: src/libslic3r/PrintConfig.cpp:607 msgid "Extruder Color" msgstr "" -#: src/libslic3r/PrintConfig.cpp:583 src/libslic3r/PrintConfig.cpp:645 +#: src/libslic3r/PrintConfig.cpp:608 src/libslic3r/PrintConfig.cpp:670 msgid "This is only used in the Slic3r interface as a visual help." msgstr "" -#: src/libslic3r/PrintConfig.cpp:589 +#: src/libslic3r/PrintConfig.cpp:614 msgid "Extruder offset" msgstr "" -#: src/libslic3r/PrintConfig.cpp:590 +#: src/libslic3r/PrintConfig.cpp:615 msgid "" "If your firmware doesn't handle the extruder displacement you need the G-" "code to take it into account. This option lets you specify the displacement " @@ -8882,21 +8965,21 @@ msgid "" "coordinates (they will be subtracted from the XY coordinate)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:599 +#: src/libslic3r/PrintConfig.cpp:624 msgid "Extrusion axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:600 +#: src/libslic3r/PrintConfig.cpp:625 msgid "" "Use this option to set the axis letter associated to your printer's extruder " "(usually E but some printers use A)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:605 +#: src/libslic3r/PrintConfig.cpp:630 msgid "Extrusion multiplier" msgstr "" -#: src/libslic3r/PrintConfig.cpp:606 +#: src/libslic3r/PrintConfig.cpp:631 msgid "" "This factor changes the amount of flow proportionally. You may need to tweak " "this setting to get nice surface finish and correct single wall widths. " @@ -8904,11 +8987,11 @@ msgid "" "more, check filament diameter and your firmware E steps." msgstr "" -#: src/libslic3r/PrintConfig.cpp:615 +#: src/libslic3r/PrintConfig.cpp:640 msgid "Default extrusion width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:617 +#: src/libslic3r/PrintConfig.cpp:642 msgid "" "Set this to a non-zero value to allow a manual extrusion width. If left to " "zero, Slic3r derives extrusion widths from the nozzle diameter (see the " @@ -8917,123 +9000,123 @@ msgid "" "height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:628 +#: src/libslic3r/PrintConfig.cpp:653 msgid "Keep fan always on" msgstr "" -#: src/libslic3r/PrintConfig.cpp:629 +#: src/libslic3r/PrintConfig.cpp:654 msgid "" "If this is enabled, fan will never be disabled and will be kept running at " "least at its minimum speed. Useful for PLA, harmful for ABS." msgstr "" -#: src/libslic3r/PrintConfig.cpp:634 +#: src/libslic3r/PrintConfig.cpp:659 msgid "Enable fan if layer print time is below" msgstr "" -#: src/libslic3r/PrintConfig.cpp:635 +#: src/libslic3r/PrintConfig.cpp:660 msgid "" "If layer print time is estimated below this number of seconds, fan will be " "enabled and its speed will be calculated by interpolating the minimum and " "maximum speeds." msgstr "" -#: src/libslic3r/PrintConfig.cpp:637 src/libslic3r/PrintConfig.cpp:1908 +#: src/libslic3r/PrintConfig.cpp:662 src/libslic3r/PrintConfig.cpp:1997 msgid "approximate seconds" msgstr "" -#: src/libslic3r/PrintConfig.cpp:644 +#: src/libslic3r/PrintConfig.cpp:669 msgid "Color" msgstr "" -#: src/libslic3r/PrintConfig.cpp:650 +#: src/libslic3r/PrintConfig.cpp:675 msgid "Filament notes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:651 +#: src/libslic3r/PrintConfig.cpp:676 msgid "You can put your notes regarding the filament here." msgstr "" -#: src/libslic3r/PrintConfig.cpp:659 src/libslic3r/PrintConfig.cpp:1455 +#: src/libslic3r/PrintConfig.cpp:684 src/libslic3r/PrintConfig.cpp:1544 msgid "Max volumetric speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:660 +#: src/libslic3r/PrintConfig.cpp:685 msgid "" "Maximum volumetric speed allowed for this filament. Limits the maximum " "volumetric speed of a print to the minimum of print and filament volumetric " "speed. Set to zero for no limit." msgstr "" -#: src/libslic3r/PrintConfig.cpp:669 +#: src/libslic3r/PrintConfig.cpp:694 msgid "Loading speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:670 +#: src/libslic3r/PrintConfig.cpp:695 msgid "Speed used for loading the filament on the wipe tower." msgstr "" -#: src/libslic3r/PrintConfig.cpp:677 +#: src/libslic3r/PrintConfig.cpp:702 msgid "Loading speed at the start" msgstr "" -#: src/libslic3r/PrintConfig.cpp:678 +#: src/libslic3r/PrintConfig.cpp:703 msgid "Speed used at the very beginning of loading phase." msgstr "" -#: src/libslic3r/PrintConfig.cpp:685 +#: src/libslic3r/PrintConfig.cpp:710 msgid "Unloading speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:686 +#: src/libslic3r/PrintConfig.cpp:711 msgid "" "Speed used for unloading the filament on the wipe tower (does not affect " "initial part of unloading just after ramming)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:694 +#: src/libslic3r/PrintConfig.cpp:719 msgid "Unloading speed at the start" msgstr "" -#: src/libslic3r/PrintConfig.cpp:695 +#: src/libslic3r/PrintConfig.cpp:720 msgid "" "Speed used for unloading the tip of the filament immediately after ramming." msgstr "" -#: src/libslic3r/PrintConfig.cpp:702 +#: src/libslic3r/PrintConfig.cpp:727 msgid "Delay after unloading" msgstr "" -#: src/libslic3r/PrintConfig.cpp:703 +#: src/libslic3r/PrintConfig.cpp:728 msgid "" "Time to wait after the filament is unloaded. May help to get reliable " "toolchanges with flexible materials that may need more time to shrink to " "original dimensions." msgstr "" -#: src/libslic3r/PrintConfig.cpp:712 +#: src/libslic3r/PrintConfig.cpp:737 msgid "Number of cooling moves" msgstr "" -#: src/libslic3r/PrintConfig.cpp:713 +#: src/libslic3r/PrintConfig.cpp:738 msgid "" "Filament is cooled by being moved back and forth in the cooling tubes. " "Specify desired number of these moves." msgstr "" -#: src/libslic3r/PrintConfig.cpp:721 +#: src/libslic3r/PrintConfig.cpp:746 msgid "Speed of the first cooling move" msgstr "" -#: src/libslic3r/PrintConfig.cpp:722 +#: src/libslic3r/PrintConfig.cpp:747 msgid "Cooling moves are gradually accelerating beginning at this speed." msgstr "" -#: src/libslic3r/PrintConfig.cpp:729 +#: src/libslic3r/PrintConfig.cpp:754 msgid "Minimal purge on wipe tower" msgstr "" -#: src/libslic3r/PrintConfig.cpp:730 +#: src/libslic3r/PrintConfig.cpp:755 msgid "" "After a tool change, the exact position of the newly loaded filament inside " "the nozzle may not be known, and the filament pressure is likely not yet " @@ -9042,63 +9125,63 @@ msgid "" "to produce successive infill or sacrificial object extrusions reliably." msgstr "" -#: src/libslic3r/PrintConfig.cpp:734 +#: src/libslic3r/PrintConfig.cpp:759 msgid "mm³" msgstr "" -#: src/libslic3r/PrintConfig.cpp:740 +#: src/libslic3r/PrintConfig.cpp:765 msgid "Speed of the last cooling move" msgstr "" -#: src/libslic3r/PrintConfig.cpp:741 +#: src/libslic3r/PrintConfig.cpp:766 msgid "Cooling moves are gradually accelerating towards this speed." msgstr "" -#: src/libslic3r/PrintConfig.cpp:748 +#: src/libslic3r/PrintConfig.cpp:773 msgid "Filament load time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:749 +#: src/libslic3r/PrintConfig.cpp:774 msgid "" "Time for the printer firmware (or the Multi Material Unit 2.0) to load a new " "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" -#: src/libslic3r/PrintConfig.cpp:756 +#: src/libslic3r/PrintConfig.cpp:781 msgid "Ramming parameters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:757 +#: src/libslic3r/PrintConfig.cpp:782 msgid "" "This string is edited by RammingDialog and contains ramming specific " "parameters." msgstr "" -#: src/libslic3r/PrintConfig.cpp:763 +#: src/libslic3r/PrintConfig.cpp:788 msgid "Filament unload time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:764 +#: src/libslic3r/PrintConfig.cpp:789 msgid "" "Time for the printer firmware (or the Multi Material Unit 2.0) to unload a " "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" -#: src/libslic3r/PrintConfig.cpp:772 +#: src/libslic3r/PrintConfig.cpp:797 msgid "" "Enter your filament diameter here. Good precision is required, so use a " "caliper and do multiple measurements along the filament, then compute the " "average." msgstr "" -#: src/libslic3r/PrintConfig.cpp:779 src/libslic3r/PrintConfig.cpp:2731 -#: src/libslic3r/PrintConfig.cpp:2732 +#: src/libslic3r/PrintConfig.cpp:804 src/libslic3r/PrintConfig.cpp:2820 +#: src/libslic3r/PrintConfig.cpp:2821 msgid "Density" msgstr "" -#: src/libslic3r/PrintConfig.cpp:780 +#: src/libslic3r/PrintConfig.cpp:805 msgid "" "Enter your filament density here. This is only for statistical information. " "A decent way is to weigh a known length of filament and compute the ratio of " @@ -9106,41 +9189,41 @@ msgid "" "displacement." msgstr "" -#: src/libslic3r/PrintConfig.cpp:783 +#: src/libslic3r/PrintConfig.cpp:808 msgid "g/cm³" msgstr "" -#: src/libslic3r/PrintConfig.cpp:788 +#: src/libslic3r/PrintConfig.cpp:813 msgid "Filament type" msgstr "" -#: src/libslic3r/PrintConfig.cpp:789 +#: src/libslic3r/PrintConfig.cpp:814 msgid "The filament material type for use in custom G-codes." msgstr "" -#: src/libslic3r/PrintConfig.cpp:816 +#: src/libslic3r/PrintConfig.cpp:841 msgid "Soluble material" msgstr "" -#: src/libslic3r/PrintConfig.cpp:817 +#: src/libslic3r/PrintConfig.cpp:842 msgid "Soluble material is most likely used for a soluble support." msgstr "" -#: src/libslic3r/PrintConfig.cpp:823 +#: src/libslic3r/PrintConfig.cpp:848 msgid "" "Enter your filament cost per kg here. This is only for statistical " "information." msgstr "" -#: src/libslic3r/PrintConfig.cpp:824 +#: src/libslic3r/PrintConfig.cpp:849 msgid "money/kg" msgstr "" -#: src/libslic3r/PrintConfig.cpp:829 +#: src/libslic3r/PrintConfig.cpp:854 msgid "Spool weight" msgstr "" -#: src/libslic3r/PrintConfig.cpp:830 +#: src/libslic3r/PrintConfig.cpp:855 msgid "" "Enter weight of the empty filament spool. One may weigh a partially consumed " "filament spool before printing and one may compare the measured weight with " @@ -9148,103 +9231,103 @@ msgid "" "amount of filament on the spool is sufficient to finish the print." msgstr "" -#: src/libslic3r/PrintConfig.cpp:834 +#: src/libslic3r/PrintConfig.cpp:859 msgid "g" msgstr "" -#: src/libslic3r/PrintConfig.cpp:843 src/libslic3r/PrintConfig.cpp:2815 +#: src/libslic3r/PrintConfig.cpp:868 src/libslic3r/PrintConfig.cpp:2904 msgid "(Unknown)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:847 +#: src/libslic3r/PrintConfig.cpp:872 msgid "Fill angle" msgstr "" -#: src/libslic3r/PrintConfig.cpp:849 +#: src/libslic3r/PrintConfig.cpp:874 msgid "" "Default base angle for infill orientation. Cross-hatching will be applied to " "this. Bridges will be infilled using the best direction Slic3r can detect, " "so this setting does not affect them." msgstr "" -#: src/libslic3r/PrintConfig.cpp:861 +#: src/libslic3r/PrintConfig.cpp:886 msgid "Fill density" msgstr "" -#: src/libslic3r/PrintConfig.cpp:863 +#: src/libslic3r/PrintConfig.cpp:888 msgid "Density of internal infill, expressed in the range 0% - 100%." msgstr "" -#: src/libslic3r/PrintConfig.cpp:898 +#: src/libslic3r/PrintConfig.cpp:923 msgid "Fill pattern" msgstr "" -#: src/libslic3r/PrintConfig.cpp:900 +#: src/libslic3r/PrintConfig.cpp:925 msgid "Fill pattern for general low-density infill." msgstr "" -#: src/libslic3r/PrintConfig.cpp:920 +#: src/libslic3r/PrintConfig.cpp:945 msgid "Grid" msgstr "" -#: src/libslic3r/PrintConfig.cpp:921 +#: src/libslic3r/PrintConfig.cpp:946 msgid "Triangles" msgstr "" -#: src/libslic3r/PrintConfig.cpp:922 +#: src/libslic3r/PrintConfig.cpp:947 msgid "Stars" msgstr "" -#: src/libslic3r/PrintConfig.cpp:923 +#: src/libslic3r/PrintConfig.cpp:948 msgid "Cubic" msgstr "" -#: src/libslic3r/PrintConfig.cpp:924 +#: src/libslic3r/PrintConfig.cpp:949 msgid "Line" msgstr "" -#: src/libslic3r/PrintConfig.cpp:926 src/libslic3r/PrintConfig.cpp:2238 +#: src/libslic3r/PrintConfig.cpp:951 src/libslic3r/PrintConfig.cpp:2327 msgid "Honeycomb" msgstr "" -#: src/libslic3r/PrintConfig.cpp:927 +#: src/libslic3r/PrintConfig.cpp:952 msgid "3D Honeycomb" msgstr "" -#: src/libslic3r/PrintConfig.cpp:928 +#: src/libslic3r/PrintConfig.cpp:953 msgid "Gyroid" msgstr "" -#: src/libslic3r/PrintConfig.cpp:932 +#: src/libslic3r/PrintConfig.cpp:957 msgid "Adaptive Cubic" msgstr "" -#: src/libslic3r/PrintConfig.cpp:933 +#: src/libslic3r/PrintConfig.cpp:958 msgid "Support Cubic" msgstr "" -#: src/libslic3r/PrintConfig.cpp:937 src/libslic3r/PrintConfig.cpp:946 -#: src/libslic3r/PrintConfig.cpp:956 src/libslic3r/PrintConfig.cpp:990 +#: src/libslic3r/PrintConfig.cpp:962 src/libslic3r/PrintConfig.cpp:971 +#: src/libslic3r/PrintConfig.cpp:981 src/libslic3r/PrintConfig.cpp:1015 msgid "First layer" msgstr "" -#: src/libslic3r/PrintConfig.cpp:938 +#: src/libslic3r/PrintConfig.cpp:963 msgid "" "This is the acceleration your printer will use for first layer. Set zero to " "disable acceleration control for first layer." msgstr "" -#: src/libslic3r/PrintConfig.cpp:947 +#: src/libslic3r/PrintConfig.cpp:972 msgid "First layer bed temperature" msgstr "" -#: src/libslic3r/PrintConfig.cpp:948 +#: src/libslic3r/PrintConfig.cpp:973 msgid "" "Heated build plate temperature for the first layer. Set this to zero to " "disable bed temperature control commands in the output." msgstr "" -#: src/libslic3r/PrintConfig.cpp:958 +#: src/libslic3r/PrintConfig.cpp:983 msgid "" "Set this to a non-zero value to set a manual extrusion width for first " "layer. You can use this to force fatter extrudates for better adhesion. If " @@ -9252,7 +9335,7 @@ msgid "" "layer height. If set to zero, it will use the default extrusion width." msgstr "" -#: src/libslic3r/PrintConfig.cpp:971 +#: src/libslic3r/PrintConfig.cpp:996 msgid "" "When printing with very low layer heights, you might still want to print a " "thicker bottom layer to improve adhesion and tolerance for non perfect build " @@ -9260,33 +9343,33 @@ msgid "" "example: 150%) over the default layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:980 +#: src/libslic3r/PrintConfig.cpp:1005 msgid "First layer speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:981 +#: src/libslic3r/PrintConfig.cpp:1006 msgid "" "If expressed as absolute value in mm/s, this speed will be applied to all " "the print moves of the first layer, regardless of their type. If expressed " "as a percentage (for example: 40%) it will scale the default speeds." msgstr "" -#: src/libslic3r/PrintConfig.cpp:991 +#: src/libslic3r/PrintConfig.cpp:1016 msgid "First layer nozzle temperature" msgstr "" -#: src/libslic3r/PrintConfig.cpp:992 +#: src/libslic3r/PrintConfig.cpp:1017 msgid "" "Nozzle temperature for the first layer. If you want to control temperature " "manually during print, set this to zero to disable temperature control " "commands in the output G-code." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1000 +#: src/libslic3r/PrintConfig.cpp:1025 msgid "Full fan speed at layer" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1001 +#: src/libslic3r/PrintConfig.cpp:1026 msgid "" "Fan speed will be ramped up linearly from zero at layer " "\"disable_fan_first_layers\" to maximum at layer \"full_fan_speed_layer\". " @@ -9295,29 +9378,62 @@ msgid "" "maximum allowed speed at layer \"disable_fan_first_layers\" + 1." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1013 +#: src/libslic3r/PrintConfig.cpp:1036 +msgid "Fuzzy skin perimeter mode" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1037 src/libslic3r/PrintConfig.cpp:1083 +#: src/libslic3r/PrintConfig.cpp:1092 +msgid "Fuzzy Skin" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1038 +msgid "Fuzzy skin perimeter mode." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1046 +msgid "External" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1047 +msgid "External (skip first layer)" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1048 +msgid "All perimeters" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1082 +msgid "Fuzzy skin thickness" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1091 +msgid "Fuzzy skin point distance" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:1102 msgid "" "Speed for filling small gaps using short zigzag moves. Keep this reasonably " "low to avoid too much shaking and resonance issues. Set zero to disable gaps " "filling." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1021 +#: src/libslic3r/PrintConfig.cpp:1110 msgid "Verbose G-code" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1022 +#: src/libslic3r/PrintConfig.cpp:1111 msgid "" "Enable this to get a commented G-code file, with each line explained by a " "descriptive text. If you print from SD card, the additional weight of the " "file could make your firmware slow down." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1029 +#: src/libslic3r/PrintConfig.cpp:1118 msgid "G-code flavor" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1030 +#: src/libslic3r/PrintConfig.cpp:1119 msgid "" "Some G/M-code commands, including temperature control and others, are not " "universal. Set this option to your printer's firmware to get a compatible " @@ -9325,15 +9441,15 @@ msgid "" "extrusion value at all." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1055 +#: src/libslic3r/PrintConfig.cpp:1144 msgid "No extrusion" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1060 +#: src/libslic3r/PrintConfig.cpp:1149 msgid "Label objects" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1061 +#: src/libslic3r/PrintConfig.cpp:1150 msgid "" "Enable this to add comments into the G-Code labeling print moves with what " "object they belong to, which is useful for the Octoprint CancelObject " @@ -9341,42 +9457,42 @@ msgid "" "setup and Wipe into Object / Wipe into Infill." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1068 +#: src/libslic3r/PrintConfig.cpp:1157 msgid "High extruder current on filament swap" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1069 +#: src/libslic3r/PrintConfig.cpp:1158 msgid "" "It may be beneficial to increase the extruder motor current during the " "filament exchange sequence to allow for rapid ramming feed rates and to " "overcome resistance when loading a filament with an ugly shaped tip." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1077 +#: src/libslic3r/PrintConfig.cpp:1166 msgid "" "This is the acceleration your printer will use for infill. Set zero to " "disable acceleration control for infill." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1085 +#: src/libslic3r/PrintConfig.cpp:1174 msgid "Combine infill every" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1087 +#: src/libslic3r/PrintConfig.cpp:1176 msgid "" "This feature allows to combine infill and speed up your print by extruding " "thicker infill layers while preserving thin perimeters, thus accuracy." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1090 +#: src/libslic3r/PrintConfig.cpp:1179 msgid "Combine infill every n layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1096 +#: src/libslic3r/PrintConfig.cpp:1185 msgid "Length of the infill anchor" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1098 +#: src/libslic3r/PrintConfig.cpp:1187 msgid "" "Connect an infill line to an internal perimeter with a short segment of an " "additional perimeter. If expressed as percentage (example: 15%) it is " @@ -9389,19 +9505,19 @@ msgid "" "perimeters connected to a single infill line." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1113 +#: src/libslic3r/PrintConfig.cpp:1202 msgid "0 (no open anchors)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1118 src/libslic3r/PrintConfig.cpp:1140 +#: src/libslic3r/PrintConfig.cpp:1207 src/libslic3r/PrintConfig.cpp:1229 msgid "1000 (unlimited)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1123 +#: src/libslic3r/PrintConfig.cpp:1212 msgid "Maximum length of the infill anchor" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1125 +#: src/libslic3r/PrintConfig.cpp:1214 msgid "" "Connect an infill line to an internal perimeter with a short segment of an " "additional perimeter. If expressed as percentage (example: 15%) it is " @@ -9413,19 +9529,19 @@ msgid "" "parameter. Set this parameter to zero to disable anchoring." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1135 +#: src/libslic3r/PrintConfig.cpp:1224 msgid "0 (not anchored)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1145 +#: src/libslic3r/PrintConfig.cpp:1234 msgid "Infill extruder" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1147 +#: src/libslic3r/PrintConfig.cpp:1236 msgid "The extruder to use when printing infill." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1155 +#: src/libslic3r/PrintConfig.cpp:1244 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill. If " "left zero, default extrusion width will be used if set, otherwise 1.125 x " @@ -9434,32 +9550,32 @@ msgid "" "example 90%) it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1165 +#: src/libslic3r/PrintConfig.cpp:1254 msgid "Infill before perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1166 +#: src/libslic3r/PrintConfig.cpp:1255 msgid "" "This option will switch the print order of perimeters and infill, making the " "latter first." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1171 +#: src/libslic3r/PrintConfig.cpp:1260 msgid "Only infill where needed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1173 +#: src/libslic3r/PrintConfig.cpp:1262 msgid "" "This option will limit infill to the areas actually needed for supporting " "ceilings (it will act as internal support material). If enabled, slows down " "the G-code generation due to the multiple checks involved." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1180 +#: src/libslic3r/PrintConfig.cpp:1269 msgid "Infill/perimeters overlap" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1182 +#: src/libslic3r/PrintConfig.cpp:1271 msgid "" "This setting applies an additional overlap between infill and perimeters for " "better bonding. Theoretically this shouldn't be needed, but backlash might " @@ -9467,71 +9583,71 @@ msgid "" "perimeter extrusion width." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1193 +#: src/libslic3r/PrintConfig.cpp:1282 msgid "Speed for printing the internal fill. Set to zero for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1201 +#: src/libslic3r/PrintConfig.cpp:1290 msgid "Inherits profile" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1202 +#: src/libslic3r/PrintConfig.cpp:1291 msgid "Name of the profile, from which this profile inherits." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1215 +#: src/libslic3r/PrintConfig.cpp:1304 msgid "Interface shells" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1216 +#: src/libslic3r/PrintConfig.cpp:1305 msgid "" "Force the generation of solid shells between adjacent materials/volumes. " "Useful for multi-extruder prints with translucent materials or manual " "soluble support material." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1224 +#: src/libslic3r/PrintConfig.cpp:1313 msgid "Enable ironing" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1225 +#: src/libslic3r/PrintConfig.cpp:1314 msgid "" "Enable ironing of the top layers with the hot print head for smooth surface" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1231 src/libslic3r/PrintConfig.cpp:1233 +#: src/libslic3r/PrintConfig.cpp:1320 src/libslic3r/PrintConfig.cpp:1322 msgid "Ironing Type" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1238 +#: src/libslic3r/PrintConfig.cpp:1327 msgid "All top surfaces" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1239 +#: src/libslic3r/PrintConfig.cpp:1328 msgid "Topmost surface only" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1240 +#: src/libslic3r/PrintConfig.cpp:1329 msgid "All solid surfaces" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1245 +#: src/libslic3r/PrintConfig.cpp:1334 msgid "Flow rate" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1247 +#: src/libslic3r/PrintConfig.cpp:1336 msgid "Percent of a flow rate relative to object's normal layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1255 +#: src/libslic3r/PrintConfig.cpp:1344 msgid "Spacing between ironing passes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1257 +#: src/libslic3r/PrintConfig.cpp:1346 msgid "Distance between ironing lines" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1274 +#: src/libslic3r/PrintConfig.cpp:1363 msgid "" "This custom code is inserted at every layer change, right after the Z move " "and before the extruder moves to the first layer point. Note that you can " @@ -9539,11 +9655,11 @@ msgid "" "[layer_z]." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1285 +#: src/libslic3r/PrintConfig.cpp:1374 msgid "Supports remaining times" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1286 +#: src/libslic3r/PrintConfig.cpp:1375 msgid "" "Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute " "intervals into the G-code to let the firmware show accurate remaining time. " @@ -9551,175 +9667,175 @@ msgid "" "firmware supports M73 Qxx Sxx for the silent mode." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1294 +#: src/libslic3r/PrintConfig.cpp:1383 msgid "Supports stealth mode" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1295 +#: src/libslic3r/PrintConfig.cpp:1384 msgid "The firmware supports stealth mode" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1300 +#: src/libslic3r/PrintConfig.cpp:1389 msgid "How to apply limits" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1301 +#: src/libslic3r/PrintConfig.cpp:1390 msgid "Purpose of Machine Limits" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1303 +#: src/libslic3r/PrintConfig.cpp:1392 msgid "How to apply the Machine Limits" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1308 +#: src/libslic3r/PrintConfig.cpp:1397 msgid "Emit to G-code" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1309 +#: src/libslic3r/PrintConfig.cpp:1398 msgid "Use for time estimate" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1310 +#: src/libslic3r/PrintConfig.cpp:1399 msgid "Ignore" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1333 +#: src/libslic3r/PrintConfig.cpp:1422 msgid "Maximum feedrate X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1334 +#: src/libslic3r/PrintConfig.cpp:1423 msgid "Maximum feedrate Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1335 +#: src/libslic3r/PrintConfig.cpp:1424 msgid "Maximum feedrate Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1336 +#: src/libslic3r/PrintConfig.cpp:1425 msgid "Maximum feedrate E" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1339 +#: src/libslic3r/PrintConfig.cpp:1428 msgid "Maximum feedrate of the X axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1340 +#: src/libslic3r/PrintConfig.cpp:1429 msgid "Maximum feedrate of the Y axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1341 +#: src/libslic3r/PrintConfig.cpp:1430 msgid "Maximum feedrate of the Z axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1342 +#: src/libslic3r/PrintConfig.cpp:1431 msgid "Maximum feedrate of the E axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1350 +#: src/libslic3r/PrintConfig.cpp:1439 msgid "Maximum acceleration X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1351 +#: src/libslic3r/PrintConfig.cpp:1440 msgid "Maximum acceleration Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1352 +#: src/libslic3r/PrintConfig.cpp:1441 msgid "Maximum acceleration Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1353 +#: src/libslic3r/PrintConfig.cpp:1442 msgid "Maximum acceleration E" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1356 +#: src/libslic3r/PrintConfig.cpp:1445 msgid "Maximum acceleration of the X axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1357 +#: src/libslic3r/PrintConfig.cpp:1446 msgid "Maximum acceleration of the Y axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1358 +#: src/libslic3r/PrintConfig.cpp:1447 msgid "Maximum acceleration of the Z axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1359 +#: src/libslic3r/PrintConfig.cpp:1448 msgid "Maximum acceleration of the E axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1367 +#: src/libslic3r/PrintConfig.cpp:1456 msgid "Maximum jerk X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1368 +#: src/libslic3r/PrintConfig.cpp:1457 msgid "Maximum jerk Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1369 +#: src/libslic3r/PrintConfig.cpp:1458 msgid "Maximum jerk Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1370 +#: src/libslic3r/PrintConfig.cpp:1459 msgid "Maximum jerk E" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1373 +#: src/libslic3r/PrintConfig.cpp:1462 msgid "Maximum jerk of the X axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1374 +#: src/libslic3r/PrintConfig.cpp:1463 msgid "Maximum jerk of the Y axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1375 +#: src/libslic3r/PrintConfig.cpp:1464 msgid "Maximum jerk of the Z axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1376 +#: src/libslic3r/PrintConfig.cpp:1465 msgid "Maximum jerk of the E axis" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1386 +#: src/libslic3r/PrintConfig.cpp:1475 msgid "Minimum feedrate when extruding" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1388 +#: src/libslic3r/PrintConfig.cpp:1477 msgid "Minimum feedrate when extruding (M205 S)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1396 +#: src/libslic3r/PrintConfig.cpp:1485 msgid "Minimum travel feedrate" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1398 +#: src/libslic3r/PrintConfig.cpp:1487 msgid "Minimum travel feedrate (M205 T)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1406 +#: src/libslic3r/PrintConfig.cpp:1495 msgid "Maximum acceleration when extruding" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1408 +#: src/libslic3r/PrintConfig.cpp:1497 msgid "Maximum acceleration when extruding (M204 S)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1416 +#: src/libslic3r/PrintConfig.cpp:1505 msgid "Maximum acceleration when retracting" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1418 +#: src/libslic3r/PrintConfig.cpp:1507 msgid "Maximum acceleration when retracting (M204 T)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1425 src/libslic3r/PrintConfig.cpp:1434 +#: src/libslic3r/PrintConfig.cpp:1514 src/libslic3r/PrintConfig.cpp:1523 msgid "Max" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1426 +#: src/libslic3r/PrintConfig.cpp:1515 msgid "This setting represents the maximum speed of your fan." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1435 +#: src/libslic3r/PrintConfig.cpp:1524 #, possible-c-format msgid "" "This is the highest printable layer height for this extruder, used to cap " @@ -9728,28 +9844,28 @@ msgid "" "adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1445 +#: src/libslic3r/PrintConfig.cpp:1534 msgid "Max print speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1446 +#: src/libslic3r/PrintConfig.cpp:1535 msgid "" "When setting other speed settings to 0 Slic3r will autocalculate the optimal " "speed in order to keep constant extruder pressure. This experimental setting " "is used to set the highest print speed you want to allow." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1456 +#: src/libslic3r/PrintConfig.cpp:1545 msgid "" "This experimental setting is used to set the maximum volumetric speed your " "extruder supports." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1465 +#: src/libslic3r/PrintConfig.cpp:1554 msgid "Max volumetric slope positive" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1466 src/libslic3r/PrintConfig.cpp:1477 +#: src/libslic3r/PrintConfig.cpp:1555 src/libslic3r/PrintConfig.cpp:1566 msgid "" "This experimental setting is used to limit the speed of change in extrusion " "rate. A value of 1.8 mm³/s² ensures, that a change from the extrusion rate " @@ -9757,95 +9873,95 @@ msgid "" "s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1470 src/libslic3r/PrintConfig.cpp:1481 +#: src/libslic3r/PrintConfig.cpp:1559 src/libslic3r/PrintConfig.cpp:1570 msgid "mm³/s²" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1476 +#: src/libslic3r/PrintConfig.cpp:1565 msgid "Max volumetric slope negative" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1488 src/libslic3r/PrintConfig.cpp:1497 +#: src/libslic3r/PrintConfig.cpp:1577 src/libslic3r/PrintConfig.cpp:1586 msgid "Min" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1489 +#: src/libslic3r/PrintConfig.cpp:1578 msgid "This setting represents the minimum PWM your fan needs to work." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1498 +#: src/libslic3r/PrintConfig.cpp:1587 msgid "" "This is the lowest printable layer height for this extruder and limits the " "resolution for variable layer height. Typical values are between 0.05 mm and " "0.1 mm." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1506 +#: src/libslic3r/PrintConfig.cpp:1595 msgid "Min print speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1507 +#: src/libslic3r/PrintConfig.cpp:1596 msgid "Slic3r will not scale speed down below this speed." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1514 +#: src/libslic3r/PrintConfig.cpp:1603 msgid "Minimal filament extrusion length" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1515 +#: src/libslic3r/PrintConfig.cpp:1604 msgid "" "Generate no less than the number of skirt loops required to consume the " "specified amount of filament on the bottom layer. For multi-extruder " "machines, this minimum applies to each extruder." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1524 +#: src/libslic3r/PrintConfig.cpp:1613 msgid "Configuration notes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1525 +#: src/libslic3r/PrintConfig.cpp:1614 msgid "" "You can put here your personal notes. This text will be added to the G-code " "header comments." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1535 +#: src/libslic3r/PrintConfig.cpp:1624 msgid "" "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1540 +#: src/libslic3r/PrintConfig.cpp:1629 msgid "Host Type" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1541 +#: src/libslic3r/PrintConfig.cpp:1630 msgid "" "Slic3r can upload G-code files to a printer host. This field must contain " "the kind of the host." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1558 +#: src/libslic3r/PrintConfig.cpp:1647 msgid "Only retract when crossing perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1559 +#: src/libslic3r/PrintConfig.cpp:1648 msgid "" "Disables retraction when the travel path does not exceed the upper layer's " "perimeters (and thus any ooze will be probably invisible)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1566 +#: src/libslic3r/PrintConfig.cpp:1655 msgid "" "This option will drop the temperature of the inactive extruders to prevent " "oozing. It will enable a tall skirt automatically and move extruders outside " "such skirt when changing temperatures." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1573 +#: src/libslic3r/PrintConfig.cpp:1662 msgid "Output filename format" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1574 +#: src/libslic3r/PrintConfig.cpp:1663 msgid "" "You can use all configuration options as variables inside this template. For " "example: [layer_height], [fill_density] etc. You can also use [timestamp], " @@ -9853,31 +9969,31 @@ msgid "" "[input_filename], [input_filename_base]." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1583 +#: src/libslic3r/PrintConfig.cpp:1672 msgid "Detect bridging perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1585 +#: src/libslic3r/PrintConfig.cpp:1674 msgid "" "Experimental option to adjust flow for overhangs (bridge flow will be used), " "to apply bridge speed to them and enable fan." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1591 +#: src/libslic3r/PrintConfig.cpp:1680 msgid "Filament parking position" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1592 +#: src/libslic3r/PrintConfig.cpp:1681 msgid "" "Distance of the extruder tip from the position where the filament is parked " "when unloaded. This should match the value in printer firmware." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1600 +#: src/libslic3r/PrintConfig.cpp:1689 msgid "Extra loading distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1601 +#: src/libslic3r/PrintConfig.cpp:1690 msgid "" "When set to zero, the distance the filament is moved from parking position " "during load is exactly the same as it was moved back during unload. When " @@ -9885,27 +10001,27 @@ msgid "" "than unloading." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1609 src/libslic3r/PrintConfig.cpp:1626 -#: src/libslic3r/PrintConfig.cpp:1639 src/libslic3r/PrintConfig.cpp:1649 +#: src/libslic3r/PrintConfig.cpp:1698 src/libslic3r/PrintConfig.cpp:1715 +#: src/libslic3r/PrintConfig.cpp:1728 src/libslic3r/PrintConfig.cpp:1738 msgid "Perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1610 +#: src/libslic3r/PrintConfig.cpp:1699 msgid "" "This is the acceleration your printer will use for perimeters. Set zero to " "disable acceleration control for perimeters." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1617 +#: src/libslic3r/PrintConfig.cpp:1706 msgid "Perimeter extruder" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1619 +#: src/libslic3r/PrintConfig.cpp:1708 msgid "" "The extruder to use when printing perimeters and brim. First extruder is 1." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1628 +#: src/libslic3r/PrintConfig.cpp:1717 msgid "" "Set this to a non-zero value to set a manual extrusion width for perimeters. " "You may want to use thinner extrudates to get more accurate surfaces. If " @@ -9914,12 +10030,12 @@ msgid "" "it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1641 +#: src/libslic3r/PrintConfig.cpp:1730 msgid "" "Speed for perimeters (contours, aka vertical shells). Set to zero for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1651 +#: src/libslic3r/PrintConfig.cpp:1740 msgid "" "This option sets the number of perimeters to generate for each layer. Note " "that Slic3r may increase this number automatically when it detects sloping " @@ -9927,11 +10043,11 @@ msgid "" "Perimeters option is enabled." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1655 +#: src/libslic3r/PrintConfig.cpp:1744 msgid "(minimum)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1663 +#: src/libslic3r/PrintConfig.cpp:1752 msgid "" "If you want to process the output G-code through custom scripts, just list " "their absolute paths here. Separate multiple scripts with a semicolon. " @@ -9940,55 +10056,55 @@ msgid "" "environment variables." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1675 +#: src/libslic3r/PrintConfig.cpp:1764 msgid "Printer type" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1676 +#: src/libslic3r/PrintConfig.cpp:1765 msgid "Type of the printer." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1681 +#: src/libslic3r/PrintConfig.cpp:1770 msgid "Printer notes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1682 +#: src/libslic3r/PrintConfig.cpp:1771 msgid "You can put your notes regarding the printer here." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1690 +#: src/libslic3r/PrintConfig.cpp:1779 msgid "Printer vendor" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1691 +#: src/libslic3r/PrintConfig.cpp:1780 msgid "Name of the printer vendor." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1696 +#: src/libslic3r/PrintConfig.cpp:1785 msgid "Printer variant" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1697 +#: src/libslic3r/PrintConfig.cpp:1786 msgid "" "Name of the printer variant. For example, the printer variants may be " "differentiated by a nozzle diameter." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1714 +#: src/libslic3r/PrintConfig.cpp:1803 msgid "Raft layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1716 +#: src/libslic3r/PrintConfig.cpp:1805 msgid "" "The object will be raised by this number of layers, and support material " "will be generated under it." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1724 +#: src/libslic3r/PrintConfig.cpp:1813 msgid "Resolution" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1725 +#: src/libslic3r/PrintConfig.cpp:1814 msgid "" "Minimum detail resolution, used to simplify the input file for speeding up " "the slicing job and reducing memory usage. High-resolution models often " @@ -9996,277 +10112,277 @@ msgid "" "simplification and use full resolution from input." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1735 +#: src/libslic3r/PrintConfig.cpp:1824 msgid "Minimum travel after retraction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1736 +#: src/libslic3r/PrintConfig.cpp:1825 msgid "" "Retraction is not triggered when travel moves are shorter than this length." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1742 +#: src/libslic3r/PrintConfig.cpp:1831 msgid "Retract amount before wipe" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1743 +#: src/libslic3r/PrintConfig.cpp:1832 msgid "" "With bowden extruders, it may be wise to do some amount of quick retract " "before doing the wipe movement." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1750 +#: src/libslic3r/PrintConfig.cpp:1839 msgid "Retract on layer change" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1751 +#: src/libslic3r/PrintConfig.cpp:1840 msgid "This flag enforces a retraction whenever a Z move is done." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1756 src/libslic3r/PrintConfig.cpp:1764 +#: src/libslic3r/PrintConfig.cpp:1845 src/libslic3r/PrintConfig.cpp:1853 msgid "Length" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1757 +#: src/libslic3r/PrintConfig.cpp:1846 msgid "Retraction Length" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1758 +#: src/libslic3r/PrintConfig.cpp:1847 msgid "" "When retraction is triggered, filament is pulled back by the specified " "amount (the length is measured on raw filament, before it enters the " "extruder)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1760 src/libslic3r/PrintConfig.cpp:1769 +#: src/libslic3r/PrintConfig.cpp:1849 src/libslic3r/PrintConfig.cpp:1858 msgid "mm (zero to disable)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1765 +#: src/libslic3r/PrintConfig.cpp:1854 msgid "Retraction Length (Toolchange)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1766 +#: src/libslic3r/PrintConfig.cpp:1855 msgid "" "When retraction is triggered before changing tool, filament is pulled back " "by the specified amount (the length is measured on raw filament, before it " "enters the extruder)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1774 +#: src/libslic3r/PrintConfig.cpp:1863 msgid "Lift Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1775 +#: src/libslic3r/PrintConfig.cpp:1864 msgid "" "If you set this to a positive value, Z is quickly raised every time a " "retraction is triggered. When using multiple extruders, only the setting for " "the first extruder will be considered." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1782 +#: src/libslic3r/PrintConfig.cpp:1871 msgid "Above Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1783 +#: src/libslic3r/PrintConfig.cpp:1872 msgid "Only lift Z above" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1784 +#: src/libslic3r/PrintConfig.cpp:1873 msgid "" "If you set this to a positive value, Z lift will only take place above the " "specified absolute Z. You can tune this setting for skipping lift on the " "first layers." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1791 +#: src/libslic3r/PrintConfig.cpp:1880 msgid "Below Z" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1792 +#: src/libslic3r/PrintConfig.cpp:1881 msgid "Only lift Z below" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1793 +#: src/libslic3r/PrintConfig.cpp:1882 msgid "" "If you set this to a positive value, Z lift will only take place below the " "specified absolute Z. You can tune this setting for limiting lift to the " "first layers." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1801 src/libslic3r/PrintConfig.cpp:1809 +#: src/libslic3r/PrintConfig.cpp:1890 src/libslic3r/PrintConfig.cpp:1898 msgid "Extra length on restart" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1802 +#: src/libslic3r/PrintConfig.cpp:1891 msgid "" "When the retraction is compensated after the travel move, the extruder will " "push this additional amount of filament. This setting is rarely needed." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1810 +#: src/libslic3r/PrintConfig.cpp:1899 msgid "" "When the retraction is compensated after changing tool, the extruder will " "push this additional amount of filament." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1817 src/libslic3r/PrintConfig.cpp:1818 +#: src/libslic3r/PrintConfig.cpp:1906 src/libslic3r/PrintConfig.cpp:1907 msgid "Retraction Speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1819 +#: src/libslic3r/PrintConfig.cpp:1908 msgid "The speed for retractions (it only applies to the extruder motor)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1825 src/libslic3r/PrintConfig.cpp:1826 +#: src/libslic3r/PrintConfig.cpp:1914 src/libslic3r/PrintConfig.cpp:1915 msgid "Deretraction Speed" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1827 +#: src/libslic3r/PrintConfig.cpp:1916 msgid "" "The speed for loading of a filament into extruder after retraction (it only " "applies to the extruder motor). If left to zero, the retraction speed is " "used." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1834 +#: src/libslic3r/PrintConfig.cpp:1923 msgid "Seam position" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1836 +#: src/libslic3r/PrintConfig.cpp:1925 msgid "Position of perimeters starting points." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1842 +#: src/libslic3r/PrintConfig.cpp:1931 msgid "Random" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1843 +#: src/libslic3r/PrintConfig.cpp:1932 msgid "Nearest" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1844 +#: src/libslic3r/PrintConfig.cpp:1933 msgid "Aligned" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1852 +#: src/libslic3r/PrintConfig.cpp:1941 msgid "Direction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1854 +#: src/libslic3r/PrintConfig.cpp:1943 msgid "Preferred direction of the seam" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1855 +#: src/libslic3r/PrintConfig.cpp:1944 msgid "Seam preferred direction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1862 +#: src/libslic3r/PrintConfig.cpp:1951 msgid "Jitter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1864 +#: src/libslic3r/PrintConfig.cpp:1953 msgid "Seam preferred direction jitter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1865 +#: src/libslic3r/PrintConfig.cpp:1954 msgid "Preferred direction of the seam - jitter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1872 +#: src/libslic3r/PrintConfig.cpp:1961 msgid "Distance from object" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1873 +#: src/libslic3r/PrintConfig.cpp:1962 msgid "" "Distance between skirt and object(s). Set this to zero to attach the skirt " "to the object(s) and get a brim for better adhesion." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1880 +#: src/libslic3r/PrintConfig.cpp:1969 msgid "Skirt height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1881 +#: src/libslic3r/PrintConfig.cpp:1970 msgid "" "Height of skirt expressed in layers. Set this to a tall value to use skirt " "as a shield against drafts." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1888 +#: src/libslic3r/PrintConfig.cpp:1977 msgid "Draft shield" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1889 +#: src/libslic3r/PrintConfig.cpp:1978 msgid "" "If enabled, the skirt will be as tall as a highest printed object. This is " "useful to protect an ABS or ASA print from warping and detaching from print " "bed due to wind draft." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1895 +#: src/libslic3r/PrintConfig.cpp:1984 msgid "Loops (minimum)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1896 +#: src/libslic3r/PrintConfig.cpp:1985 msgid "Skirt Loops" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1897 +#: src/libslic3r/PrintConfig.cpp:1986 msgid "" "Number of loops for the skirt. If the Minimum Extrusion Length option is " "set, the number of loops might be greater than the one configured here. Set " "this to zero to disable skirt completely." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1905 +#: src/libslic3r/PrintConfig.cpp:1994 msgid "Slow down if layer print time is below" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1906 +#: src/libslic3r/PrintConfig.cpp:1995 msgid "" "If layer print time is estimated below this number of seconds, print moves " "speed will be scaled down to extend duration to this value." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1915 +#: src/libslic3r/PrintConfig.cpp:2004 msgid "Small perimeters" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1917 +#: src/libslic3r/PrintConfig.cpp:2006 msgid "" "This separate setting will affect the speed of perimeters having radius <= " "6.5mm (usually holes). If expressed as percentage (for example: 80%) it will " "be calculated on the perimeters speed setting above. Set to zero for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1927 +#: src/libslic3r/PrintConfig.cpp:2016 msgid "Solid infill threshold area" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1929 +#: src/libslic3r/PrintConfig.cpp:2018 msgid "" "Force solid infill for regions having a smaller area than the specified " "threshold." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1930 +#: src/libslic3r/PrintConfig.cpp:2019 msgid "mm²" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1936 +#: src/libslic3r/PrintConfig.cpp:2025 msgid "Solid infill extruder" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1938 +#: src/libslic3r/PrintConfig.cpp:2027 msgid "The extruder to use when printing solid infill." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1944 +#: src/libslic3r/PrintConfig.cpp:2033 msgid "Solid infill every" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1946 +#: src/libslic3r/PrintConfig.cpp:2035 msgid "" "This feature allows to force a solid layer every given number of layers. " "Zero to disable. You can set this to any value (for example 9999); Slic3r " @@ -10274,7 +10390,7 @@ msgid "" "according to nozzle diameter and layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1958 +#: src/libslic3r/PrintConfig.cpp:2047 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill for " "solid surfaces. If left zero, default extrusion width will be used if set, " @@ -10282,26 +10398,26 @@ msgid "" "(for example 90%) it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1969 +#: src/libslic3r/PrintConfig.cpp:2058 msgid "" "Speed for printing solid regions (top/bottom/internal horizontal shells). " "This can be expressed as a percentage (for example: 80%) over the default " "infill speed above. Set to zero for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1981 +#: src/libslic3r/PrintConfig.cpp:2070 msgid "Number of solid layers to generate on top and bottom surfaces." msgstr "" -#: src/libslic3r/PrintConfig.cpp:1987 src/libslic3r/PrintConfig.cpp:1988 +#: src/libslic3r/PrintConfig.cpp:2076 src/libslic3r/PrintConfig.cpp:2077 msgid "Minimum thickness of a top / bottom shell" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1994 +#: src/libslic3r/PrintConfig.cpp:2083 msgid "Spiral vase" msgstr "" -#: src/libslic3r/PrintConfig.cpp:1995 +#: src/libslic3r/PrintConfig.cpp:2084 msgid "" "This feature will raise Z gradually while printing a single-walled object in " "order to remove any visible seam. This option requires a single perimeter, " @@ -10310,18 +10426,18 @@ msgid "" "when printing more than one single object." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2003 +#: src/libslic3r/PrintConfig.cpp:2092 msgid "Temperature variation" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2004 +#: src/libslic3r/PrintConfig.cpp:2093 msgid "" "Temperature difference to be applied when an extruder is not active. Enables " "a full-height \"sacrificial\" skirt on which the nozzles are periodically " "wiped." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2014 +#: src/libslic3r/PrintConfig.cpp:2103 msgid "" "This start procedure is inserted at the beginning, after bed has reached the " "target temperature and extruder just started heating, and before extruder " @@ -10332,7 +10448,7 @@ msgid "" "put a \"M109 S[first_layer_temperature]\" command wherever you want." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2029 +#: src/libslic3r/PrintConfig.cpp:2118 msgid "" "This start procedure is inserted at the beginning, after any printer start " "gcode (and after any toolchange to this filament in case of multi-material " @@ -10345,45 +10461,45 @@ msgid "" "extruders, the gcode is processed in extruder order." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2045 +#: src/libslic3r/PrintConfig.cpp:2134 msgid "Color change G-code" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2046 +#: src/libslic3r/PrintConfig.cpp:2135 msgid "This G-code will be used as a code for the color change" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2055 +#: src/libslic3r/PrintConfig.cpp:2144 msgid "This G-code will be used as a code for the pause print" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2064 +#: src/libslic3r/PrintConfig.cpp:2153 msgid "This G-code will be used as a custom code" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2072 +#: src/libslic3r/PrintConfig.cpp:2161 msgid "Single Extruder Multi Material" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2073 +#: src/libslic3r/PrintConfig.cpp:2162 msgid "The printer multiplexes filaments into a single hot end." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2078 +#: src/libslic3r/PrintConfig.cpp:2167 msgid "Prime all printing extruders" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2079 +#: src/libslic3r/PrintConfig.cpp:2168 msgid "" "If enabled, all printing extruders will be primed at the front edge of the " "print bed at the start of the print." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2084 +#: src/libslic3r/PrintConfig.cpp:2173 msgid "No sparse layers (EXPERIMENTAL)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2085 +#: src/libslic3r/PrintConfig.cpp:2174 msgid "" "If enabled, the wipe tower will not be printed on layers with no " "toolchanges. On layers with a toolchange, extruder will travel downward to " @@ -10391,75 +10507,75 @@ msgid "" "with the print." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2092 +#: src/libslic3r/PrintConfig.cpp:2181 msgid "Generate support material" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2094 +#: src/libslic3r/PrintConfig.cpp:2183 msgid "Enable support material generation." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2098 +#: src/libslic3r/PrintConfig.cpp:2187 msgid "Auto generated supports" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2100 +#: src/libslic3r/PrintConfig.cpp:2189 msgid "" "If checked, supports will be generated automatically based on the overhang " "threshold value. If unchecked, supports will be generated inside the " "\"Support Enforcer\" volumes only." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2106 +#: src/libslic3r/PrintConfig.cpp:2195 msgid "XY separation between an object and its support" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2108 +#: src/libslic3r/PrintConfig.cpp:2197 msgid "" "XY separation between an object and its support. If expressed as percentage " "(for example 50%), it will be calculated over external perimeter width." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2118 +#: src/libslic3r/PrintConfig.cpp:2207 msgid "Pattern angle" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2120 +#: src/libslic3r/PrintConfig.cpp:2209 msgid "" "Use this setting to rotate the support material pattern on the horizontal " "plane." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2130 src/libslic3r/PrintConfig.cpp:2925 +#: src/libslic3r/PrintConfig.cpp:2219 src/libslic3r/PrintConfig.cpp:3014 msgid "" "Only create support if it lies on a build plate. Don't create support on a " "print." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2136 +#: src/libslic3r/PrintConfig.cpp:2225 msgid "Contact Z distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2138 +#: src/libslic3r/PrintConfig.cpp:2227 msgid "" "The vertical distance between object and support material interface. Setting " "this to 0 will also prevent Slic3r from using bridge flow and speed for the " "first object layer." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2145 +#: src/libslic3r/PrintConfig.cpp:2234 msgid "0 (soluble)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2146 +#: src/libslic3r/PrintConfig.cpp:2235 msgid "0.2 (detachable)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2151 +#: src/libslic3r/PrintConfig.cpp:2240 msgid "Enforce support for the first" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2153 +#: src/libslic3r/PrintConfig.cpp:2242 msgid "" "Generate support material for the specified number of layers counting from " "bottom, regardless of whether normal support material is enabled or not and " @@ -10467,21 +10583,21 @@ msgid "" "of objects having a very thin or poor footprint on the build plate." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2158 +#: src/libslic3r/PrintConfig.cpp:2247 msgid "Enforce support for the first n layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2164 +#: src/libslic3r/PrintConfig.cpp:2253 msgid "Support material/raft/skirt extruder" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2166 +#: src/libslic3r/PrintConfig.cpp:2255 msgid "" "The extruder to use when printing support material, raft and skirt (1+, 0 to " "use the current extruder to minimize tool changes)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2175 +#: src/libslic3r/PrintConfig.cpp:2264 msgid "" "Set this to a non-zero value to set a manual extrusion width for support " "material. If left zero, default extrusion width will be used if set, " @@ -10489,89 +10605,89 @@ msgid "" "example 90%) it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2184 +#: src/libslic3r/PrintConfig.cpp:2273 msgid "Interface loops" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2186 +#: src/libslic3r/PrintConfig.cpp:2275 msgid "" "Cover the top contact layer of the supports with loops. Disabled by default." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2191 +#: src/libslic3r/PrintConfig.cpp:2280 msgid "Support material/raft interface extruder" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2193 +#: src/libslic3r/PrintConfig.cpp:2282 msgid "" "The extruder to use when printing support material interface (1+, 0 to use " "the current extruder to minimize tool changes). This affects raft too." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2200 +#: src/libslic3r/PrintConfig.cpp:2289 msgid "Interface layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2202 +#: src/libslic3r/PrintConfig.cpp:2291 msgid "" "Number of interface layers to insert between the object(s) and support " "material." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2209 +#: src/libslic3r/PrintConfig.cpp:2298 msgid "Interface pattern spacing" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2211 +#: src/libslic3r/PrintConfig.cpp:2300 msgid "Spacing between interface lines. Set zero to get a solid interface." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2220 +#: src/libslic3r/PrintConfig.cpp:2309 msgid "" "Speed for printing support material interface layers. If expressed as " "percentage (for example 50%) it will be calculated over support material " "speed." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2229 +#: src/libslic3r/PrintConfig.cpp:2318 msgid "Pattern" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2231 +#: src/libslic3r/PrintConfig.cpp:2320 msgid "Pattern used to generate support material." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2237 +#: src/libslic3r/PrintConfig.cpp:2326 msgid "Rectilinear grid" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2243 +#: src/libslic3r/PrintConfig.cpp:2332 msgid "Pattern spacing" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2245 +#: src/libslic3r/PrintConfig.cpp:2334 msgid "Spacing between support material lines." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2254 +#: src/libslic3r/PrintConfig.cpp:2343 msgid "Speed for printing support material." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2261 +#: src/libslic3r/PrintConfig.cpp:2350 msgid "Synchronize with object layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2263 +#: src/libslic3r/PrintConfig.cpp:2352 msgid "" "Synchronize support layers with the object print layers. This is useful with " "multi-material printers, where the extruder switch is expensive." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2269 +#: src/libslic3r/PrintConfig.cpp:2358 msgid "Overhang threshold" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2271 +#: src/libslic3r/PrintConfig.cpp:2360 msgid "" "Support material will not be generated for overhangs whose slope angle (90° " "= vertical) is above the given threshold. In other words, this value " @@ -10580,47 +10696,47 @@ msgid "" "detection (recommended)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2283 +#: src/libslic3r/PrintConfig.cpp:2372 msgid "With sheath around the support" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2285 +#: src/libslic3r/PrintConfig.cpp:2374 msgid "" "Add a sheath (a single perimeter line) around the base support. This makes " "the support more reliable, but also more difficult to remove." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2292 +#: src/libslic3r/PrintConfig.cpp:2381 msgid "" "Nozzle temperature for layers after the first one. Set this to zero to " "disable temperature control commands in the output G-code." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2295 +#: src/libslic3r/PrintConfig.cpp:2384 msgid "Nozzle temperature" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2301 +#: src/libslic3r/PrintConfig.cpp:2390 msgid "Detect thin walls" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2303 +#: src/libslic3r/PrintConfig.cpp:2392 msgid "" "Detect single-width walls (parts where two extrusions don't fit and we need " "to collapse them into a single trace)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2309 +#: src/libslic3r/PrintConfig.cpp:2398 msgid "Threads" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2310 +#: src/libslic3r/PrintConfig.cpp:2399 msgid "" "Threads are used to parallelize long-running tasks. Optimal threads number " "is slightly above the number of available cores/processors." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2322 +#: src/libslic3r/PrintConfig.cpp:2411 msgid "" "This custom code is inserted before every toolchange. Placeholder variables " "for all PrusaSlicer settings as well as {previous_extruder} and " @@ -10630,7 +10746,7 @@ msgid "" "behaviour both before and after the toolchange." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2335 +#: src/libslic3r/PrintConfig.cpp:2424 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill for " "top surfaces. You may want to use thinner extrudates to fill all narrow " @@ -10639,7 +10755,7 @@ msgid "" "percentage (for example 90%) it will be computed over layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2347 +#: src/libslic3r/PrintConfig.cpp:2436 msgid "" "Speed for printing top solid layers (it only applies to the uppermost " "external layers and not to their internal solid layers). You may want to " @@ -10648,54 +10764,54 @@ msgid "" "for auto." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2362 +#: src/libslic3r/PrintConfig.cpp:2451 msgid "Number of solid layers to generate on top surfaces." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2363 +#: src/libslic3r/PrintConfig.cpp:2452 msgid "Top solid layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2371 +#: src/libslic3r/PrintConfig.cpp:2460 msgid "" "The number of top solid layers is increased above top_solid_layers if " "necessary to satisfy minimum thickness of top shell. This is useful to " "prevent pillowing effect when printing with variable layer height." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2374 +#: src/libslic3r/PrintConfig.cpp:2463 msgid "Minimum top shell thickness" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2381 +#: src/libslic3r/PrintConfig.cpp:2470 msgid "Speed for travel moves (jumps between distant extrusion points)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2389 +#: src/libslic3r/PrintConfig.cpp:2478 msgid "Use firmware retraction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2390 +#: src/libslic3r/PrintConfig.cpp:2479 msgid "" "This experimental setting uses G10 and G11 commands to have the firmware " "handle the retraction. This is only supported in recent Marlin." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2396 +#: src/libslic3r/PrintConfig.cpp:2485 msgid "Use relative E distances" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2397 +#: src/libslic3r/PrintConfig.cpp:2486 msgid "" "If your firmware requires relative E values, check this, otherwise leave it " "unchecked. Most firmwares use absolute values." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2403 +#: src/libslic3r/PrintConfig.cpp:2492 msgid "Use volumetric E" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2404 +#: src/libslic3r/PrintConfig.cpp:2493 msgid "" "This experimental setting uses outputs the E values in cubic millimeters " "instead of linear millimeters. If your firmware doesn't already know " @@ -10705,127 +10821,127 @@ msgid "" "only supported in recent Marlin." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2414 +#: src/libslic3r/PrintConfig.cpp:2503 msgid "Enable variable layer height feature" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2415 +#: src/libslic3r/PrintConfig.cpp:2504 msgid "" "Some printers or printer setups may have difficulties printing with a " "variable layer height. Enabled by default." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2421 +#: src/libslic3r/PrintConfig.cpp:2510 msgid "Wipe while retracting" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2422 +#: src/libslic3r/PrintConfig.cpp:2511 msgid "" "This flag will move the nozzle while retracting to minimize the possible " "blob on leaky extruders." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2429 +#: src/libslic3r/PrintConfig.cpp:2518 msgid "" "Multi material printers may need to prime or purge extruders on tool " "changes. Extrude the excess material into the wipe tower." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2435 +#: src/libslic3r/PrintConfig.cpp:2524 msgid "Purging volumes - load/unload volumes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2436 +#: src/libslic3r/PrintConfig.cpp:2525 msgid "" "This vector saves required volumes to change from/to each tool used on the " "wipe tower. These values are used to simplify creation of the full purging " "volumes below." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2442 +#: src/libslic3r/PrintConfig.cpp:2531 msgid "Purging volumes - matrix" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2443 +#: src/libslic3r/PrintConfig.cpp:2532 msgid "" "This matrix describes volumes (in cubic milimetres) required to purge the " "new filament on the wipe tower for any given pair of tools." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2452 +#: src/libslic3r/PrintConfig.cpp:2541 msgid "Position X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2453 +#: src/libslic3r/PrintConfig.cpp:2542 msgid "X coordinate of the left front corner of a wipe tower" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2459 +#: src/libslic3r/PrintConfig.cpp:2548 msgid "Position Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2460 +#: src/libslic3r/PrintConfig.cpp:2549 msgid "Y coordinate of the left front corner of a wipe tower" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2467 +#: src/libslic3r/PrintConfig.cpp:2556 msgid "Width of a wipe tower" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2473 +#: src/libslic3r/PrintConfig.cpp:2562 msgid "Wipe tower rotation angle" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2474 +#: src/libslic3r/PrintConfig.cpp:2563 msgid "Wipe tower rotation angle with respect to x-axis." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2481 +#: src/libslic3r/PrintConfig.cpp:2570 msgid "Wipe into this object's infill" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2482 +#: src/libslic3r/PrintConfig.cpp:2571 msgid "" "Purging after toolchange will done inside this object's infills. This lowers " "the amount of waste but may result in longer print time due to additional " "travel moves." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2489 +#: src/libslic3r/PrintConfig.cpp:2578 msgid "Wipe into this object" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2490 +#: src/libslic3r/PrintConfig.cpp:2579 msgid "" "Object will be used to purge the nozzle after a toolchange to save material " "that would otherwise end up in the wipe tower and decrease print time. " "Colours of the objects will be mixed as a result." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2496 +#: src/libslic3r/PrintConfig.cpp:2585 msgid "Maximal bridging distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2497 +#: src/libslic3r/PrintConfig.cpp:2586 msgid "Maximal distance between supports on sparse infill sections." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2503 +#: src/libslic3r/PrintConfig.cpp:2592 msgid "XY Size Compensation" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2505 +#: src/libslic3r/PrintConfig.cpp:2594 msgid "" "The object will be grown/shrunk in the XY plane by the configured value " "(negative = inwards, positive = outwards). This might be useful for fine-" "tuning hole sizes." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2513 +#: src/libslic3r/PrintConfig.cpp:2602 msgid "Z offset" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2514 +#: src/libslic3r/PrintConfig.cpp:2603 msgid "" "This value will be added (or subtracted) from all the Z coordinates in the " "output G-code. It is used to compensate for bad Z endstop position: for " @@ -10833,414 +10949,414 @@ msgid "" "print bed, set this to -0.3 (or fix your endstop)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2581 +#: src/libslic3r/PrintConfig.cpp:2670 msgid "Display width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2582 +#: src/libslic3r/PrintConfig.cpp:2671 msgid "Width of the display" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2587 +#: src/libslic3r/PrintConfig.cpp:2676 msgid "Display height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2588 +#: src/libslic3r/PrintConfig.cpp:2677 msgid "Height of the display" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2593 +#: src/libslic3r/PrintConfig.cpp:2682 msgid "Number of pixels in" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2595 +#: src/libslic3r/PrintConfig.cpp:2684 msgid "Number of pixels in X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2601 +#: src/libslic3r/PrintConfig.cpp:2690 msgid "Number of pixels in Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2606 +#: src/libslic3r/PrintConfig.cpp:2695 msgid "Display horizontal mirroring" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2607 +#: src/libslic3r/PrintConfig.cpp:2696 msgid "Mirror horizontally" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2608 +#: src/libslic3r/PrintConfig.cpp:2697 msgid "Enable horizontal mirroring of output images" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2613 +#: src/libslic3r/PrintConfig.cpp:2702 msgid "Display vertical mirroring" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2614 +#: src/libslic3r/PrintConfig.cpp:2703 msgid "Mirror vertically" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2615 +#: src/libslic3r/PrintConfig.cpp:2704 msgid "Enable vertical mirroring of output images" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2620 +#: src/libslic3r/PrintConfig.cpp:2709 msgid "Display orientation" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2621 +#: src/libslic3r/PrintConfig.cpp:2710 msgid "" "Set the actual LCD display orientation inside the SLA printer. Portrait mode " "will flip the meaning of display width and height parameters and the output " "images will be rotated by 90 degrees." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2627 +#: src/libslic3r/PrintConfig.cpp:2716 msgid "Landscape" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2628 +#: src/libslic3r/PrintConfig.cpp:2717 msgid "Portrait" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2633 +#: src/libslic3r/PrintConfig.cpp:2722 msgid "Fast" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2634 +#: src/libslic3r/PrintConfig.cpp:2723 msgid "Fast tilt" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2635 +#: src/libslic3r/PrintConfig.cpp:2724 msgid "Time of the fast tilt" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2642 +#: src/libslic3r/PrintConfig.cpp:2731 msgid "Slow" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2643 +#: src/libslic3r/PrintConfig.cpp:2732 msgid "Slow tilt" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2644 +#: src/libslic3r/PrintConfig.cpp:2733 msgid "Time of the slow tilt" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2651 +#: src/libslic3r/PrintConfig.cpp:2740 msgid "Area fill" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2652 +#: src/libslic3r/PrintConfig.cpp:2741 msgid "" "The percentage of the bed area. \n" "If the print area exceeds the specified value, \n" "then a slow tilt will be used, otherwise - a fast tilt" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2659 src/libslic3r/PrintConfig.cpp:2660 -#: src/libslic3r/PrintConfig.cpp:2661 +#: src/libslic3r/PrintConfig.cpp:2748 src/libslic3r/PrintConfig.cpp:2749 +#: src/libslic3r/PrintConfig.cpp:2750 msgid "Printer scaling correction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2667 src/libslic3r/PrintConfig.cpp:2668 +#: src/libslic3r/PrintConfig.cpp:2756 src/libslic3r/PrintConfig.cpp:2757 msgid "Printer absolute correction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2669 +#: src/libslic3r/PrintConfig.cpp:2758 msgid "" "Will inflate or deflate the sliced 2D polygons according to the sign of the " "correction." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2675 +#: src/libslic3r/PrintConfig.cpp:2764 msgid "Elephant foot minimum width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2677 +#: src/libslic3r/PrintConfig.cpp:2766 msgid "" "Minimum width of features to maintain when doing elephant foot compensation." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2684 src/libslic3r/PrintConfig.cpp:2685 +#: src/libslic3r/PrintConfig.cpp:2773 src/libslic3r/PrintConfig.cpp:2774 msgid "Printer gamma correction" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2686 +#: src/libslic3r/PrintConfig.cpp:2775 msgid "" "This will apply a gamma correction to the rasterized 2D polygons. A gamma " "value of zero means thresholding with the threshold in the middle. This " "behaviour eliminates antialiasing without losing holes in polygons." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2698 src/libslic3r/PrintConfig.cpp:2699 +#: src/libslic3r/PrintConfig.cpp:2787 src/libslic3r/PrintConfig.cpp:2788 msgid "SLA material type" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2710 src/libslic3r/PrintConfig.cpp:2711 +#: src/libslic3r/PrintConfig.cpp:2799 src/libslic3r/PrintConfig.cpp:2800 msgid "Initial layer height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2717 src/libslic3r/PrintConfig.cpp:2718 +#: src/libslic3r/PrintConfig.cpp:2806 src/libslic3r/PrintConfig.cpp:2807 msgid "Bottle volume" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2719 +#: src/libslic3r/PrintConfig.cpp:2808 msgid "ml" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2724 src/libslic3r/PrintConfig.cpp:2725 +#: src/libslic3r/PrintConfig.cpp:2813 src/libslic3r/PrintConfig.cpp:2814 msgid "Bottle weight" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2726 +#: src/libslic3r/PrintConfig.cpp:2815 msgid "kg" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2733 +#: src/libslic3r/PrintConfig.cpp:2822 msgid "g/ml" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2740 +#: src/libslic3r/PrintConfig.cpp:2829 msgid "money/bottle" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2745 +#: src/libslic3r/PrintConfig.cpp:2834 msgid "Faded layers" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2746 +#: src/libslic3r/PrintConfig.cpp:2835 msgid "" "Number of the layers needed for the exposure time fade from initial exposure " "time to the exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2753 src/libslic3r/PrintConfig.cpp:2754 +#: src/libslic3r/PrintConfig.cpp:2842 src/libslic3r/PrintConfig.cpp:2843 msgid "Minimum exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2761 src/libslic3r/PrintConfig.cpp:2762 +#: src/libslic3r/PrintConfig.cpp:2850 src/libslic3r/PrintConfig.cpp:2851 msgid "Maximum exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2769 src/libslic3r/PrintConfig.cpp:2770 +#: src/libslic3r/PrintConfig.cpp:2858 src/libslic3r/PrintConfig.cpp:2859 msgid "Exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2776 src/libslic3r/PrintConfig.cpp:2777 +#: src/libslic3r/PrintConfig.cpp:2865 src/libslic3r/PrintConfig.cpp:2866 msgid "Minimum initial exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2784 src/libslic3r/PrintConfig.cpp:2785 +#: src/libslic3r/PrintConfig.cpp:2873 src/libslic3r/PrintConfig.cpp:2874 msgid "Maximum initial exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2792 src/libslic3r/PrintConfig.cpp:2793 +#: src/libslic3r/PrintConfig.cpp:2881 src/libslic3r/PrintConfig.cpp:2882 msgid "Initial exposure time" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2799 src/libslic3r/PrintConfig.cpp:2800 +#: src/libslic3r/PrintConfig.cpp:2888 src/libslic3r/PrintConfig.cpp:2889 msgid "Correction for expansion" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2806 +#: src/libslic3r/PrintConfig.cpp:2895 msgid "SLA print material notes" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2807 +#: src/libslic3r/PrintConfig.cpp:2896 msgid "You can put your notes regarding the SLA print material here." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2819 src/libslic3r/PrintConfig.cpp:2830 +#: src/libslic3r/PrintConfig.cpp:2908 src/libslic3r/PrintConfig.cpp:2919 msgid "Default SLA material profile" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2841 +#: src/libslic3r/PrintConfig.cpp:2930 msgid "Generate supports" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2843 +#: src/libslic3r/PrintConfig.cpp:2932 msgid "Generate supports for the models" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2848 +#: src/libslic3r/PrintConfig.cpp:2937 msgid "Pinhead front diameter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2850 +#: src/libslic3r/PrintConfig.cpp:2939 msgid "Diameter of the pointing side of the head" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2857 +#: src/libslic3r/PrintConfig.cpp:2946 msgid "Head penetration" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2859 +#: src/libslic3r/PrintConfig.cpp:2948 msgid "How much the pinhead has to penetrate the model surface" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2866 +#: src/libslic3r/PrintConfig.cpp:2955 msgid "Pinhead width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2868 +#: src/libslic3r/PrintConfig.cpp:2957 msgid "Width from the back sphere center to the front sphere center" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2876 +#: src/libslic3r/PrintConfig.cpp:2965 msgid "Pillar diameter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2878 +#: src/libslic3r/PrintConfig.cpp:2967 msgid "Diameter in mm of the support pillars" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2886 +#: src/libslic3r/PrintConfig.cpp:2975 msgid "Small pillar diameter percent" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2888 +#: src/libslic3r/PrintConfig.cpp:2977 msgid "" "The percentage of smaller pillars compared to the normal pillar diameter " "which are used in problematic areas where a normal pilla cannot fit." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2897 +#: src/libslic3r/PrintConfig.cpp:2986 msgid "Max bridges on a pillar" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2899 +#: src/libslic3r/PrintConfig.cpp:2988 msgid "" "Maximum number of bridges that can be placed on a pillar. Bridges hold " "support point pinheads and connect to pillars as small branches." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2907 +#: src/libslic3r/PrintConfig.cpp:2996 msgid "Pillar connection mode" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2908 +#: src/libslic3r/PrintConfig.cpp:2997 msgid "" "Controls the bridge type between two neighboring pillars. Can be zig-zag, " "cross (double zig-zag) or dynamic which will automatically switch between " "the first two depending on the distance of the two pillars." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2916 +#: src/libslic3r/PrintConfig.cpp:3005 msgid "Zig-Zag" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2917 +#: src/libslic3r/PrintConfig.cpp:3006 msgid "Cross" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2918 +#: src/libslic3r/PrintConfig.cpp:3007 msgid "Dynamic" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2930 +#: src/libslic3r/PrintConfig.cpp:3019 msgid "Pillar widening factor" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2932 +#: src/libslic3r/PrintConfig.cpp:3021 msgid "" "Merging bridges or pillars into another pillars can increase the radius. " "Zero means no increase, one means full increase." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2941 +#: src/libslic3r/PrintConfig.cpp:3030 msgid "Support base diameter" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2943 +#: src/libslic3r/PrintConfig.cpp:3032 msgid "Diameter in mm of the pillar base" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2951 +#: src/libslic3r/PrintConfig.cpp:3040 msgid "Support base height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2953 +#: src/libslic3r/PrintConfig.cpp:3042 msgid "The height of the pillar base cone" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2960 +#: src/libslic3r/PrintConfig.cpp:3049 msgid "Support base safety distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2963 +#: src/libslic3r/PrintConfig.cpp:3052 msgid "" "The minimum distance of the pillar base from the model in mm. Makes sense in " "zero elevation mode where a gap according to this parameter is inserted " "between the model and the pad." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2973 +#: src/libslic3r/PrintConfig.cpp:3062 msgid "Critical angle" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2975 +#: src/libslic3r/PrintConfig.cpp:3064 msgid "The default angle for connecting support sticks and junctions." msgstr "" -#: src/libslic3r/PrintConfig.cpp:2983 +#: src/libslic3r/PrintConfig.cpp:3072 msgid "Max bridge length" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2985 +#: src/libslic3r/PrintConfig.cpp:3074 msgid "The max length of a bridge" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2992 +#: src/libslic3r/PrintConfig.cpp:3081 msgid "Max pillar linking distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:2994 +#: src/libslic3r/PrintConfig.cpp:3083 msgid "" "The max distance of two pillars to get linked with each other. A zero value " "will prohibit pillar cascading." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3004 +#: src/libslic3r/PrintConfig.cpp:3093 msgid "" "How much the supports should lift up the supported object. If \"Pad around " "object\" is enabled, this value is ignored." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3015 +#: src/libslic3r/PrintConfig.cpp:3104 msgid "This is a relative measure of support points density." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3021 +#: src/libslic3r/PrintConfig.cpp:3110 msgid "Minimal distance of the support points" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3023 +#: src/libslic3r/PrintConfig.cpp:3112 msgid "No support points will be placed closer than this threshold." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3029 +#: src/libslic3r/PrintConfig.cpp:3118 msgid "Use pad" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3031 +#: src/libslic3r/PrintConfig.cpp:3120 msgid "Add a pad underneath the supported model" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3036 +#: src/libslic3r/PrintConfig.cpp:3125 msgid "Pad wall thickness" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3038 +#: src/libslic3r/PrintConfig.cpp:3127 msgid "The thickness of the pad and its optional cavity walls." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3046 +#: src/libslic3r/PrintConfig.cpp:3135 msgid "Pad wall height" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3047 +#: src/libslic3r/PrintConfig.cpp:3136 msgid "" "Defines the pad cavity depth. Set to zero to disable the cavity. Be careful " "when enabling this feature, as some resins may produce an extreme suction " @@ -11248,111 +11364,111 @@ msgid "" "difficult." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3060 +#: src/libslic3r/PrintConfig.cpp:3149 msgid "Pad brim size" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3061 +#: src/libslic3r/PrintConfig.cpp:3150 msgid "How far should the pad extend around the contained geometry" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3071 +#: src/libslic3r/PrintConfig.cpp:3160 msgid "Max merge distance" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3073 +#: src/libslic3r/PrintConfig.cpp:3162 msgid "" "Some objects can get along with a few smaller pads instead of a single big " "one. This parameter defines how far the center of two smaller pads should " "be. If theyare closer, they will get merged into one pad." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3093 +#: src/libslic3r/PrintConfig.cpp:3182 msgid "Pad wall slope" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3095 +#: src/libslic3r/PrintConfig.cpp:3184 msgid "" "The slope of the pad wall relative to the bed plane. 90 degrees means " "straight walls." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3106 +#: src/libslic3r/PrintConfig.cpp:3195 msgid "Create pad around object and ignore the support elevation" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3111 +#: src/libslic3r/PrintConfig.cpp:3200 msgid "Pad around object everywhere" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3113 +#: src/libslic3r/PrintConfig.cpp:3202 msgid "Force pad around object everywhere" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3118 +#: src/libslic3r/PrintConfig.cpp:3207 msgid "Pad object gap" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3120 +#: src/libslic3r/PrintConfig.cpp:3209 msgid "" "The gap between the object bottom and the generated pad in zero elevation " "mode." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3129 +#: src/libslic3r/PrintConfig.cpp:3218 msgid "Pad object connector stride" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3131 +#: src/libslic3r/PrintConfig.cpp:3220 msgid "" "Distance between two connector sticks which connect the object and the " "generated pad." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3138 +#: src/libslic3r/PrintConfig.cpp:3227 msgid "Pad object connector width" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3140 +#: src/libslic3r/PrintConfig.cpp:3229 msgid "" "Width of the connector sticks which connect the object and the generated pad." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3147 +#: src/libslic3r/PrintConfig.cpp:3236 msgid "Pad object connector penetration" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3150 +#: src/libslic3r/PrintConfig.cpp:3239 msgid "How much should the tiny connectors penetrate into the model body." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3157 +#: src/libslic3r/PrintConfig.cpp:3246 msgid "Enable hollowing" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3159 +#: src/libslic3r/PrintConfig.cpp:3248 msgid "Hollow out a model to have an empty interior" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3164 +#: src/libslic3r/PrintConfig.cpp:3253 msgid "Wall thickness" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3166 +#: src/libslic3r/PrintConfig.cpp:3255 msgid "Minimum wall thickness of a hollowed model." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3174 +#: src/libslic3r/PrintConfig.cpp:3263 msgid "Accuracy" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3176 +#: src/libslic3r/PrintConfig.cpp:3265 msgid "" "Performance vs accuracy of calculation. Lower values may produce unwanted " "artifacts." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3186 +#: src/libslic3r/PrintConfig.cpp:3275 msgid "" "Hollowing is done in two steps: first, an imaginary interior is calculated " "deeper (offset plus the closing distance) in the object and then it's " @@ -11361,270 +11477,270 @@ msgid "" "most." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3602 +#: src/libslic3r/PrintConfig.cpp:3683 msgid "Export OBJ" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3603 +#: src/libslic3r/PrintConfig.cpp:3684 msgid "Export the model(s) as OBJ." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3614 +#: src/libslic3r/PrintConfig.cpp:3695 msgid "Export SLA" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3615 +#: src/libslic3r/PrintConfig.cpp:3696 msgid "Slice the model and export SLA printing layers as PNG." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3620 +#: src/libslic3r/PrintConfig.cpp:3701 msgid "Export 3MF" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3621 +#: src/libslic3r/PrintConfig.cpp:3702 msgid "Export the model(s) as 3MF." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3625 +#: src/libslic3r/PrintConfig.cpp:3706 msgid "Export AMF" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3626 +#: src/libslic3r/PrintConfig.cpp:3707 msgid "Export the model(s) as AMF." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3630 +#: src/libslic3r/PrintConfig.cpp:3711 msgid "Export STL" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3631 +#: src/libslic3r/PrintConfig.cpp:3712 msgid "Export the model(s) as STL." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3636 +#: src/libslic3r/PrintConfig.cpp:3717 msgid "Slice the model and export toolpaths as G-code." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3641 +#: src/libslic3r/PrintConfig.cpp:3722 msgid "G-code viewer" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3642 +#: src/libslic3r/PrintConfig.cpp:3723 msgid "Visualize an already sliced and saved G-code" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3647 +#: src/libslic3r/PrintConfig.cpp:3728 msgid "Slice" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3648 +#: src/libslic3r/PrintConfig.cpp:3729 msgid "" "Slice the model as FFF or SLA based on the printer_technology configuration " "value." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3653 +#: src/libslic3r/PrintConfig.cpp:3734 msgid "Help" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3654 +#: src/libslic3r/PrintConfig.cpp:3735 msgid "Show this help." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3659 +#: src/libslic3r/PrintConfig.cpp:3740 msgid "Help (FFF options)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3660 +#: src/libslic3r/PrintConfig.cpp:3741 msgid "Show the full list of print/G-code configuration options." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3664 +#: src/libslic3r/PrintConfig.cpp:3745 msgid "Help (SLA options)" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3665 +#: src/libslic3r/PrintConfig.cpp:3746 msgid "Show the full list of SLA print configuration options." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3669 +#: src/libslic3r/PrintConfig.cpp:3750 msgid "Output Model Info" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3670 +#: src/libslic3r/PrintConfig.cpp:3751 msgid "Write information about the model to the console." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3674 +#: src/libslic3r/PrintConfig.cpp:3755 msgid "Save config file" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3675 +#: src/libslic3r/PrintConfig.cpp:3756 msgid "Save configuration to the specified file." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3685 +#: src/libslic3r/PrintConfig.cpp:3766 msgid "Align XY" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3686 +#: src/libslic3r/PrintConfig.cpp:3767 msgid "Align the model to the given point." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3691 +#: src/libslic3r/PrintConfig.cpp:3772 msgid "Cut model at the given Z." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3712 +#: src/libslic3r/PrintConfig.cpp:3793 msgid "Center" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3713 +#: src/libslic3r/PrintConfig.cpp:3794 msgid "Center the print around the given center." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3717 +#: src/libslic3r/PrintConfig.cpp:3798 msgid "Don't arrange" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3718 +#: src/libslic3r/PrintConfig.cpp:3799 msgid "" "Do not rearrange the given models before merging and keep their original XY " "coordinates." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3721 +#: src/libslic3r/PrintConfig.cpp:3802 msgid "Duplicate" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3722 +#: src/libslic3r/PrintConfig.cpp:3803 msgid "Multiply copies by this factor." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3726 +#: src/libslic3r/PrintConfig.cpp:3807 msgid "Duplicate by grid" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3727 +#: src/libslic3r/PrintConfig.cpp:3808 msgid "Multiply copies by creating a grid." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3731 +#: src/libslic3r/PrintConfig.cpp:3812 msgid "" "Arrange the supplied models in a plate and merge them in a single model in " "order to perform actions once." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3736 +#: src/libslic3r/PrintConfig.cpp:3817 msgid "" "Try to repair any non-manifold meshes (this option is implicitly added " "whenever we need to slice the model to perform the requested action)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3740 +#: src/libslic3r/PrintConfig.cpp:3821 msgid "Rotation angle around the Z axis in degrees." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3744 +#: src/libslic3r/PrintConfig.cpp:3825 msgid "Rotate around X" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3745 +#: src/libslic3r/PrintConfig.cpp:3826 msgid "Rotation angle around the X axis in degrees." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3749 +#: src/libslic3r/PrintConfig.cpp:3830 msgid "Rotate around Y" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3750 +#: src/libslic3r/PrintConfig.cpp:3831 msgid "Rotation angle around the Y axis in degrees." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3755 +#: src/libslic3r/PrintConfig.cpp:3836 msgid "Scaling factor or percentage." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3760 +#: src/libslic3r/PrintConfig.cpp:3841 msgid "" "Detect unconnected parts in the given model(s) and split them into separate " "objects." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3763 +#: src/libslic3r/PrintConfig.cpp:3844 msgid "Scale to Fit" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3764 +#: src/libslic3r/PrintConfig.cpp:3845 msgid "Scale to fit the given volume." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3773 +#: src/libslic3r/PrintConfig.cpp:3854 msgid "Ignore non-existent config files" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3774 +#: src/libslic3r/PrintConfig.cpp:3855 msgid "Do not fail if a file supplied to --load does not exist." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3777 +#: src/libslic3r/PrintConfig.cpp:3858 msgid "Load config file" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3778 +#: src/libslic3r/PrintConfig.cpp:3859 msgid "" "Load configuration from the specified file. It can be used more than once to " "load options from multiple files." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3781 +#: src/libslic3r/PrintConfig.cpp:3862 msgid "Output File" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3782 +#: src/libslic3r/PrintConfig.cpp:3863 msgid "" "The file where the output will be written (if not specified, it will be " "based on the input file)." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3786 +#: src/libslic3r/PrintConfig.cpp:3867 msgid "Single instance mode" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3787 +#: src/libslic3r/PrintConfig.cpp:3868 msgid "" "If enabled, the command line arguments are sent to an existing instance of " "GUI PrusaSlicer, or an existing PrusaSlicer window is activated. Overrides " "the \"single_instance\" configuration value from application preferences." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3798 +#: src/libslic3r/PrintConfig.cpp:3879 msgid "Data directory" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3799 +#: src/libslic3r/PrintConfig.cpp:3880 msgid "" "Load and store settings at the given directory. This is useful for " "maintaining different profiles or including configurations from a network " "storage." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3802 +#: src/libslic3r/PrintConfig.cpp:3883 msgid "Logging level" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3803 +#: src/libslic3r/PrintConfig.cpp:3884 msgid "" "Sets logging sensitivity. 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:" "trace\n" "For example. loglevel=2 logs fatal, error and warning level messages." msgstr "" -#: src/libslic3r/PrintConfig.cpp:3809 +#: src/libslic3r/PrintConfig.cpp:3890 msgid "Render with a software renderer" msgstr "" -#: src/libslic3r/PrintConfig.cpp:3810 +#: src/libslic3r/PrintConfig.cpp:3891 msgid "" "Render with a software renderer. The bundled MESA software renderer is " "loaded instead of the default OpenGL driver." diff --git a/resources/localization/ru/PrusaSlicer.mo b/resources/localization/ru/PrusaSlicer.mo index ea21653648..967c50ca69 100644 Binary files a/resources/localization/ru/PrusaSlicer.mo and b/resources/localization/ru/PrusaSlicer.mo differ diff --git a/resources/localization/ru/PrusaSlicer_ru.po b/resources/localization/ru/PrusaSlicer_ru.po index 604dff5be5..2a929e55ef 100644 --- a/resources/localization/ru/PrusaSlicer_ru.po +++ b/resources/localization/ru/PrusaSlicer_ru.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-09 15:30+0700\n" -"PO-Revision-Date: 2021-01-10 02:38+0700\n" +"PO-Revision-Date: 2021-02-03 14:06+0100\n" "Language-Team: Andylg \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && " -"(n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 1.8.7\n" -"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n" +"%100>=20) ? 1 : 2);\n" +"X-Generator: Poedit 2.4.2\n" +"Last-Translator: Oleksandra Iushchenko \n" "Language: ru_RU\n" #: src/slic3r/GUI/AboutDialog.cpp:45 src/slic3r/GUI/AboutDialog.cpp:299 @@ -394,7 +394,6 @@ msgid "First layer height" msgstr "Высота первого слоя" #: src/slic3r/GUI/ConfigManipulation.cpp:81 -#, c-format msgid "" "The Spiral Vase mode requires:\n" "- one perimeter\n" @@ -410,7 +409,7 @@ msgstr "" "- отсутствие верхних сплошных слоёв\n" "- плотность заполнения 0%\n" "- отсутствие поддержки\n" -"- отключено \"Обеспечивать вертикальную толщину оболочки\"\n" +"- включено \"Обеспечивать вертикальную толщину оболочки\"\n" "- отключено \"Обнаружение тонких стенок\"" #: src/slic3r/GUI/ConfigManipulation.cpp:89 @@ -432,7 +431,7 @@ msgstr "" "только в том случае, если она печатается текущим экструдером, без запуска\n" "смены инструмента. (Значения \"Экструдер, печатающий поддержки/подложки/юбки\"\n" "и \"Экструдер, печатающий связующий слой поддержки/подложки\" должны быть\n" -"установлены в 0).\"" +"установлены в 0)." #: src/slic3r/GUI/ConfigManipulation.cpp:119 msgid "Shall I adjust those settings in order to enable the Wipe Tower?" @@ -546,7 +545,7 @@ msgstr "пруток" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:59 src/libslic3r/Preset.cpp:1300 msgid "SLA print" -msgstr "Профиль SLA печати:" +msgstr "Профиль SLA печати" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:60 src/slic3r/GUI/Plater.cpp:696 #: src/libslic3r/Preset.cpp:1301 @@ -1070,7 +1069,7 @@ msgstr "" #: src/slic3r/GUI/DoubleSlider.cpp:1241 msgid "Edit current color - Right click the colored slider segment" -msgstr "Изменить текущий цвет - Правая кнопка мыши по цветному сегменту ползунка ???" +msgstr "Изменить текущий цвет - Правая кнопка мыши по цветному сегменту ползунка" #: src/slic3r/GUI/DoubleSlider.cpp:1251 msgid "Print mode" @@ -2238,7 +2237,7 @@ msgstr "Ctrl + Колесо мыши" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:233 msgid "Autoset custom supports" -msgstr "Автоустановка пользовательских поддержек ???" +msgstr "Автоустановка пользовательских поддержек" #: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:235 msgid "Threshold:" @@ -2344,7 +2343,7 @@ msgstr "Поворот" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:547 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:563 src/libslic3r/PrintConfig.cpp:3754 msgid "Scale" -msgstr "Масштаб " +msgstr "Масштаб" #: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:30 #: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:381 @@ -2712,7 +2711,7 @@ msgid "" "Note: This name can be changed later from the physical printers settings" msgstr "" "При создании новых принтеров они будут именоваться как \"Принтер N\".\n" -"Примечание: это имя можно изменить позже в настройках физических принтеров." +"Примечание: это имя можно изменить позже в настройках физических принтеров" #: src/slic3r/GUI/GUI_App.cpp:1124 src/slic3r/GUI/PhysicalPrinterDialog.cpp:626 msgid "Information" @@ -2875,7 +2874,7 @@ msgstr "&Настройки" #: src/slic3r/GUI/GUI_App.cpp:1781 msgid "The preset(s) modifications are successfully saved" -msgstr "Изменения в профиле(-ях) успешно сохранены." +msgstr "Изменения в профиле(-ях) успешно сохранены" #: src/slic3r/GUI/GUI_App.cpp:1802 msgid "The uploads are still ongoing" @@ -3459,7 +3458,7 @@ msgstr "Неподдерживаемый выбор" #: src/slic3r/GUI/GUI_ObjectList.cpp:4012 #, c-format msgid "You started your selection with %s Item." -msgstr "Вы начали свой выбор с сущности %s" +msgstr "Вы начали свой выбор с сущности %s." #: src/slic3r/GUI/GUI_ObjectList.cpp:4013 #, c-format @@ -3477,7 +3476,7 @@ msgstr "Информация" #: src/slic3r/GUI/GUI_ObjectList.cpp:4137 msgid "You can't change a type of the last solid part of the object." -msgstr "Вы не можете изменить тип последнего твердотельного элемента модели" +msgstr "Вы не можете изменить тип последнего твердотельного элемента модели." #: src/slic3r/GUI/GUI_ObjectList.cpp:4142 msgid "Modifier" @@ -3794,7 +3793,7 @@ msgstr "ОШИБКА: недостаточно ресурсов для выпо #: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:41 msgid "Searching for optimal orientation" -msgstr "Поиск оптимального положения." +msgstr "Поиск оптимального положения" #: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:73 msgid "Orientation search canceled." @@ -3850,7 +3849,7 @@ msgstr "Импорт завершён." #: src/slic3r/GUI/Jobs/SLAImportJob.cpp:208 src/slic3r/GUI/Plater.cpp:2357 msgid "You cannot load SLA project with a multi-part object on the bed" -msgstr "Вы не можете загрузить SLA проект с составной моделью на столе." +msgstr "Вы не можете загрузить SLA проект с составной моделью на столе" #: src/slic3r/GUI/Jobs/SLAImportJob.cpp:209 src/slic3r/GUI/Plater.cpp:2358 #: src/slic3r/GUI/Tab.cpp:3243 @@ -5114,7 +5113,7 @@ msgstr "" #: src/slic3r/GUI/NotificationManager.cpp:490 #: src/slic3r/GUI/NotificationManager.cpp:500 msgid "More" -msgstr "Подробнее." +msgstr "Подробнее" #: src/slic3r/GUI/NotificationManager.cpp:864 #: src/slic3r/GUI/NotificationManager.cpp:1141 @@ -9314,7 +9313,6 @@ msgid "Extra perimeters if needed" msgstr "Дополнительные периметры при необходимости" #: src/libslic3r/PrintConfig.cpp:539 -#, c-format msgid "" "Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r keeps " "adding perimeters, until more than 70% of the loop immediately above is supported." @@ -10365,7 +10363,6 @@ msgid "This setting represents the maximum speed of your fan." msgstr "Этот параметр регулирует максимальную скорость вращения вентилятора." #: src/libslic3r/PrintConfig.cpp:1435 -#, c-format msgid "" "This is the highest printable layer height for this extruder, used to cap the " "variable layer height and support layer height. Maximum recommended layer height is " diff --git a/resources/localization/uk/PrusaSlicer.mo b/resources/localization/uk/PrusaSlicer.mo index aae82889f3..66b5e0be3e 100644 Binary files a/resources/localization/uk/PrusaSlicer.mo and b/resources/localization/uk/PrusaSlicer.mo differ diff --git a/resources/localization/uk/PrusaSlicer_uk.po b/resources/localization/uk/PrusaSlicer_uk.po index 42b067361e..fefe52eb52 100644 --- a/resources/localization/uk/PrusaSlicer_uk.po +++ b/resources/localization/uk/PrusaSlicer_uk.po @@ -2,95 +2,234 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-04-09 14:34+0200\n" -"PO-Revision-Date: 2019-04-09 15:18+0200\n" +"POT-Creation-Date: 2020-12-18 13:59+0100\n" +"PO-Revision-Date: 2021-02-03 17:15+0100\n" "Last-Translator: Oleksandra Iushchenko \n" "Language-Team: \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.8\n" +"X-Generator: Poedit 2.4.2\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: src/slic3r/GUI/AboutDialog.cpp:35 -msgid "About Slic3r" -msgstr "Про Slic3r" +#: src/slic3r/GUI/AboutDialog.cpp:45 src/slic3r/GUI/AboutDialog.cpp:299 +msgid "Portions copyright" +msgstr "Використані розробки" -#: src/slic3r/GUI/AboutDialog.cpp:64 src/slic3r/GUI/MainFrame.cpp:52 +#: src/slic3r/GUI/AboutDialog.cpp:135 src/slic3r/GUI/AboutDialog.cpp:263 +msgid "Copyright" +msgstr "Копірайт" + +#. TRN "Slic3r _is licensed under the_ License" +#: src/slic3r/GUI/AboutDialog.cpp:137 +msgid "" +"License agreements of all following programs (libraries) are part of " +"application license agreement" +msgstr "" +"Ліцензійні угоди всіх наступних програм (бібліотек) є частиною ліцензійної " +"угоди програми" + +#: src/slic3r/GUI/AboutDialog.cpp:206 +#, c-format +msgid "About %s" +msgstr "О %s" + +#: src/slic3r/GUI/AboutDialog.cpp:238 src/slic3r/GUI/AboutDialog.cpp:361 +#: src/slic3r/GUI/GUI_App.cpp:235 src/slic3r/GUI/MainFrame.cpp:151 msgid "Version" msgstr "Версія" -#: src/slic3r/GUI/BedShapeDialog.cpp:43 -msgid "Shape" -msgstr "Вигляд (Форма)" +#. TRN "Slic3r _is licensed under the_ License" +#: src/slic3r/GUI/AboutDialog.cpp:265 src/slic3r/GUI/GUI_App.cpp:240 +msgid "is licensed under the" +msgstr "ліцензовано згідно" -#: src/slic3r/GUI/BedShapeDialog.cpp:51 -msgid "Rectangular" -msgstr "Прямокутний" +#: src/slic3r/GUI/AboutDialog.cpp:266 src/slic3r/GUI/GUI_App.cpp:240 +msgid "GNU Affero General Public License, version 3" +msgstr "Загальна публічна ліцензія GNU Affero, версія 3" -#: src/slic3r/GUI/BedShapeDialog.cpp:55 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:118 src/slic3r/GUI/Plater.cpp:136 -#: src/slic3r/GUI/Tab.cpp:2185 +#: src/slic3r/GUI/AboutDialog.cpp:267 +msgid "" +"PrusaSlicer is based on Slic3r by Alessandro Ranellucci and the RepRap " +"community." +msgstr "" +"PrusaSlicer заснований на Slic3r від Alessandro Ranellucci та спільноти " +"RepRap." + +#: src/slic3r/GUI/AboutDialog.cpp:268 +msgid "" +"Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, " +"Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and " +"numerous others." +msgstr "" +"Розробки від Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr " +"Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik та багатьох " +"інших." + +#: src/slic3r/GUI/AboutDialog.cpp:304 +msgid "Copy Version Info" +msgstr "Скопіювати інформацію про версію" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:78 +#, c-format +msgid "" +"%s has encountered an error. It was likely caused by running out of memory. " +"If you are sure you have enough RAM on your system, this may also be a bug " +"and we would be glad if you reported it." +msgstr "" +"%s виявив помилку. Ймовірно, це було пов’язано з закінченням пам’яті. Якщо " +"ви впевнені, що у вашій системі достатньо оперативної пам'яті, це також може " +"бути помилкою, і ми будемо раді, якщо ви нам про це повідомите." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:163 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:183 +msgid "Unknown error occured during exporting G-code." +msgstr "Під час експорту G-коду сталася невідома помилка." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:168 +msgid "" +"Copying of the temporary G-code to the output G-code failed. Maybe the SD " +"card is write locked?\n" +"Error message: %1%" +msgstr "" +"Не вдалося скопіювати тимчасовий G-код у вихідний G-код. Можливо, SD-карта " +"заблокована?\n" +"Повідомлення про помилку: %1%" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:171 +msgid "" +"Copying of the temporary G-code to the output G-code failed. There might be " +"problem with target device, please try exporting again or using different " +"device. The corrupted output G-code is at %1%.tmp." +msgstr "" +"Не вдалося скопіювати тимчасовий G-код у вихідний G-код. Можливо, проблема з " +"цільовим пристроєм, спробуйте експортувати ще раз або використати інший " +"пристрій. Пошкоджений вихідний G-код - %1% .tmp." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:174 +msgid "" +"Renaming of the G-code after copying to the selected destination folder has " +"failed. Current path is %1%.tmp. Please try exporting again." +msgstr "" +"Не вдалося перейменувати G-код після копіювання у вибрану папку призначення. " +"Поточний шлях - %1%.tmp. Спробуйте експортувати ще раз." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:177 +msgid "" +"Copying of the temporary G-code has finished but the original code at %1% " +"couldn't be opened during copy check. The output G-code is at %2%.tmp." +msgstr "" +"Копіювання тимчасового G-коду закінчено, але оригінальний код на рівні %1% " +"не вдалося відкрити під час перевірки копії. Вихідний G-код - %2% .tmp." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:180 +msgid "" +"Copying of the temporary G-code has finished but the exported code couldn't " +"be opened during copy check. The output G-code is at %1%.tmp." +msgstr "" +"Копіювання тимчасового G-коду завершено, але експортований код не вдалося " +"відкрити під час перевірки копії. Вихідний G-код - %1% .tmp." + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:187 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:536 +msgid "Running post-processing scripts" +msgstr "Запуск скриптів пост-обробки" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:189 +msgid "G-code file exported to %1%" +msgstr "Файл G-коду експортується до %1%" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:194 +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:243 +msgid "Slicing complete" +msgstr "Нарізання завершено" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:238 +msgid "Masked SLA file exported to %1%" +msgstr "Файл SLA експортовано до %1%" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:539 +msgid "Copying of the temporary G-code to the output G-code failed" +msgstr "Не вдалося скопіювати тимчасовий G-код у вихідний G-код" + +#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:562 +msgid "Scheduling upload to `%1%`. See Window -> Print Host Upload Queue" +msgstr "" +"Планування завантаження до `%1%`. Див. Вікно -> Черга завантаження хоста " +"друку" + +#: src/slic3r/GUI/BedShapeDialog.cpp:93 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:240 src/slic3r/GUI/Plater.cpp:162 +#: src/slic3r/GUI/Tab.cpp:2536 msgid "Size" msgstr "Розмір" -#: src/slic3r/GUI/BedShapeDialog.cpp:56 -msgid "Size in X and Y of the rectangular plate." -msgstr "Розмір прямокутної подложки за X та Y." - -#: src/slic3r/GUI/BedShapeDialog.cpp:62 +#: src/slic3r/GUI/BedShapeDialog.cpp:94 msgid "Origin" msgstr "Початок координат" -#: src/slic3r/GUI/BedShapeDialog.cpp:63 +#: src/slic3r/GUI/BedShapeDialog.cpp:95 src/libslic3r/PrintConfig.cpp:771 +msgid "Diameter" +msgstr "Діаметр" + +#: src/slic3r/GUI/BedShapeDialog.cpp:110 +msgid "Size in X and Y of the rectangular plate." +msgstr "Розмір прямокутної подложки за X та Y." + +#: src/slic3r/GUI/BedShapeDialog.cpp:121 msgid "" "Distance of the 0,0 G-code coordinate from the front left corner of the " "rectangle." msgstr "Відстань координат 0,0 G-коду від нижнього лівого кута прямокутника." -#: src/slic3r/GUI/BedShapeDialog.cpp:67 -msgid "Circular" -msgstr "Круговий" - -#: src/slic3r/GUI/BedShapeDialog.cpp:70 src/slic3r/GUI/ConfigWizard.cpp:111 -#: src/slic3r/GUI/ConfigWizard.cpp:544 src/slic3r/GUI/ConfigWizard.cpp:558 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:115 -#: src/slic3r/GUI/RammingChart.cpp:81 src/slic3r/GUI/WipeTowerDialog.cpp:84 -#: src/libslic3r/PrintConfig.cpp:59 src/libslic3r/PrintConfig.cpp:66 -#: src/libslic3r/PrintConfig.cpp:75 src/libslic3r/PrintConfig.cpp:209 -#: src/libslic3r/PrintConfig.cpp:284 src/libslic3r/PrintConfig.cpp:292 -#: src/libslic3r/PrintConfig.cpp:342 src/libslic3r/PrintConfig.cpp:352 -#: src/libslic3r/PrintConfig.cpp:472 src/libslic3r/PrintConfig.cpp:483 -#: src/libslic3r/PrintConfig.cpp:501 src/libslic3r/PrintConfig.cpp:679 -#: src/libslic3r/PrintConfig.cpp:1165 src/libslic3r/PrintConfig.cpp:1226 -#: src/libslic3r/PrintConfig.cpp:1244 src/libslic3r/PrintConfig.cpp:1262 -#: src/libslic3r/PrintConfig.cpp:1314 src/libslic3r/PrintConfig.cpp:1324 -#: src/libslic3r/PrintConfig.cpp:1445 src/libslic3r/PrintConfig.cpp:1453 -#: src/libslic3r/PrintConfig.cpp:1494 src/libslic3r/PrintConfig.cpp:1502 -#: src/libslic3r/PrintConfig.cpp:1512 src/libslic3r/PrintConfig.cpp:1520 -#: src/libslic3r/PrintConfig.cpp:1528 src/libslic3r/PrintConfig.cpp:1611 -#: src/libslic3r/PrintConfig.cpp:1827 src/libslic3r/PrintConfig.cpp:1897 -#: src/libslic3r/PrintConfig.cpp:1931 src/libslic3r/PrintConfig.cpp:2123 -#: src/libslic3r/PrintConfig.cpp:2130 src/libslic3r/PrintConfig.cpp:2137 -#: src/libslic3r/PrintConfig.cpp:2167 src/libslic3r/PrintConfig.cpp:2177 -#: src/libslic3r/PrintConfig.cpp:2187 src/libslic3r/PrintConfig.cpp:2293 -#: src/libslic3r/PrintConfig.cpp:2368 src/libslic3r/PrintConfig.cpp:2377 -#: src/libslic3r/PrintConfig.cpp:2386 src/libslic3r/PrintConfig.cpp:2396 -#: src/libslic3r/PrintConfig.cpp:2440 src/libslic3r/PrintConfig.cpp:2450 -#: src/libslic3r/PrintConfig.cpp:2469 src/libslic3r/PrintConfig.cpp:2479 -#: src/libslic3r/PrintConfig.cpp:2488 src/libslic3r/PrintConfig.cpp:2506 -#: src/libslic3r/PrintConfig.cpp:2521 src/libslic3r/PrintConfig.cpp:2532 -#: src/libslic3r/PrintConfig.cpp:2545 src/libslic3r/PrintConfig.cpp:2555 +#: src/slic3r/GUI/BedShapeDialog.cpp:129 src/slic3r/GUI/ConfigWizard.cpp:242 +#: src/slic3r/GUI/ConfigWizard.cpp:1368 src/slic3r/GUI/ConfigWizard.cpp:1382 +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:88 +#: src/slic3r/GUI/GCodeViewer.cpp:2337 src/slic3r/GUI/GCodeViewer.cpp:2343 +#: src/slic3r/GUI/GCodeViewer.cpp:2351 src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:179 +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:145 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:341 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:418 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:486 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:487 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:96 +#: src/slic3r/GUI/WipeTowerDialog.cpp:85 src/libslic3r/PrintConfig.cpp:77 +#: src/libslic3r/PrintConfig.cpp:84 src/libslic3r/PrintConfig.cpp:95 +#: src/libslic3r/PrintConfig.cpp:135 src/libslic3r/PrintConfig.cpp:244 +#: src/libslic3r/PrintConfig.cpp:302 src/libslic3r/PrintConfig.cpp:377 +#: src/libslic3r/PrintConfig.cpp:385 src/libslic3r/PrintConfig.cpp:435 +#: src/libslic3r/PrintConfig.cpp:565 src/libslic3r/PrintConfig.cpp:576 +#: src/libslic3r/PrintConfig.cpp:594 src/libslic3r/PrintConfig.cpp:774 +#: src/libslic3r/PrintConfig.cpp:1258 src/libslic3r/PrintConfig.cpp:1439 +#: src/libslic3r/PrintConfig.cpp:1500 src/libslic3r/PrintConfig.cpp:1518 +#: src/libslic3r/PrintConfig.cpp:1536 src/libslic3r/PrintConfig.cpp:1594 +#: src/libslic3r/PrintConfig.cpp:1604 src/libslic3r/PrintConfig.cpp:1729 +#: src/libslic3r/PrintConfig.cpp:1737 src/libslic3r/PrintConfig.cpp:1778 +#: src/libslic3r/PrintConfig.cpp:1786 src/libslic3r/PrintConfig.cpp:1796 +#: src/libslic3r/PrintConfig.cpp:1804 src/libslic3r/PrintConfig.cpp:1812 +#: src/libslic3r/PrintConfig.cpp:1875 src/libslic3r/PrintConfig.cpp:2141 +#: src/libslic3r/PrintConfig.cpp:2212 src/libslic3r/PrintConfig.cpp:2246 +#: src/libslic3r/PrintConfig.cpp:2375 src/libslic3r/PrintConfig.cpp:2454 +#: src/libslic3r/PrintConfig.cpp:2461 src/libslic3r/PrintConfig.cpp:2468 +#: src/libslic3r/PrintConfig.cpp:2498 src/libslic3r/PrintConfig.cpp:2508 +#: src/libslic3r/PrintConfig.cpp:2518 src/libslic3r/PrintConfig.cpp:2678 +#: src/libslic3r/PrintConfig.cpp:2712 src/libslic3r/PrintConfig.cpp:2851 +#: src/libslic3r/PrintConfig.cpp:2860 src/libslic3r/PrintConfig.cpp:2869 +#: src/libslic3r/PrintConfig.cpp:2879 src/libslic3r/PrintConfig.cpp:2944 +#: src/libslic3r/PrintConfig.cpp:2954 src/libslic3r/PrintConfig.cpp:2966 +#: src/libslic3r/PrintConfig.cpp:2986 src/libslic3r/PrintConfig.cpp:2996 +#: src/libslic3r/PrintConfig.cpp:3006 src/libslic3r/PrintConfig.cpp:3024 +#: src/libslic3r/PrintConfig.cpp:3039 src/libslic3r/PrintConfig.cpp:3053 +#: src/libslic3r/PrintConfig.cpp:3064 src/libslic3r/PrintConfig.cpp:3077 +#: src/libslic3r/PrintConfig.cpp:3122 src/libslic3r/PrintConfig.cpp:3132 +#: src/libslic3r/PrintConfig.cpp:3141 src/libslic3r/PrintConfig.cpp:3151 +#: src/libslic3r/PrintConfig.cpp:3167 src/libslic3r/PrintConfig.cpp:3191 msgid "mm" msgstr "мм" -#: src/slic3r/GUI/BedShapeDialog.cpp:71 src/libslic3r/PrintConfig.cpp:676 -msgid "Diameter" -msgstr "Діаметр" - -#: src/slic3r/GUI/BedShapeDialog.cpp:72 +#: src/slic3r/GUI/BedShapeDialog.cpp:131 msgid "" "Diameter of the print bed. It is assumed that origin (0,0) is located in the " "center." @@ -98,55 +237,106 @@ msgstr "" "Діаметр подложки. Передбачається, що початок координат (0,0) знаходиться в " "центрі." -#: src/slic3r/GUI/BedShapeDialog.cpp:76 src/slic3r/GUI/GUI_Preview.cpp:239 -#: src/libslic3r/GCode/PreviewData.cpp:175 +#: src/slic3r/GUI/BedShapeDialog.cpp:141 +msgid "Rectangular" +msgstr "Прямокутний" + +#: src/slic3r/GUI/BedShapeDialog.cpp:142 +msgid "Circular" +msgstr "Круговий" + +#: src/slic3r/GUI/BedShapeDialog.cpp:143 src/slic3r/GUI/GUI_Preview.cpp:243 +#: src/libslic3r/ExtrusionEntity.cpp:323 src/libslic3r/ExtrusionEntity.cpp:358 msgid "Custom" msgstr "Користувацький" -#: src/slic3r/GUI/BedShapeDialog.cpp:80 +#: src/slic3r/GUI/BedShapeDialog.cpp:145 +msgid "Invalid" +msgstr "Недійсний" + +#: src/slic3r/GUI/BedShapeDialog.cpp:156 src/slic3r/GUI/BedShapeDialog.cpp:222 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2288 +msgid "Shape" +msgstr "Форма" + +#: src/slic3r/GUI/BedShapeDialog.cpp:243 msgid "Load shape from STL..." msgstr "Завантажте форму з STL ..." -#: src/slic3r/GUI/BedShapeDialog.cpp:126 +#: src/slic3r/GUI/BedShapeDialog.cpp:292 src/slic3r/GUI/MainFrame.cpp:1826 msgid "Settings" msgstr "Налаштування" -#: src/slic3r/GUI/BedShapeDialog.cpp:299 -msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Виберіть файл, щоб імпортувати форму полотна з (STL/OBJ/AMF/PRUSA):" +#: src/slic3r/GUI/BedShapeDialog.cpp:315 +msgid "Texture" +msgstr "Текстура" -#: src/slic3r/GUI/BedShapeDialog.cpp:316 src/slic3r/GUI/GUI_ObjectList.cpp:1252 -msgid "Error! " -msgstr "Помилка! " +#: src/slic3r/GUI/BedShapeDialog.cpp:325 src/slic3r/GUI/BedShapeDialog.cpp:405 +msgid "Load..." +msgstr "Завантажити..." -#: src/slic3r/GUI/BedShapeDialog.cpp:325 +#: src/slic3r/GUI/BedShapeDialog.cpp:333 src/slic3r/GUI/BedShapeDialog.cpp:413 +#: src/slic3r/GUI/Tab.cpp:3484 +msgid "Remove" +msgstr "Видалити" + +#: src/slic3r/GUI/BedShapeDialog.cpp:366 src/slic3r/GUI/BedShapeDialog.cpp:446 +msgid "Not found:" +msgstr "Не знайдено:" + +#: src/slic3r/GUI/BedShapeDialog.cpp:395 +msgid "Model" +msgstr "Модель" + +#: src/slic3r/GUI/BedShapeDialog.cpp:563 +msgid "Choose an STL file to import bed shape from:" +msgstr "Виберіть STL-файл для імпорту форми столу з:" + +#: src/slic3r/GUI/BedShapeDialog.cpp:570 src/slic3r/GUI/BedShapeDialog.cpp:619 +#: src/slic3r/GUI/BedShapeDialog.cpp:642 +msgid "Invalid file format." +msgstr "Недійсний формат файлу." + +#: src/slic3r/GUI/BedShapeDialog.cpp:581 +msgid "Error! Invalid model" +msgstr "Помилка! Недійсна модель" + +#: src/slic3r/GUI/BedShapeDialog.cpp:589 msgid "The selected file contains no geometry." msgstr "Обраний файл не містить геометрії." -#: src/slic3r/GUI/BedShapeDialog.cpp:329 +#: src/slic3r/GUI/BedShapeDialog.cpp:593 msgid "" "The selected file contains several disjoint areas. This is not supported." msgstr "Обраний файл містить декілька непересічних областей. Не підтримується." -#: src/slic3r/GUI/BedShapeDialog.hpp:44 src/slic3r/GUI/ConfigWizard.cpp:507 +#: src/slic3r/GUI/BedShapeDialog.cpp:608 +msgid "Choose a file to import bed texture from (PNG/SVG):" +msgstr "Виберіть файл для імпорту текстури столу (PNG / SVG):" + +#: src/slic3r/GUI/BedShapeDialog.cpp:631 +msgid "Choose an STL file to import bed model from:" +msgstr "Виберіть STL-файл для імпорту моделі столу з:" + +#: src/slic3r/GUI/BedShapeDialog.hpp:98 src/slic3r/GUI/ConfigWizard.cpp:1327 msgid "Bed Shape" -msgstr "Форма полотна" +msgstr "Форма столу" #: src/slic3r/GUI/BonjourDialog.cpp:55 msgid "Network lookup" -msgstr "" +msgstr "Пошук мережі" #: src/slic3r/GUI/BonjourDialog.cpp:72 msgid "Address" -msgstr "" +msgstr "Адреса" #: src/slic3r/GUI/BonjourDialog.cpp:73 msgid "Hostname" -msgstr "" +msgstr "Назва хоста" #: src/slic3r/GUI/BonjourDialog.cpp:74 msgid "Service name" -msgstr "" +msgstr "Назва сервісу" #: src/slic3r/GUI/BonjourDialog.cpp:76 msgid "OctoPrint version" @@ -154,417 +344,1184 @@ msgstr "Версія OctoPrint" #: src/slic3r/GUI/BonjourDialog.cpp:218 msgid "Searching for devices" -msgstr "" +msgstr "Пошук пристроїв" #: src/slic3r/GUI/BonjourDialog.cpp:225 msgid "Finished" -msgstr "" +msgstr "Завершено" -#: src/slic3r/GUI/ButtonsDescription.cpp:15 +#: src/slic3r/GUI/ButtonsDescription.cpp:16 msgid "Buttons And Text Colors Description" -msgstr "" +msgstr "Опис кнопок та кольорів тексту" -#: src/slic3r/GUI/ButtonsDescription.cpp:40 +#: src/slic3r/GUI/ButtonsDescription.cpp:36 msgid "Value is the same as the system value" -msgstr "" +msgstr "Значення таке ж, як системне" -#: src/slic3r/GUI/ButtonsDescription.cpp:57 +#: src/slic3r/GUI/ButtonsDescription.cpp:53 msgid "" "Value was changed and is not equal to the system value or the last saved " "preset" msgstr "" +"Значення було змінено і не дорівнює системному значенню або останньому " +"збереженому пресету" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:17 -msgid "Upgrade" +#: src/slic3r/GUI/ConfigManipulation.cpp:48 +msgid "" +"Zero layer height is not valid.\n" +"\n" +"The layer height will be reset to 0.01." msgstr "" +"Нульового висота шару є недійсною.\n" +"\n" +"Висота шару буде скинута до 0,01." + +#: src/slic3r/GUI/ConfigManipulation.cpp:49 +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:29 src/slic3r/GUI/Tab.cpp:1387 +#: src/libslic3r/PrintConfig.cpp:73 +msgid "Layer height" +msgstr "Висота шару" + +#: src/slic3r/GUI/ConfigManipulation.cpp:60 +msgid "" +"Zero first layer height is not valid.\n" +"\n" +"The first layer height will be reset to 0.01." +msgstr "" +"Нульового висота першого шару є недійсною.\n" +"\n" +"Висота першого шару буде скинута до 0,01." + +#: src/slic3r/GUI/ConfigManipulation.cpp:61 src/libslic3r/PrintConfig.cpp:969 +msgid "First layer height" +msgstr "Висота першого шару" + +#: src/slic3r/GUI/ConfigManipulation.cpp:81 +msgid "" +"The Spiral Vase mode requires:\n" +"- one perimeter\n" +"- no top solid layers\n" +"- 0% fill density\n" +"- no support material\n" +"- Ensure vertical shell thickness enabled\n" +"- Detect thin walls disabled" +msgstr "" +"Режим спіральної вази вимагає:\n" +"- один периметр\n" +"- немає верхніх щільних шарів\n" +"- щільність заповнення 0%\n" +"- немає підтримуючого матеріалу\n" +"- \"Забезпечення товщини вертикальної оболонки\" увімкнено\n" +"- \"Виявлення тонких стінок\" вимкнено" + +#: src/slic3r/GUI/ConfigManipulation.cpp:89 +msgid "Shall I adjust those settings in order to enable Spiral Vase?" +msgstr "" +"Чи потрібно змінити ці налаштування, щоб увімкнути режим Спіральної вази?" + +#: src/slic3r/GUI/ConfigManipulation.cpp:90 +msgid "Spiral Vase" +msgstr "Спіральна ваза" + +#: src/slic3r/GUI/ConfigManipulation.cpp:115 +msgid "" +"The Wipe Tower currently supports the non-soluble supports only\n" +"if they are printed with the current extruder without triggering a tool " +"change.\n" +"(both support_material_extruder and support_material_interface_extruder need " +"to be set to 0)." +msgstr "" +"Вежа витирання в даний момент підтримує лише нерозчинні підтримки,\n" +"якщо вони друкуються з поточним екструдером, не запускаючи зміну " +"інструменту.\n" +"(обидва значення support_material_extruder і " +"support_material_interface_extruder повинні бути встановлені на 0)." + +#: src/slic3r/GUI/ConfigManipulation.cpp:119 +msgid "Shall I adjust those settings in order to enable the Wipe Tower?" +msgstr "Чи потрібно коригувати ці налаштування, щоб увімкнути вежу витирання?" + +#: src/slic3r/GUI/ConfigManipulation.cpp:120 +#: src/slic3r/GUI/ConfigManipulation.cpp:140 +msgid "Wipe Tower" +msgstr "Вежа витирання" + +#: src/slic3r/GUI/ConfigManipulation.cpp:136 +msgid "" +"For the Wipe Tower to work with the soluble supports, the support layers\n" +"need to be synchronized with the object layers." +msgstr "" +"Для того, щоб вежа витирання працювала з розчинними підтримками, шари " +"підтримки\n" +"повинні бути синхронізовані з шаром об'єкта." + +#: src/slic3r/GUI/ConfigManipulation.cpp:139 +msgid "Shall I synchronize support layers in order to enable the Wipe Tower?" +msgstr "" +"Чи потрібно синхронізувати шари підтримки, щоб увімкнути вежу витирання?" + +#: src/slic3r/GUI/ConfigManipulation.cpp:159 +msgid "" +"Supports work better, if the following feature is enabled:\n" +"- Detect bridging perimeters" +msgstr "" +"Підтримка працює краще, якщо ввімкнена така функція:\n" +"- Виявлення нависаючих периметрів(перемичок)" + +#: src/slic3r/GUI/ConfigManipulation.cpp:162 +msgid "Shall I adjust those settings for supports?" +msgstr "Чи потрібно змінити ці налаштування для підтримки?" + +#: src/slic3r/GUI/ConfigManipulation.cpp:163 +msgid "Support Generator" +msgstr "Створення підтримки" + +#: src/slic3r/GUI/ConfigManipulation.cpp:198 +msgid "The %1% infill pattern is not supposed to work at 100%% density." +msgstr "Шаблон заповнення %1% не підтримується при щільності 100%%." + +#: src/slic3r/GUI/ConfigManipulation.cpp:201 +msgid "Shall I switch to rectilinear fill pattern?" +msgstr "Чи потрібно змінити його на прямолінійний шаблон заповнення?" + +#: src/slic3r/GUI/ConfigManipulation.cpp:202 +#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:93 +#: src/slic3r/GUI/GUI_ObjectList.cpp:668 src/slic3r/GUI/Plater.cpp:389 +#: src/slic3r/GUI/Tab.cpp:1432 src/slic3r/GUI/Tab.cpp:1434 +#: src/libslic3r/PrintConfig.cpp:259 src/libslic3r/PrintConfig.cpp:472 +#: src/libslic3r/PrintConfig.cpp:496 src/libslic3r/PrintConfig.cpp:848 +#: src/libslic3r/PrintConfig.cpp:862 src/libslic3r/PrintConfig.cpp:899 +#: src/libslic3r/PrintConfig.cpp:1076 src/libslic3r/PrintConfig.cpp:1086 +#: src/libslic3r/PrintConfig.cpp:1153 src/libslic3r/PrintConfig.cpp:1172 +#: src/libslic3r/PrintConfig.cpp:1191 src/libslic3r/PrintConfig.cpp:1928 +#: src/libslic3r/PrintConfig.cpp:1945 +msgid "Infill" +msgstr "Заповнення" + +#: src/slic3r/GUI/ConfigManipulation.cpp:320 +msgid "Head penetration should not be greater than the head width." +msgstr "Проникнення головки не повинно бути більше її ширини." + +#: src/slic3r/GUI/ConfigManipulation.cpp:322 +msgid "Invalid Head penetration" +msgstr "Неприпустиме проникнення головки" + +#: src/slic3r/GUI/ConfigManipulation.cpp:333 +msgid "Pinhead diameter should be smaller than the pillar diameter." +msgstr "Діаметр головки стовпа повинен бути менше діаметра стовпа." + +#: src/slic3r/GUI/ConfigManipulation.cpp:335 +msgid "Invalid pinhead diameter" +msgstr "Неприпустимий діаметр головки" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:19 -msgid "Downgrade" -msgstr "" +msgid "Upgrade" +msgstr "Оновити" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:21 -msgid "Before roll back" -msgstr "" +msgid "Downgrade" +msgstr "Повернути до попередньої версії" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:23 +msgid "Before roll back" +msgstr "Перед відкатом" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:25 src/libslic3r/PrintConfig.cpp:143 msgid "User" -msgstr "" +msgstr "Користувацький" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:26 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:28 +#: src/slic3r/GUI/GUI_Preview.cpp:229 src/libslic3r/ExtrusionEntity.cpp:309 msgid "Unknown" -msgstr "" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:38 -msgid "Active: " -msgstr "" +msgstr "Невідомий" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:44 -msgid "slic3r version" -msgstr "версія slic3r" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:45 src/slic3r/GUI/Preset.cpp:1250 -msgid "print" -msgstr "" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:46 -msgid "filaments" -msgstr "" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:47 src/slic3r/GUI/Preset.cpp:1254 -msgid "printer" -msgstr "" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:51 src/slic3r/GUI/Tab.cpp:872 -msgid "vendor" -msgstr "" +msgid "Active" +msgstr "Активний" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:51 +msgid "PrusaSlicer version" +msgstr "Версія PrusaSlicer" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:55 src/libslic3r/Preset.cpp:1298 +msgid "print" +msgstr "друк" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:56 +msgid "filaments" +msgstr "філаменти" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:59 src/libslic3r/Preset.cpp:1300 +msgid "SLA print" +msgstr "SLA-друк" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:60 src/slic3r/GUI/Plater.cpp:696 +#: src/libslic3r/Preset.cpp:1301 +msgid "SLA material" +msgstr "SLA-матеріал" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:62 src/libslic3r/Preset.cpp:1302 +msgid "printer" +msgstr "принтер" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:66 src/slic3r/GUI/Tab.cpp:1304 +msgid "vendor" +msgstr "виробник" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:66 msgid "version" msgstr "версія" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:52 -msgid "min slic3r version" -msgstr "мінімальна версія slic3r" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:54 -msgid "max slic3r version" -msgstr "максимальна версія slic3r" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:57 -msgid "model" -msgstr "" - -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:57 -msgid "variants" -msgstr "" +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:67 +msgid "min PrusaSlicer version" +msgstr "мінімальна версія PrusaSlicer" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:69 -msgid "Incompatible with this Slic3r" -msgstr "" +msgid "max PrusaSlicer version" +msgstr "максимальна версія PrusaSlicer" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:72 +msgid "model" +msgstr "модель" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:72 +msgid "variants" +msgstr "варіанти" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:84 +#, c-format +msgid "Incompatible with this %s" +msgstr "Є несумісним з цією версією %s" + +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:87 msgid "Activate" -msgstr "" +msgstr "Активувати" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:98 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:113 msgid "Configuration Snapshots" -msgstr "" +msgstr "Знімки конфігурації" -#: src/slic3r/GUI/ConfigWizard.cpp:111 +#: src/slic3r/GUI/ConfigWizard.cpp:242 msgid "nozzle" -msgstr "" +msgstr "сопло" -#: src/slic3r/GUI/ConfigWizard.cpp:115 +#: src/slic3r/GUI/ConfigWizard.cpp:246 msgid "Alternate nozzles:" -msgstr "" +msgstr "Альтернативні сопла:" -#: src/slic3r/GUI/ConfigWizard.cpp:181 +#: src/slic3r/GUI/ConfigWizard.cpp:310 msgid "All standard" -msgstr "" +msgstr "Всі стандартні" -#: src/slic3r/GUI/ConfigWizard.cpp:182 src/slic3r/GUI/Tab.cpp:2909 +#: src/slic3r/GUI/ConfigWizard.cpp:310 +msgid "Standard" +msgstr "Стандартний" + +#: src/slic3r/GUI/ConfigWizard.cpp:311 src/slic3r/GUI/ConfigWizard.cpp:605 +#: src/slic3r/GUI/Tab.cpp:3565 src/slic3r/GUI/UnsavedChangesDialog.cpp:933 msgid "All" msgstr "Всі" -#: src/slic3r/GUI/ConfigWizard.cpp:183 src/slic3r/GUI/Plater.cpp:414 -#: src/libslic3r/GCode/PreviewData.cpp:162 +#: src/slic3r/GUI/ConfigWizard.cpp:312 src/slic3r/GUI/ConfigWizard.cpp:606 +#: src/slic3r/GUI/DoubleSlider.cpp:1859 src/slic3r/GUI/Plater.cpp:361 +#: src/slic3r/GUI/Plater.cpp:504 msgid "None" msgstr "Жодне" -#: src/slic3r/GUI/ConfigWizard.cpp:284 +#: src/slic3r/GUI/ConfigWizard.cpp:452 #, c-format -msgid "Welcome to the Slic3r %s" -msgstr "Ласкаво просимо до Slic3r %s" +msgid "Welcome to the %s Configuration Assistant" +msgstr "Ласкаво просимо до Асистента конфігурації %s" -#: src/slic3r/GUI/ConfigWizard.cpp:284 +#: src/slic3r/GUI/ConfigWizard.cpp:454 +#, c-format +msgid "Welcome to the %s Configuration Wizard" +msgstr "Ласкаво просимо до Майстру конфігурації %s" + +#: src/slic3r/GUI/ConfigWizard.cpp:456 msgid "Welcome" msgstr "Ласкаво просимо" -#: src/slic3r/GUI/ConfigWizard.cpp:288 src/slic3r/GUI/GUI_App.cpp:600 -#, c-format -msgid "Run %s" -msgstr "" - -#: src/slic3r/GUI/ConfigWizard.cpp:290 +#: src/slic3r/GUI/ConfigWizard.cpp:458 #, c-format msgid "" -"Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial " -"configuration; just a few settings and you will be ready to print." +"Hello, welcome to %s! This %s helps you with the initial configuration; just " +"a few settings and you will be ready to print." msgstr "" +"Вітаємо, ласкаво просимо до %s! Цей %s допоможе вам в початковій " +"конфігурації; лише кілька налаштувань, і ви будете готові до друку." -#: src/slic3r/GUI/ConfigWizard.cpp:294 -msgid "" -"Remove user profiles - install from scratch (a snapshot will be taken " -"beforehand)" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:463 +msgid "Remove user profiles (a snapshot will be taken beforehand)" +msgstr "Видалити профілі користувачів (знімок буде зроблено заздалегідь)" -#: src/slic3r/GUI/ConfigWizard.cpp:325 +#: src/slic3r/GUI/ConfigWizard.cpp:506 #, c-format msgid "%s Family" -msgstr "" +msgstr "%s Родина" -#: src/slic3r/GUI/ConfigWizard.cpp:362 -msgid "Custom Printer Setup" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:594 +msgid "Printer:" +msgstr "Принтер:" -#: src/slic3r/GUI/ConfigWizard.cpp:362 -msgid "Custom Printer" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:596 +msgid "Vendor:" +msgstr "Виробник:" -#: src/slic3r/GUI/ConfigWizard.cpp:364 -msgid "Define a custom printer profile" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:597 +msgid "Profile:" +msgstr "Профіль:" -#: src/slic3r/GUI/ConfigWizard.cpp:366 -msgid "Custom profile name:" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:669 src/slic3r/GUI/ConfigWizard.cpp:819 +#: src/slic3r/GUI/ConfigWizard.cpp:880 src/slic3r/GUI/ConfigWizard.cpp:1017 +msgid "(All)" +msgstr "(Всі)" -#: src/slic3r/GUI/ConfigWizard.cpp:390 -msgid "Automatic updates" -msgstr "" - -#: src/slic3r/GUI/ConfigWizard.cpp:390 -msgid "Updates" -msgstr "" - -#: src/slic3r/GUI/ConfigWizard.cpp:398 src/slic3r/GUI/Preferences.cpp:59 -msgid "Check for application updates" -msgstr "" - -#: src/slic3r/GUI/ConfigWizard.cpp:401 src/slic3r/GUI/Preferences.cpp:61 +#: src/slic3r/GUI/ConfigWizard.cpp:698 msgid "" -"If enabled, Slic3r checks for new versions of Slic3r PE online. When a new " -"version becomes available a notification is displayed at the next " +"Filaments marked with * are not compatible with some installed " +"printers." +msgstr "" +"Філаменти, позначені *, є несумісні з деякими встановленими " +"принтерами." + +#: src/slic3r/GUI/ConfigWizard.cpp:701 +msgid "All installed printers are compatible with the selected filament." +msgstr "Усі встановлені принтери сумісні з обраним філаментем." + +#: src/slic3r/GUI/ConfigWizard.cpp:721 +msgid "" +"Only the following installed printers are compatible with the selected " +"filament:" +msgstr "Тільки наступні встановлені принтери сумісні з обраним філаментом:" + +#: src/slic3r/GUI/ConfigWizard.cpp:1107 +msgid "Custom Printer Setup" +msgstr "Користувацьке налаштування принтера" + +#: src/slic3r/GUI/ConfigWizard.cpp:1107 +msgid "Custom Printer" +msgstr "Користувацький принтер" + +#: src/slic3r/GUI/ConfigWizard.cpp:1109 +msgid "Define a custom printer profile" +msgstr "Визначте власний профіль принтера" + +#: src/slic3r/GUI/ConfigWizard.cpp:1111 +msgid "Custom profile name:" +msgstr "Користувацьке ім'я пресету:" + +#: src/slic3r/GUI/ConfigWizard.cpp:1136 +msgid "Automatic updates" +msgstr "Автоматичні оновлення" + +#: src/slic3r/GUI/ConfigWizard.cpp:1136 +msgid "Updates" +msgstr "Оновлення" + +#: src/slic3r/GUI/ConfigWizard.cpp:1144 src/slic3r/GUI/Preferences.cpp:94 +msgid "Check for application updates" +msgstr "Перевірте наявність оновлень програми" + +#: src/slic3r/GUI/ConfigWizard.cpp:1148 +#, c-format +msgid "" +"If enabled, %s checks for new application versions online. When a new " +"version becomes available, a notification is displayed at the next " "application startup (never during program usage). This is only a " "notification mechanisms, no automatic installation is done." msgstr "" +"Якщо цей параметр увімкнено, %s перевіряє наявність нової версії онлайн. " +"Коли нова версія стає доступною, сповіщення відображатиметься під час " +"наступного запуску застосування (ніколи не під час використання програми). " +"Це лише механізми сповіщення, автоматична інсталяція не виконується." -#: src/slic3r/GUI/ConfigWizard.cpp:405 src/slic3r/GUI/Preferences.cpp:67 +#: src/slic3r/GUI/ConfigWizard.cpp:1154 src/slic3r/GUI/Preferences.cpp:129 msgid "Update built-in Presets automatically" -msgstr "" +msgstr "Автоматично оновлювати вбудовані пресети" -#: src/slic3r/GUI/ConfigWizard.cpp:408 src/slic3r/GUI/Preferences.cpp:69 +#: src/slic3r/GUI/ConfigWizard.cpp:1158 +#, c-format msgid "" -"If enabled, Slic3r downloads updates of built-in system presets in the " -"background. These updates are downloaded into a separate temporary location. " +"If enabled, %s downloads updates of built-in system presets in the " +"background.These updates are downloaded into a separate temporary location." "When a new preset version becomes available it is offered at application " "startup." msgstr "" +"Якщо увімкнено, %s завантажує оновлення вбудованих системних пресетів у " +"фоновому режимі. Ці оновлення завантажуються в окреме тимчасове місце. Коли " +"з’являється нова попередньо встановлена версія, вона пропонується під час " +"запуску програми." -#: src/slic3r/GUI/ConfigWizard.cpp:409 +#: src/slic3r/GUI/ConfigWizard.cpp:1161 msgid "" "Updates are never applied without user's consent and never overwrite user's " "customized settings." msgstr "" +"Оновлення ніколи не застосовуються без згоди користувача та ніколи не " +"перезаписують власні налаштування користувача." -#: src/slic3r/GUI/ConfigWizard.cpp:414 +#: src/slic3r/GUI/ConfigWizard.cpp:1166 msgid "" "Additionally a backup snapshot of the whole configuration is created before " "an update is applied." msgstr "" +"Крім того, перед застосуванням оновлення створюється резервний знімок всієї " +"конфігурації." -#: src/slic3r/GUI/ConfigWizard.cpp:421 +#: src/slic3r/GUI/ConfigWizard.cpp:1173 src/slic3r/GUI/GUI_ObjectList.cpp:1825 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4567 src/slic3r/GUI/Plater.cpp:3116 +#: src/slic3r/GUI/Plater.cpp:4001 src/slic3r/GUI/Plater.cpp:4032 +msgid "Reload from disk" +msgstr "Перезавантажити з диска" + +#: src/slic3r/GUI/ConfigWizard.cpp:1176 +msgid "" +"Export full pathnames of models and parts sources into 3mf and amf files" +msgstr "" +"Експортуйте повні назви шляхів джерел моделей та частей у файли 3MF та AMF" + +#: src/slic3r/GUI/ConfigWizard.cpp:1180 +msgid "" +"If enabled, allows the Reload from disk command to automatically find and " +"load the files when invoked.\n" +"If not enabled, the Reload from disk command will ask to select each file " +"using an open file dialog." +msgstr "" +"Якщо ввімкнено, дозволяє команді «Перезавантажити з диска» автоматично " +"знаходити та завантажувати файли при виклику.\n" +"Якщо не ввімкнено, команда «Перезавантажити з диска» попросить вибрати кожен " +"файл за допомогою діалогового вікна відкритого файлу." + +#: src/slic3r/GUI/ConfigWizard.cpp:1190 +msgid "Files association" +msgstr "Асоціація файлів" + +#: src/slic3r/GUI/ConfigWizard.cpp:1192 src/slic3r/GUI/Preferences.cpp:112 +msgid "Associate .3mf files to PrusaSlicer" +msgstr "Асоціювати 3MF-файли з PrusaSlicer" + +#: src/slic3r/GUI/ConfigWizard.cpp:1193 src/slic3r/GUI/Preferences.cpp:119 +msgid "Associate .stl files to PrusaSlicer" +msgstr "Асоціювати stl-файли з PrusaSlicer" + +#: src/slic3r/GUI/ConfigWizard.cpp:1204 +msgid "View mode" +msgstr "Режим перегляду" + +#: src/slic3r/GUI/ConfigWizard.cpp:1206 +msgid "" +"PrusaSlicer's user interfaces comes in three variants:\n" +"Simple, Advanced, and Expert.\n" +"The Simple mode shows only the most frequently used settings relevant for " +"regular 3D printing. The other two offer progressively more sophisticated " +"fine-tuning, they are suitable for advanced and expert users, respectively." +msgstr "" +"Користувацький інтерфейс PrusaSlicer поставляються в трьох варіантах:\n" +"Простий, Розширений та Експертний.\n" +"У простому режимі відображаються лише найбільш часто використовувані " +"налаштування, що стосуються звичайного 3D-друку. Два інших пропонують " +"поступово більш досконалу точну настройку, вони підходять для більш " +"досвідчених користувачів." + +#: src/slic3r/GUI/ConfigWizard.cpp:1211 +msgid "Simple mode" +msgstr "Простий режим" + +#: src/slic3r/GUI/ConfigWizard.cpp:1212 +msgid "Advanced mode" +msgstr "Розширений режим" + +#: src/slic3r/GUI/ConfigWizard.cpp:1213 +msgid "Expert mode" +msgstr "Експертний режим" + +#: src/slic3r/GUI/ConfigWizard.cpp:1219 +msgid "The size of the object can be specified in inches" +msgstr "Розмір предмета можна вказати в дюймах" + +#: src/slic3r/GUI/ConfigWizard.cpp:1220 +msgid "Use inches" +msgstr "Використовувати дюйми" + +#: src/slic3r/GUI/ConfigWizard.cpp:1254 msgid "Other Vendors" -msgstr "" +msgstr "Інші постачальники" -#: src/slic3r/GUI/ConfigWizard.cpp:423 -msgid "Pick another vendor supported by Slic3r PE:" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:1258 +#, c-format +msgid "Pick another vendor supported by %s" +msgstr "Виберіть іншого постачальника, який підтримує %s" -#: src/slic3r/GUI/ConfigWizard.cpp:469 +#: src/slic3r/GUI/ConfigWizard.cpp:1289 msgid "Firmware Type" -msgstr "" +msgstr "Тип прошивки" -#: src/slic3r/GUI/ConfigWizard.cpp:469 src/slic3r/GUI/Tab.cpp:1870 +#: src/slic3r/GUI/ConfigWizard.cpp:1289 src/slic3r/GUI/Tab.cpp:2172 msgid "Firmware" msgstr "Прошивка" -#: src/slic3r/GUI/ConfigWizard.cpp:473 +#: src/slic3r/GUI/ConfigWizard.cpp:1293 msgid "Choose the type of firmware used by your printer." -msgstr "" +msgstr "Виберіть тип прошивки, що використовуються вашим принтером." -#: src/slic3r/GUI/ConfigWizard.cpp:507 +#: src/slic3r/GUI/ConfigWizard.cpp:1327 msgid "Bed Shape and Size" -msgstr "" +msgstr "Форма та розмір столу" -#: src/slic3r/GUI/ConfigWizard.cpp:510 +#: src/slic3r/GUI/ConfigWizard.cpp:1330 msgid "Set the shape of your printer's bed." -msgstr "" +msgstr "Встановіть форму столу свого принтеру." -#: src/slic3r/GUI/ConfigWizard.cpp:524 +#: src/slic3r/GUI/ConfigWizard.cpp:1350 msgid "Filament and Nozzle Diameters" -msgstr "" +msgstr "Діаметри філатенту та сопла" -#: src/slic3r/GUI/ConfigWizard.cpp:524 +#: src/slic3r/GUI/ConfigWizard.cpp:1350 msgid "Print Diameters" -msgstr "" +msgstr "Діаметри друку" -#: src/slic3r/GUI/ConfigWizard.cpp:540 +#: src/slic3r/GUI/ConfigWizard.cpp:1364 msgid "Enter the diameter of your printer's hot end nozzle." -msgstr "" +msgstr "Введіть діаметр кінчику екструдерного сопла." -#: src/slic3r/GUI/ConfigWizard.cpp:543 +#: src/slic3r/GUI/ConfigWizard.cpp:1367 msgid "Nozzle Diameter:" -msgstr "" +msgstr "Діаметр сопла:" -#: src/slic3r/GUI/ConfigWizard.cpp:553 +#: src/slic3r/GUI/ConfigWizard.cpp:1377 msgid "Enter the diameter of your filament." -msgstr "" +msgstr "Введіть діаметр вашого філаметну." -#: src/slic3r/GUI/ConfigWizard.cpp:554 +#: src/slic3r/GUI/ConfigWizard.cpp:1378 msgid "" "Good precision is required, so use a caliper and do multiple measurements " "along the filament, then compute the average." msgstr "" +"Необхідна висока точність, тому використовуйте калібрувальник і виконайте " +"декілька вимірювань вздовж філаменту, потім обчисліть середнє значення." -#: src/slic3r/GUI/ConfigWizard.cpp:557 +#: src/slic3r/GUI/ConfigWizard.cpp:1381 msgid "Filament Diameter:" -msgstr "" +msgstr "Діаметр філаменту:" -#: src/slic3r/GUI/ConfigWizard.cpp:575 -msgid "Extruder and Bed Temperatures" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:1415 +msgid "Nozzle and Bed Temperatures" +msgstr "Температура сопла та столу" -#: src/slic3r/GUI/ConfigWizard.cpp:575 +#: src/slic3r/GUI/ConfigWizard.cpp:1415 msgid "Temperatures" -msgstr "" +msgstr "Температури" -#: src/slic3r/GUI/ConfigWizard.cpp:591 +#: src/slic3r/GUI/ConfigWizard.cpp:1431 msgid "Enter the temperature needed for extruding your filament." -msgstr "" +msgstr "Введіть температуру, необхідну для екструдування вашого філаменту." -#: src/slic3r/GUI/ConfigWizard.cpp:592 +#: src/slic3r/GUI/ConfigWizard.cpp:1432 msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." -msgstr "" +msgstr "Зазвичай - 160-230°C для PLA та 215-250°C для ABS." -#: src/slic3r/GUI/ConfigWizard.cpp:595 +#: src/slic3r/GUI/ConfigWizard.cpp:1435 msgid "Extrusion Temperature:" -msgstr "" +msgstr "Температура екструзії:" -#: src/slic3r/GUI/ConfigWizard.cpp:596 src/slic3r/GUI/ConfigWizard.cpp:610 +#: src/slic3r/GUI/ConfigWizard.cpp:1436 src/slic3r/GUI/ConfigWizard.cpp:1450 +#: src/libslic3r/PrintConfig.cpp:202 src/libslic3r/PrintConfig.cpp:950 +#: src/libslic3r/PrintConfig.cpp:994 src/libslic3r/PrintConfig.cpp:2294 msgid "°C" -msgstr "" +msgstr "°C" -#: src/slic3r/GUI/ConfigWizard.cpp:605 +#: src/slic3r/GUI/ConfigWizard.cpp:1445 msgid "" "Enter the bed temperature needed for getting your filament to stick to your " "heated bed." msgstr "" +"Введіть температуру столу, необхідну для того, щоб ваш філамент добре " +"кріпився до нагрітого столу." -#: src/slic3r/GUI/ConfigWizard.cpp:606 +#: src/slic3r/GUI/ConfigWizard.cpp:1446 msgid "" "A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have " "no heated bed." msgstr "" +"Зазвичай - 60°C для PLA та 110°C для ABS. Залиште рівним нулю, якщо стіл " +"нерозігрітий." -#: src/slic3r/GUI/ConfigWizard.cpp:609 +#: src/slic3r/GUI/ConfigWizard.cpp:1449 msgid "Bed Temperature:" -msgstr "" +msgstr "Температура столу:" -#: src/slic3r/GUI/ConfigWizard.cpp:1001 +#: src/slic3r/GUI/ConfigWizard.cpp:1909 src/slic3r/GUI/ConfigWizard.cpp:2582 +msgid "Filaments" +msgstr "Філаменти" + +#: src/slic3r/GUI/ConfigWizard.cpp:1909 src/slic3r/GUI/ConfigWizard.cpp:2584 +msgid "SLA Materials" +msgstr "SLA-матеріали" + +#: src/slic3r/GUI/ConfigWizard.cpp:1963 +msgid "FFF Technology Printers" +msgstr "Принтери технології FFF" + +#: src/slic3r/GUI/ConfigWizard.cpp:1968 +msgid "SLA Technology Printers" +msgstr "Принтери технології SLA" + +#: src/slic3r/GUI/ConfigWizard.cpp:2274 src/slic3r/GUI/DoubleSlider.cpp:2245 +#: src/slic3r/GUI/DoubleSlider.cpp:2265 src/slic3r/GUI/GUI.cpp:244 +msgid "Notice" +msgstr "Зауваження" + +#: src/slic3r/GUI/ConfigWizard.cpp:2295 +msgid "The following FFF printer models have no filament selected:" +msgstr "Наступні моделі FFF-принтерів не мають вибраного філаменту:" + +#: src/slic3r/GUI/ConfigWizard.cpp:2299 +msgid "Do you want to select default filaments for these FFF printer models?" +msgstr "" +"Ви хочете вибрати філаменти за замовчуванням для цих моделей FFF-принтерів?" + +#: src/slic3r/GUI/ConfigWizard.cpp:2313 +msgid "The following SLA printer models have no materials selected:" +msgstr "Наступні моделі SLA-принтерів не мають вибраного матеріалу:" + +#: src/slic3r/GUI/ConfigWizard.cpp:2317 +msgid "Do you want to select default SLA materials for these printer models?" +msgstr "" +"Ви хочете вибрати матеріали за замовчуванням для цих моделей SLA-принтерів?" + +#: src/slic3r/GUI/ConfigWizard.cpp:2545 msgid "Select all standard printers" -msgstr "" +msgstr "Виберіть усі стандартні принтери" -#: src/slic3r/GUI/ConfigWizard.cpp:1004 +#: src/slic3r/GUI/ConfigWizard.cpp:2548 msgid "< &Back" -msgstr "" +msgstr "< Назад" -#: src/slic3r/GUI/ConfigWizard.cpp:1005 +#: src/slic3r/GUI/ConfigWizard.cpp:2549 msgid "&Next >" -msgstr "" +msgstr "Далі >" -#: src/slic3r/GUI/ConfigWizard.cpp:1006 +#: src/slic3r/GUI/ConfigWizard.cpp:2550 msgid "&Finish" -msgstr "" +msgstr "Завершити" -#: src/slic3r/GUI/ConfigWizard.cpp:1007 src/slic3r/GUI/FirmwareDialog.cpp:142 -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:37 -#: src/slic3r/GUI/ProgressStatusBar.cpp:28 +#: src/slic3r/GUI/ConfigWizard.cpp:2551 src/slic3r/GUI/FirmwareDialog.cpp:151 +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:248 +#: src/slic3r/GUI/ProgressStatusBar.cpp:26 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:656 msgid "Cancel" -msgstr "" +msgstr "Скасувати" -#: src/slic3r/GUI/ConfigWizard.cpp:1021 +#: src/slic3r/GUI/ConfigWizard.cpp:2564 msgid "Prusa FFF Technology Printers" -msgstr "" +msgstr "Принтери технології FFF" -#: src/slic3r/GUI/ConfigWizard.cpp:1024 +#: src/slic3r/GUI/ConfigWizard.cpp:2567 msgid "Prusa MSLA Technology Printers" -msgstr "" +msgstr "Принтери технології MSLA" -#: src/slic3r/GUI/ConfigWizard.cpp:1111 -msgid "Configuration Wizard" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:2582 +msgid "Filament Profiles Selection" +msgstr "Вибір профілів філаменту" -#: src/slic3r/GUI/ConfigWizard.cpp:1112 -msgid "Configuration &Wizard" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:2582 src/slic3r/GUI/ConfigWizard.cpp:2584 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4144 +msgid "Type:" +msgstr "Тип:" -#: src/slic3r/GUI/ConfigWizard.cpp:1114 +#: src/slic3r/GUI/ConfigWizard.cpp:2584 +msgid "SLA Material Profiles Selection" +msgstr "Вибір профілів SLA-матеріалу" + +#: src/slic3r/GUI/ConfigWizard.cpp:2701 msgid "Configuration Assistant" -msgstr "" +msgstr "Асистент конфігурації" -#: src/slic3r/GUI/ConfigWizard.cpp:1115 +#: src/slic3r/GUI/ConfigWizard.cpp:2702 msgid "Configuration &Assistant" -msgstr "" +msgstr "Асистент конфігурації" -#: src/slic3r/GUI/Field.cpp:112 -msgid "default value" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:2704 +msgid "Configuration Wizard" +msgstr "Майстер конфігурації" -#: src/slic3r/GUI/Field.cpp:115 -msgid "parameter name" -msgstr "" +#: src/slic3r/GUI/ConfigWizard.cpp:2705 +msgid "Configuration &Wizard" +msgstr "Майстер конфігурації" -#: src/slic3r/GUI/Field.cpp:143 -#, c-format -msgid "%s doesn't support percentage" -msgstr "" +#: src/slic3r/GUI/DoubleSlider.cpp:97 +msgid "Place bearings in slots and resume printing" +msgstr "Розмістіть необхідні деталі в гніздах і відновіть друк" -#: src/slic3r/GUI/Field.cpp:157 src/slic3r/GUI/Field.cpp:180 -msgid "Invalid numeric input." -msgstr "" +#: src/slic3r/GUI/DoubleSlider.cpp:1224 +msgid "One layer mode" +msgstr "Одношаровий режим" -#: src/slic3r/GUI/Field.cpp:162 -msgid "Input value is out of range" -msgstr "" +#: src/slic3r/GUI/DoubleSlider.cpp:1226 +msgid "Discard all custom changes" +msgstr "Відхилити всі користувацькі зміни" -#: src/slic3r/GUI/Field.cpp:188 +#: src/slic3r/GUI/DoubleSlider.cpp:1230 src/slic3r/GUI/DoubleSlider.cpp:1995 +msgid "Jump to move" +msgstr "Перейти до руху" + +#: src/slic3r/GUI/DoubleSlider.cpp:1233 #, c-format msgid "" -"Do you mean %d%% instead of %d %s?\n" -"Select YES if you want to change this value to %d%%, \n" -"or NO if you are sure that %d %s is a correct value." +"Jump to height %s\n" +"Set ruler mode\n" +"or Set extruder sequence for the entire print" msgstr "" +"Перейти на висоту %s\n" +"Налаштувати режим лінійки\n" +"або Налаштувати послідовність екструдерів для поточного тіску" -#: src/slic3r/GUI/Field.cpp:191 +#: src/slic3r/GUI/DoubleSlider.cpp:1236 +#, c-format +msgid "" +"Jump to height %s\n" +"or Set ruler mode" +msgstr "" +"Перейти на висоту %s\n" +"або Налаштувати режим лінійки" + +#: src/slic3r/GUI/DoubleSlider.cpp:1241 +msgid "Edit current color - Right click the colored slider segment" +msgstr "" +"Редагувати поточний колір - Клацніть правою кнопкою миші на кольоровий " +"сегмент повзунка" + +#: src/slic3r/GUI/DoubleSlider.cpp:1251 +msgid "Print mode" +msgstr "Режим друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1265 +msgid "Add extruder change - Left click" +msgstr "Додати зміну екструдеру - ліва кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1267 +msgid "" +"Add color change - Left click for predefined color or Shift + Left click for " +"custom color selection" +msgstr "" +"Додати зміну кольору - ліва кнопка миші для попередньо визначеного кольору " +"або Shift + ліва кнопка миші для властного вибору кольору" + +#: src/slic3r/GUI/DoubleSlider.cpp:1269 +msgid "Add color change - Left click" +msgstr "Додати зміну кольору - ліва кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1270 +msgid "or press \"+\" key" +msgstr "або натисніть клавішу \"+\"" + +#: src/slic3r/GUI/DoubleSlider.cpp:1272 +msgid "Add another code - Ctrl + Left click" +msgstr "Додайте інший код - Ctrl + ліва кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1273 +msgid "Add another code - Right click" +msgstr "Додайте інший код - права кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1279 +msgid "" +"The sequential print is on.\n" +"It's impossible to apply any custom G-code for objects printing " +"sequentually.\n" +"This code won't be processed during G-code generation." +msgstr "" +"Послідовний друк увімкнено.\n" +"Неможливо застосувати будь-який власний G-код для послідовного друку " +"об'єктів.\n" +"Цей код не буде оброблятися під час створення G-коду." + +#: src/slic3r/GUI/DoubleSlider.cpp:1288 +msgid "Color change (\"%1%\")" +msgstr "Зміну кольору (\"%1%\")" + +#: src/slic3r/GUI/DoubleSlider.cpp:1289 +msgid "Color change (\"%1%\") for Extruder %2%" +msgstr "Зміну кольору (\"%1%\") для екструдеру %2%" + +#: src/slic3r/GUI/DoubleSlider.cpp:1291 +msgid "Pause print (\"%1%\")" +msgstr "Пауза друку (\"%1%\")" + +#: src/slic3r/GUI/DoubleSlider.cpp:1293 +msgid "Custom template (\"%1%\")" +msgstr "Користувацький шаблон (\"%1%\")" + +#: src/slic3r/GUI/DoubleSlider.cpp:1295 +msgid "Extruder (tool) is changed to Extruder \"%1%\"" +msgstr "Екструдер (інструмент) змінено на Екструдер \"%1%\"" + +#: src/slic3r/GUI/DoubleSlider.cpp:1302 +msgid "Note" +msgstr "Примітка" + +#: src/slic3r/GUI/DoubleSlider.cpp:1304 +msgid "" +"G-code associated to this tick mark is in a conflict with print mode.\n" +"Editing it will cause changes of Slider data." +msgstr "" +"G-код, пов'язаний з цим маркером, суперечить режиму друку.\n" +"Редагування призведе до змін даних повзунка." + +#: src/slic3r/GUI/DoubleSlider.cpp:1307 +msgid "" +"There is a color change for extruder that won't be used till the end of " +"print job.\n" +"This code won't be processed during G-code generation." +msgstr "" +"Змінено колір екструдера, який не використовуватиметься до кінця завдання " +"друку.\n" +"Цей код не буде оброблятися під час створення G-коду." + +#: src/slic3r/GUI/DoubleSlider.cpp:1310 +msgid "" +"There is an extruder change set to the same extruder.\n" +"This code won't be processed during G-code generation." +msgstr "" +"Існує зміна екструдера, встановлена на той самий екструдер.\n" +"Цей код не буде оброблятися під час створення G-коду." + +#: src/slic3r/GUI/DoubleSlider.cpp:1313 +msgid "" +"There is a color change for extruder that has not been used before.\n" +"Check your settings to avoid redundant color changes." +msgstr "" +"Змінюється колір екструдера, який раніше не застосовувався.\n" +"Перевірте свої налаштування, щоб уникнути зайвих змін кольору." + +#: src/slic3r/GUI/DoubleSlider.cpp:1318 +msgid "Delete tick mark - Left click or press \"-\" key" +msgstr "" +"Видалити маркер - клацніть лівою кнопкою миші або натисніть клавішу \"-\"" + +#: src/slic3r/GUI/DoubleSlider.cpp:1320 +msgid "Edit tick mark - Ctrl + Left click" +msgstr "Змінити маркер - Ctrl+Ліва кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1321 +msgid "Edit tick mark - Right click" +msgstr "Змінити маркер - Права кнопка миші" + +#: src/slic3r/GUI/DoubleSlider.cpp:1417 src/slic3r/GUI/DoubleSlider.cpp:1451 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1864 +#, c-format +msgid "Extruder %d" +msgstr "Екструдер %d" + +#: src/slic3r/GUI/DoubleSlider.cpp:1418 src/slic3r/GUI/GUI_ObjectList.cpp:1865 +msgid "active" +msgstr "активний" + +#: src/slic3r/GUI/DoubleSlider.cpp:1427 +msgid "Switch code to Change extruder" +msgstr "Переключити код на \"Змінити екструдер\"" + +#: src/slic3r/GUI/DoubleSlider.cpp:1427 src/slic3r/GUI/GUI_ObjectList.cpp:1832 +msgid "Change extruder" +msgstr "Змінити екструдер" + +#: src/slic3r/GUI/DoubleSlider.cpp:1428 +msgid "Change extruder (N/A)" +msgstr "Змінити екструдер (Недоступний)" + +#: src/slic3r/GUI/DoubleSlider.cpp:1430 +msgid "Use another extruder" +msgstr "Використати інший екструдер" + +#: src/slic3r/GUI/DoubleSlider.cpp:1452 +msgid "used" +msgstr "використовується" + +#: src/slic3r/GUI/DoubleSlider.cpp:1460 +msgid "Switch code to Color change (%1%) for:" +msgstr "Переключити код на \"Змінити колір\" (%1%) для:" + +#: src/slic3r/GUI/DoubleSlider.cpp:1461 +msgid "Add color change (%1%) for:" +msgstr "Додати зміну кольору (%1%) для:" + +#: src/slic3r/GUI/DoubleSlider.cpp:1797 +msgid "Add color change" +msgstr "Додати зміну кольору" + +#: src/slic3r/GUI/DoubleSlider.cpp:1808 +msgid "Add pause print" +msgstr "Додати паузу друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1812 +msgid "Add custom template" +msgstr "Додати власний шаблон" + +#: src/slic3r/GUI/DoubleSlider.cpp:1815 +msgid "Add custom G-code" +msgstr "Додати власний G-код" + +#: src/slic3r/GUI/DoubleSlider.cpp:1833 +msgid "Edit color" +msgstr "Редагувати колір" + +#: src/slic3r/GUI/DoubleSlider.cpp:1834 +msgid "Edit pause print message" +msgstr "Редагувати повідомлення під час паузи друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1835 +msgid "Edit custom G-code" +msgstr "Редагувати власний G-код" + +#: src/slic3r/GUI/DoubleSlider.cpp:1841 +msgid "Delete color change" +msgstr "Видалити зміну кольору" + +#: src/slic3r/GUI/DoubleSlider.cpp:1842 +msgid "Delete tool change" +msgstr "Видалити зміну інструменту" + +#: src/slic3r/GUI/DoubleSlider.cpp:1843 +msgid "Delete pause print" +msgstr "Видалити паузу друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1844 +msgid "Delete custom G-code" +msgstr "Видалити власний G-код" + +#: src/slic3r/GUI/DoubleSlider.cpp:1854 src/slic3r/GUI/DoubleSlider.cpp:1995 +msgid "Jump to height" +msgstr "Перейти на висоту" + +#: src/slic3r/GUI/DoubleSlider.cpp:1859 +msgid "Hide ruler" +msgstr "Сховати лінійку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1863 +msgid "Show object height" +msgstr "Показувати висоту об’єкта" + +#: src/slic3r/GUI/DoubleSlider.cpp:1863 +msgid "Show object height on the ruler" +msgstr "Показувати висоту об’єкта на лінійці" + +#: src/slic3r/GUI/DoubleSlider.cpp:1867 +msgid "Show estimated print time" +msgstr "Показувати приблизний час друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1867 +msgid "Show estimated print time on the ruler" +msgstr "Показувати приблизний час друку на лінійці" + +#: src/slic3r/GUI/DoubleSlider.cpp:1871 +msgid "Ruler mode" +msgstr "Режим лінійки" + +#: src/slic3r/GUI/DoubleSlider.cpp:1871 +msgid "Set ruler mode" +msgstr "Встановити режим лінійки" + +#: src/slic3r/GUI/DoubleSlider.cpp:1876 +msgid "Set extruder sequence for the entire print" +msgstr "Встановити послідовність екструдерів для всього друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1962 +msgid "Enter custom G-code used on current layer" +msgstr "Введіть власний G-код, для використання на поточному шарі" + +#: src/slic3r/GUI/DoubleSlider.cpp:1963 +msgid "Custom G-code on current layer (%1% mm)." +msgstr "Користувацький G-код на поточному шарі (%1% мм)." + +#: src/slic3r/GUI/DoubleSlider.cpp:1978 +msgid "Enter short message shown on Printer display when a print is paused" +msgstr "" +"Введіть коротке повідомлення, що відображатиметься на дисплеї принтера піж " +"час паузи друку" + +#: src/slic3r/GUI/DoubleSlider.cpp:1979 +msgid "Message for pause print on current layer (%1% mm)." +msgstr "Повідомлення для паузи друку на поточному шарі (%1% мм)." + +#: src/slic3r/GUI/DoubleSlider.cpp:1994 +msgid "Enter the move you want to jump to" +msgstr "Введіть рух, до якого ви хочете перейти" + +#: src/slic3r/GUI/DoubleSlider.cpp:1994 +msgid "Enter the height you want to jump to" +msgstr "Введіть висоту, на яку ви хочете перейти" + +#: src/slic3r/GUI/DoubleSlider.cpp:2239 +msgid "The last color change data was saved for a single extruder printing." +msgstr "" +"Дані про останню зміну кольору були збережені для одно-екструдерного друку." + +#: src/slic3r/GUI/DoubleSlider.cpp:2240 src/slic3r/GUI/DoubleSlider.cpp:2255 +msgid "The last color change data was saved for a multi extruder printing." +msgstr "" +"Дані про останню зміну кольору були збережені для багато-екструдерного друку." + +#: src/slic3r/GUI/DoubleSlider.cpp:2242 +msgid "Your current changes will delete all saved color changes." +msgstr "Ваші поточні зміни видалять усі збережені зміни кольору." + +#: src/slic3r/GUI/DoubleSlider.cpp:2243 src/slic3r/GUI/DoubleSlider.cpp:2263 +msgid "Are you sure you want to continue?" +msgstr "Ви впевнені, що хочете продовжити?" + +#: src/slic3r/GUI/DoubleSlider.cpp:2256 +msgid "" +"Select YES if you want to delete all saved tool changes, \n" +"NO if you want all tool changes switch to color changes, \n" +"or CANCEL to leave it unchanged." +msgstr "" +"Виберіть ТАК, якщо ви хочете видалити всі збережені зміни інструменту,\n" +"НІ, якщо ви хочете, щоб усі зміни інструменту було змінено на зміну " +"кольору,\n" +"або СКАСУВАТИ, щоб залишити це без змін." + +#: src/slic3r/GUI/DoubleSlider.cpp:2259 +msgid "Do you want to delete all saved tool changes?" +msgstr "Ви хочете видалити всі збережені зміни інструменту?" + +#: src/slic3r/GUI/DoubleSlider.cpp:2261 +msgid "" +"The last color change data was saved for a multi extruder printing with tool " +"changes for whole print." +msgstr "" +"Дані про останню зміну кольору були збережені для багато-екструдерного друку " +"зі зміною інструменту для цілого друку." + +#: src/slic3r/GUI/DoubleSlider.cpp:2262 +msgid "Your current changes will delete all saved extruder (tool) changes." +msgstr "" +"Ваші поточні зміни видалять усі збережені зміни екструдера (інструменту)." + +#: src/slic3r/GUI/ExtraRenderers.cpp:297 src/slic3r/GUI/GUI_ObjectList.cpp:512 +#: src/slic3r/GUI/GUI_ObjectList.cpp:524 src/slic3r/GUI/GUI_ObjectList.cpp:1033 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4582 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4592 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4627 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:209 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:266 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:291 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:499 src/libslic3r/PrintConfig.cpp:552 +msgid "default" +msgstr "за замовчанням" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:24 +msgid "Set extruder sequence" +msgstr "Встановити послідовність екструдерів" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:40 +msgid "Set extruder change for every" +msgstr "Встановіть зміну екструдера для кожних" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:53 +#: src/libslic3r/PrintConfig.cpp:418 src/libslic3r/PrintConfig.cpp:1089 +#: src/libslic3r/PrintConfig.cpp:1718 src/libslic3r/PrintConfig.cpp:1883 +#: src/libslic3r/PrintConfig.cpp:1950 src/libslic3r/PrintConfig.cpp:2157 +#: src/libslic3r/PrintConfig.cpp:2203 +msgid "layers" +msgstr "шару(ів)" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:137 +msgid "Set extruder(tool) sequence" +msgstr "Встановити послідовність екструдерів (інструментів)" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:183 +msgid "Remove extruder from sequence" +msgstr "Видалити екструдер з послідовності" + +#: src/slic3r/GUI/ExtruderSequenceDialog.cpp:193 +msgid "Add extruder to sequence" +msgstr "Додати екструдер до послідовності" + +#: src/slic3r/GUI/Field.cpp:197 +msgid "default value" +msgstr "значення за замовчанням" + +#: src/slic3r/GUI/Field.cpp:200 +msgid "parameter name" +msgstr "назва параметра" + +#: src/slic3r/GUI/Field.cpp:211 src/slic3r/GUI/OptionsGroup.cpp:781 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:886 +msgid "N/A" +msgstr "Н/Д" + +#: src/slic3r/GUI/Field.cpp:233 +#, c-format +msgid "%s doesn't support percentage" +msgstr "%s не підтримує відсотки" + +#: src/slic3r/GUI/Field.cpp:253 src/slic3r/GUI/Field.cpp:307 +#: src/slic3r/GUI/Field.cpp:1520 src/slic3r/GUI/GUI_ObjectLayers.cpp:413 +msgid "Invalid numeric input." +msgstr "Недійсне числове значення." + +#: src/slic3r/GUI/Field.cpp:264 +#, c-format +msgid "" +"Input value is out of range\n" +"Are you sure that %s is a correct value and that you want to continue?" +msgstr "" +"Вхідне значення виходить за межі діапазону\n" +"Ви впевнені, що %s є правильним значенням і хочете продовжити?" + +#: src/slic3r/GUI/Field.cpp:266 src/slic3r/GUI/Field.cpp:326 msgid "Parameter validation" -msgstr "" +msgstr "Перевірка параметрів" -#: src/slic3r/GUI/FirmwareDialog.cpp:141 +#: src/slic3r/GUI/Field.cpp:279 src/slic3r/GUI/Field.cpp:373 +#: src/slic3r/GUI/Field.cpp:1532 +msgid "Input value is out of range" +msgstr "Вхідне значення виходить за межі діапазону" + +#: src/slic3r/GUI/Field.cpp:323 +#, c-format +msgid "" +"Do you mean %s%% instead of %s %s?\n" +"Select YES if you want to change this value to %s%%, \n" +"or NO if you are sure that %s %s is a correct value." +msgstr "" +"Ви маєте на увазі %s%% замість %s %s?\n" +"Виберіть ТАК, якщо ви хочете змінити це значення на %s%%,\n" +"або НІ, якщо ви впевнені, що %s %s є правильним значенням." + +#: src/slic3r/GUI/Field.cpp:381 +msgid "" +"Invalid input format. Expected vector of dimensions in the following format: " +"\"%1%\"" +msgstr "" +"Недійсний формат введення. Очікується вектор розмірів у наступному форматі: " +"\"%1%\"" + +#: src/slic3r/GUI/FirmwareDialog.cpp:150 msgid "Flash!" -msgstr "" +msgstr "Прошити!" -#: src/slic3r/GUI/FirmwareDialog.cpp:143 +#: src/slic3r/GUI/FirmwareDialog.cpp:152 msgid "Flashing in progress. Please do not disconnect the printer!" -msgstr "" +msgstr "Триває прошивка. Будь ласка, не від'єднуй принтер!" -#: src/slic3r/GUI/FirmwareDialog.cpp:187 -msgid "Flashing failed: " -msgstr "" +#: src/slic3r/GUI/FirmwareDialog.cpp:199 +msgid "Flashing failed" +msgstr "Помилка прошивки" -#: src/slic3r/GUI/FirmwareDialog.cpp:268 +#: src/slic3r/GUI/FirmwareDialog.cpp:282 msgid "Flashing succeeded!" -msgstr "" +msgstr "Прошивка вдалася!" -#: src/slic3r/GUI/FirmwareDialog.cpp:269 +#: src/slic3r/GUI/FirmwareDialog.cpp:283 msgid "Flashing failed. Please see the avrdude log below." -msgstr "" +msgstr "Помилка прошивки. Будь ласка, переглянте журнал avrdude нижче." -#: src/slic3r/GUI/FirmwareDialog.cpp:270 +#: src/slic3r/GUI/FirmwareDialog.cpp:284 msgid "Flashing cancelled." -msgstr "" +msgstr "Прошивку скасовано." -#: src/slic3r/GUI/FirmwareDialog.cpp:308 +#: src/slic3r/GUI/FirmwareDialog.cpp:332 #, c-format msgid "" "This firmware hex file does not match the printer model.\n" @@ -574,1779 +1531,4036 @@ msgid "" "Do you want to continue and flash this hex file anyway?\n" "Please only continue if you are sure this is the right thing to do." msgstr "" +"Цей hex-файл не відповідає моделі принтера.\n" +"Даний hex-файл призначений для: %s\n" +"Повідомлено для принтеру: %s\n" +"\n" +"Продовжити роботу та все одно прошити цей hex-файл?\n" +"Будь ласка, продовжуйте, тільки якщо ви впевнені, що це правильно робити." -#: src/slic3r/GUI/FirmwareDialog.cpp:395 src/slic3r/GUI/FirmwareDialog.cpp:431 +#: src/slic3r/GUI/FirmwareDialog.cpp:419 src/slic3r/GUI/FirmwareDialog.cpp:454 #, c-format msgid "" "Multiple %s devices found. Please only connect one at a time for flashing." msgstr "" +"Знайдено кілька пристроїв %s . Будь ласка, підключайте лише один пристрій " +"для прошивки." -#: src/slic3r/GUI/FirmwareDialog.cpp:412 +#: src/slic3r/GUI/FirmwareDialog.cpp:436 #, c-format msgid "" "The %s device was not found.\n" "If the device is connected, please press the Reset button next to the USB " "connector ..." msgstr "" +"Пристрій %s не знайдено.\n" +"Якщо пристрій підключений, натисніть кнопку Скинути поруч з USB-роз'ємом ..." -#: src/slic3r/GUI/FirmwareDialog.cpp:525 +#: src/slic3r/GUI/FirmwareDialog.cpp:548 #, c-format msgid "The %s device could not have been found" -msgstr "" +msgstr "Пристрою %s не знайдено" -#: src/slic3r/GUI/FirmwareDialog.cpp:603 +#: src/slic3r/GUI/FirmwareDialog.cpp:645 #, c-format msgid "Error accessing port at %s: %s" -msgstr "" +msgstr "Помилка доступу до порту на %s: %s" -#: src/slic3r/GUI/FirmwareDialog.cpp:605 +#: src/slic3r/GUI/FirmwareDialog.cpp:647 #, c-format msgid "Error: %s" -msgstr "" +msgstr "Помилка: %s" -#: src/slic3r/GUI/FirmwareDialog.cpp:735 +#: src/slic3r/GUI/FirmwareDialog.cpp:777 msgid "Firmware flasher" -msgstr "" +msgstr "Пепепрошивка" -#: src/slic3r/GUI/FirmwareDialog.cpp:762 +#: src/slic3r/GUI/FirmwareDialog.cpp:802 msgid "Firmware image:" -msgstr "" +msgstr "Імідж прошивки:" -#: src/slic3r/GUI/FirmwareDialog.cpp:766 +#: src/slic3r/GUI/FirmwareDialog.cpp:805 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:289 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:364 +msgid "Browse" +msgstr "Переглянути" + +#: src/slic3r/GUI/FirmwareDialog.cpp:807 msgid "Serial port:" -msgstr "" +msgstr "Послідовний порт:" -#: src/slic3r/GUI/FirmwareDialog.cpp:768 +#: src/slic3r/GUI/FirmwareDialog.cpp:809 msgid "Autodetected" -msgstr "" +msgstr "Автоматично виявлено" -#: src/slic3r/GUI/FirmwareDialog.cpp:769 +#: src/slic3r/GUI/FirmwareDialog.cpp:810 msgid "Rescan" -msgstr "" +msgstr "Пересканувати" -#: src/slic3r/GUI/FirmwareDialog.cpp:776 +#: src/slic3r/GUI/FirmwareDialog.cpp:817 msgid "Progress:" -msgstr "" +msgstr "Прогрес:" -#: src/slic3r/GUI/FirmwareDialog.cpp:779 +#: src/slic3r/GUI/FirmwareDialog.cpp:820 msgid "Status:" -msgstr "" +msgstr "Статус:" -#: src/slic3r/GUI/FirmwareDialog.cpp:780 +#: src/slic3r/GUI/FirmwareDialog.cpp:821 msgid "Ready" -msgstr "" +msgstr "Готово" -#: src/slic3r/GUI/FirmwareDialog.cpp:800 +#: src/slic3r/GUI/FirmwareDialog.cpp:841 msgid "Advanced: Output log" -msgstr "" +msgstr "Розширений: журнал виводу" -#: src/slic3r/GUI/FirmwareDialog.cpp:811 -#: src/slic3r/GUI/PrintHostDialogs.cpp:161 +#: src/slic3r/GUI/FirmwareDialog.cpp:852 +#: src/slic3r/GUI/Mouse3DController.cpp:551 +#: src/slic3r/GUI/PrintHostDialogs.cpp:189 msgid "Close" -msgstr "" +msgstr "Закрити" -#: src/slic3r/GUI/FirmwareDialog.cpp:859 +#: src/slic3r/GUI/FirmwareDialog.cpp:902 msgid "" "Are you sure you want to cancel firmware flashing?\n" "This could leave your printer in an unusable state!" msgstr "" +"Ви впевнені, що хочете скасувати перепрошивку?\n" +"Це може привести ваш принтер у непридатний стан!" -#: src/slic3r/GUI/FirmwareDialog.cpp:860 +#: src/slic3r/GUI/FirmwareDialog.cpp:903 msgid "Confirmation" -msgstr "" +msgstr "Підтвердження" -#: src/slic3r/GUI/FirmwareDialog.cpp:863 +#: src/slic3r/GUI/FirmwareDialog.cpp:906 msgid "Cancelling..." -msgstr "" - -#: src/slic3r/GUI/GLCanvas3D.cpp:709 -msgid "Detected object outside print volume" -msgstr "" - -#: src/slic3r/GUI/GLCanvas3D.cpp:710 -msgid "Detected toolpath outside print volume" -msgstr "" - -#: src/slic3r/GUI/GLCanvas3D.cpp:711 -msgid "Some objects are not visible when editing supports" -msgstr "" - -#: src/slic3r/GUI/GLCanvas3D.cpp:713 -msgid "" -"Detected object outside print volume\n" -"Resolve a clash to continue slicing/export process correctly" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:35 -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:195 -msgid "Rotate lower part upwards" -msgstr "Повернути нижню частину вгору" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:36 -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:198 -msgid "Perform cut" -msgstr "Виконати розріз" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:43 -msgid "Cut object:" -msgstr "Розрізати об'єкт:" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:88 -msgid "Cut [C]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:188 src/libslic3r/PrintConfig.cpp:3006 -msgid "Cut" -msgstr "Розрізати" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:193 -msgid "Keep upper part" -msgstr "Залишити верхню частину" - -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:194 -msgid "Keep lower part" -msgstr "Залишити нижню частину" - -#: src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp:32 -msgid "Place on face [F]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:51 -msgid "Move [M]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:176 -msgid "Position (mm)" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:176 -msgid "Displacement (mm)" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:458 -msgid "Rotate [R]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:491 -msgid "Rotation (deg)" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:51 -msgid "Scale [S]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:276 -msgid "Scale (%)" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:597 -msgid "Left mouse click - add point" -msgstr "Ліва кнопка миші - додати точку" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:598 -msgid "Right mouse click - remove point" -msgstr "Права кнопка миші - видалити точку" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:599 -msgid "Shift + Left (+ drag) - select point(s)" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:606 -msgid "Head diameter: " -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:618 -msgid "Lock supports under new islands" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:622 -msgid "Remove selected points" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:626 -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:679 -msgid "Remove all points" -msgstr "Видалити всі точки" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:631 -msgid "Apply changes" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:636 -msgid "Discard changes" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:644 -msgid "Minimal points distance: " -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:655 -msgid "Support points density: " -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:669 -msgid "Auto-generate points [A]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:675 -msgid "Manual editing [M]" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:738 -msgid "SLA Support Points [L]" -msgstr "Точки SLA підтримки [L]" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:767 -msgid "Do you want to save your manually edited support points ?\n" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:768 -msgid "Save changes?" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:897 -msgid "" -"Autogeneration will erase all manually edited points.\n" -"\n" -"Are you sure you want to do it?\n" -msgstr "" - -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:899 src/slic3r/GUI/GUI.cpp:288 -#: src/slic3r/GUI/WipeTowerDialog.cpp:44 src/slic3r/GUI/WipeTowerDialog.cpp:328 -msgid "Warning" -msgstr "Застереження" - -#: src/slic3r/GUI/GUI.cpp:147 src/slic3r/GUI/Tab.cpp:2720 -msgid "It's impossible to print multi-part object(s) with SLA technology." -msgstr "" - -#: src/slic3r/GUI/GUI.cpp:148 -msgid "Please check and fix your object list." -msgstr "" - -#: src/slic3r/GUI/GUI.cpp:149 src/slic3r/GUI/GUI_App.cpp:679 -#: src/slic3r/GUI/Tab.cpp:2722 -msgid "Attention!" -msgstr "Увага!" - -#: src/slic3r/GUI/GUI.cpp:282 -msgid "Notice" -msgstr "Зауваження" - -#: src/slic3r/GUI/GUI_App.cpp:318 -msgid "Changing of an application language" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:326 src/slic3r/GUI/GUI_App.cpp:335 -msgid "Recreating" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:339 -msgid "Loading of a current presets" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:347 -msgid "Loading of a mode view" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:429 -msgid "Choose one file (3MF):" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:441 -msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Виберіть один чи кілька файлів (STL/OBJ/AMF/PRUSA):" - -#: src/slic3r/GUI/GUI_App.cpp:454 -msgid "Array of language names and identifiers should have the same size." -msgstr "Масив імен мов та їх ідентифікаторів має бути однакового розміру." - -#: src/slic3r/GUI/GUI_App.cpp:464 -msgid "Select the language" -msgstr "Оберіть мову" - -#: src/slic3r/GUI/GUI_App.cpp:464 -msgid "Language" -msgstr "Мова" - -#: src/slic3r/GUI/GUI_App.cpp:534 src/slic3r/GUI/GUI_ObjectList.cpp:1067 -#: src/libslic3r/PrintConfig.cpp:298 -msgid "Default" -msgstr "За замовчуванням" - -#: src/slic3r/GUI/GUI_App.cpp:603 -msgid "&Configuration Snapshots" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:603 -msgid "Inspect / activate configuration snapshots" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:604 -msgid "Take Configuration &Snapshot" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:604 -msgid "Capture a configuration snapshot" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:607 -msgid "&Preferences" -msgstr "&Преференції" - -#: src/slic3r/GUI/GUI_App.cpp:613 -msgid "Application preferences" -msgstr "Преференції застосування" - -#: src/slic3r/GUI/GUI_App.cpp:616 src/slic3r/GUI/wxExtensions.cpp:2446 -msgid "Simple" -msgstr "Простий" - -#: src/slic3r/GUI/GUI_App.cpp:616 -msgid "Simple View Mode" -msgstr "Простий режим перегляду" - -#: src/slic3r/GUI/GUI_App.cpp:617 src/slic3r/GUI/GUI_ObjectList.cpp:73 -#: src/slic3r/GUI/Tab.cpp:977 src/slic3r/GUI/Tab.cpp:992 -#: src/slic3r/GUI/Tab.cpp:1090 src/slic3r/GUI/Tab.cpp:1093 -#: src/slic3r/GUI/Tab.cpp:1466 src/slic3r/GUI/Tab.cpp:1890 -#: src/slic3r/GUI/Tab.cpp:3347 src/slic3r/GUI/wxExtensions.cpp:2447 -#: src/libslic3r/PrintConfig.cpp:72 src/libslic3r/PrintConfig.cpp:186 -#: src/libslic3r/PrintConfig.cpp:349 src/libslic3r/PrintConfig.cpp:987 -#: src/libslic3r/PrintConfig.cpp:2173 -msgid "Advanced" -msgstr "Розширений" - -#: src/slic3r/GUI/GUI_App.cpp:617 -msgid "Advanced View Mode" -msgstr "Розширений режим перегляду" - -#: src/slic3r/GUI/GUI_App.cpp:618 src/slic3r/GUI/wxExtensions.cpp:2448 -msgid "Expert" -msgstr "Експерт" - -#: src/slic3r/GUI/GUI_App.cpp:618 -msgid "Expert View Mode" -msgstr "Режим перегляду Експерт" - -#: src/slic3r/GUI/GUI_App.cpp:623 -msgid "Mode" -msgstr "Режим" - -#: src/slic3r/GUI/GUI_App.cpp:623 -msgid "Slic3r View Mode" -msgstr "Режим перегляду Slic3r'у" - -#: src/slic3r/GUI/GUI_App.cpp:625 -msgid "Change Application &Language" -msgstr "Змінити &мову застосування" - -#: src/slic3r/GUI/GUI_App.cpp:627 -msgid "Flash printer &firmware" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:627 -msgid "Upload a firmware image into an Arduino based printer" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:639 -msgid "Taking configuration snapshot" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:639 -msgid "Snapshot name" -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:676 -msgid "Application will be restarted after language change." -msgstr "Застосування буде перезапущене після зміни мови." - -#: src/slic3r/GUI/GUI_App.cpp:677 -msgid "3D-Scene will be cleaned." -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:678 -msgid "Please, check your changes before." -msgstr "" - -#: src/slic3r/GUI/GUI_App.cpp:706 -msgid "&Configuration" -msgstr "&Конфігурація" - -#: src/slic3r/GUI/GUI_App.cpp:726 -msgid "You have unsaved changes " -msgstr "У вас є незбережені зміни " - -#: src/slic3r/GUI/GUI_App.cpp:726 -msgid ". Discard changes and continue anyway?" -msgstr ". Відхилити зміни і продовжити в будь-якому випадку?" - -#: src/slic3r/GUI/GUI_App.cpp:727 -msgid "Unsaved Presets" -msgstr "Незбереженні налаштування" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:28 src/slic3r/GUI/GUI_ObjectList.cpp:65 -#: src/libslic3r/PrintConfig.cpp:56 src/libslic3r/PrintConfig.cpp:149 -#: src/libslic3r/PrintConfig.cpp:380 src/libslic3r/PrintConfig.cpp:437 -#: src/libslic3r/PrintConfig.cpp:445 src/libslic3r/PrintConfig.cpp:841 -#: src/libslic3r/PrintConfig.cpp:1025 src/libslic3r/PrintConfig.cpp:1304 -#: src/libslic3r/PrintConfig.cpp:1370 src/libslic3r/PrintConfig.cpp:1551 -#: src/libslic3r/PrintConfig.cpp:1986 src/libslic3r/PrintConfig.cpp:2042 -msgid "Layers and Perimeters" -msgstr "Шари та периметри" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:29 src/slic3r/GUI/GUI_ObjectList.cpp:66 -#: src/slic3r/GUI/Plater.cpp:431 src/slic3r/GUI/Tab.cpp:981 -#: src/slic3r/GUI/Tab.cpp:982 src/slic3r/GUI/Tab.cpp:1311 -#: src/libslic3r/PrintConfig.cpp:166 src/libslic3r/PrintConfig.cpp:388 -#: src/libslic3r/PrintConfig.cpp:728 src/libslic3r/PrintConfig.cpp:742 -#: src/libslic3r/PrintConfig.cpp:779 src/libslic3r/PrintConfig.cpp:932 -#: src/libslic3r/PrintConfig.cpp:942 src/libslic3r/PrintConfig.cpp:960 -#: src/libslic3r/PrintConfig.cpp:978 src/libslic3r/PrintConfig.cpp:997 -#: src/libslic3r/PrintConfig.cpp:1658 src/libslic3r/PrintConfig.cpp:1675 -msgid "Infill" -msgstr "Заповнення" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:30 src/slic3r/GUI/GUI_ObjectList.cpp:67 -#: src/slic3r/GUI/GUI_Preview.cpp:236 src/slic3r/GUI/Tab.cpp:1010 -#: src/slic3r/GUI/Tab.cpp:1011 src/libslic3r/PrintConfig.cpp:333 -#: src/libslic3r/PrintConfig.cpp:1431 src/libslic3r/PrintConfig.cpp:1779 -#: src/libslic3r/PrintConfig.cpp:1785 src/libslic3r/PrintConfig.cpp:1793 -#: src/libslic3r/PrintConfig.cpp:1805 src/libslic3r/PrintConfig.cpp:1815 -#: src/libslic3r/PrintConfig.cpp:1823 src/libslic3r/PrintConfig.cpp:1838 -#: src/libslic3r/PrintConfig.cpp:1859 src/libslic3r/PrintConfig.cpp:1870 -#: src/libslic3r/PrintConfig.cpp:1886 src/libslic3r/PrintConfig.cpp:1895 -#: src/libslic3r/PrintConfig.cpp:1904 src/libslic3r/PrintConfig.cpp:1915 -#: src/libslic3r/PrintConfig.cpp:1929 src/libslic3r/PrintConfig.cpp:1937 -#: src/libslic3r/PrintConfig.cpp:1938 src/libslic3r/PrintConfig.cpp:1947 -#: src/libslic3r/PrintConfig.cpp:1955 src/libslic3r/PrintConfig.cpp:1969 -#: src/libslic3r/GCode/PreviewData.cpp:172 -msgid "Support material" -msgstr "Підтримка" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:33 src/slic3r/GUI/GUI_ObjectList.cpp:69 -#: src/slic3r/GUI/Tab.cpp:1070 src/slic3r/GUI/Tab.cpp:1794 -#: src/libslic3r/PrintConfig.cpp:455 src/libslic3r/PrintConfig.cpp:953 -#: src/libslic3r/PrintConfig.cpp:1339 src/libslic3r/PrintConfig.cpp:1667 -#: src/libslic3r/PrintConfig.cpp:1851 src/libslic3r/PrintConfig.cpp:1877 -#: src/libslic3r/PrintConfig.cpp:2149 src/libslic3r/PrintConfig.cpp:2157 -msgid "Extruders" -msgstr "Екструдери" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:39 -msgid "Pad and Support" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:68 src/slic3r/GUI/GUI_Preview.cpp:215 -#: src/slic3r/GUI/Tab.cpp:1035 src/libslic3r/PrintConfig.cpp:198 -#: src/libslic3r/PrintConfig.cpp:425 src/libslic3r/PrintConfig.cpp:870 -#: src/libslic3r/PrintConfig.cpp:998 src/libslic3r/PrintConfig.cpp:1360 -#: src/libslic3r/PrintConfig.cpp:1597 src/libslic3r/PrintConfig.cpp:1646 -#: src/libslic3r/PrintConfig.cpp:1697 src/libslic3r/PrintConfig.cpp:2028 -msgid "Speed" -msgstr "Швидкість" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:70 src/libslic3r/PrintConfig.cpp:415 -#: src/libslic3r/PrintConfig.cpp:522 src/libslic3r/PrintConfig.cpp:829 -#: src/libslic3r/PrintConfig.cpp:961 src/libslic3r/PrintConfig.cpp:1348 -#: src/libslic3r/PrintConfig.cpp:1687 src/libslic3r/PrintConfig.cpp:1860 -#: src/libslic3r/PrintConfig.cpp:2017 -msgid "Extrusion Width" -msgstr "Ширина екструзії" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:75 src/slic3r/GUI/Plater.cpp:410 -#: src/slic3r/GUI/Tab.cpp:3309 src/slic3r/GUI/Tab.cpp:3310 -#: src/libslic3r/PrintConfig.cpp:2359 src/libslic3r/PrintConfig.cpp:2366 -#: src/libslic3r/PrintConfig.cpp:2375 src/libslic3r/PrintConfig.cpp:2384 -#: src/libslic3r/PrintConfig.cpp:2394 src/libslic3r/PrintConfig.cpp:2420 -#: src/libslic3r/PrintConfig.cpp:2427 src/libslic3r/PrintConfig.cpp:2438 -#: src/libslic3r/PrintConfig.cpp:2448 src/libslic3r/PrintConfig.cpp:2457 -#: src/libslic3r/PrintConfig.cpp:2467 src/libslic3r/PrintConfig.cpp:2476 -#: src/libslic3r/PrintConfig.cpp:2486 src/libslic3r/PrintConfig.cpp:2496 -#: src/libslic3r/PrintConfig.cpp:2504 -msgid "Supports" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:76 src/slic3r/GUI/Tab.cpp:3337 -#: src/slic3r/GUI/Tab.cpp:3338 src/libslic3r/PrintConfig.cpp:2512 -#: src/libslic3r/PrintConfig.cpp:2519 src/libslic3r/PrintConfig.cpp:2530 -#: src/libslic3r/PrintConfig.cpp:2540 src/libslic3r/PrintConfig.cpp:2553 -#: src/libslic3r/PrintConfig.cpp:2562 -msgid "Pad" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:173 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:45 -msgid "Name" -msgstr "Ім'я" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:201 -msgid "Right button click the icon to change the object settings" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:209 -#, c-format -msgid "Auto-repaired (%d errors):\n" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:212 -msgid "degenerate facets" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:213 -msgid "edges fixed" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:214 -msgid "facets removed" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:215 -msgid "facets added" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:216 -msgid "facets reversed" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:217 -msgid "backwards edges" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:231 -msgid "Right button click the icon to fix STL through Netfabb" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:278 src/slic3r/GUI/Tab.cpp:1430 -#: src/libslic3r/PrintConfig.cpp:454 +msgstr "Скасування..." + +#: src/slic3r/GUI/GCodeViewer.cpp:239 +msgid "Tool position" +msgstr "Позиція інструменту" + +#: src/slic3r/GUI/GCodeViewer.cpp:1016 +msgid "Generating toolpaths" +msgstr "Створення траєкторій" + +#: src/slic3r/GUI/GCodeViewer.cpp:1405 +msgid "Generating vertex buffer" +msgstr "Створення буфера вершин" + +#: src/slic3r/GUI/GCodeViewer.cpp:1496 +msgid "Generating index buffers" +msgstr "Формування буферів індексів" + +#: src/slic3r/GUI/GCodeViewer.cpp:2225 +msgid "Click to hide" +msgstr "Клацніть, щоб сховати" + +#: src/slic3r/GUI/GCodeViewer.cpp:2225 +msgid "Click to show" +msgstr "Клацніть, щоб показати" + +#: src/slic3r/GUI/GCodeViewer.cpp:2337 +msgid "up to" +msgstr "аж до" + +#: src/slic3r/GUI/GCodeViewer.cpp:2343 +msgid "above" +msgstr "вище" + +#: src/slic3r/GUI/GCodeViewer.cpp:2351 +msgid "from" +msgstr "від" + +#: src/slic3r/GUI/GCodeViewer.cpp:2351 +msgid "to" +msgstr "до" + +#: src/slic3r/GUI/GCodeViewer.cpp:2379 src/slic3r/GUI/GCodeViewer.cpp:2387 +#: src/slic3r/GUI/GUI_Preview.cpp:214 src/slic3r/GUI/GUI_Preview.cpp:533 +#: src/slic3r/GUI/GUI_Preview.cpp:942 +msgid "Feature type" +msgstr "Тип ознаки" + +#: src/slic3r/GUI/GCodeViewer.cpp:2379 src/slic3r/GUI/GCodeViewer.cpp:2387 +#: src/slic3r/GUI/RammingChart.cpp:76 +msgid "Time" +msgstr "Час" + +#: src/slic3r/GUI/GCodeViewer.cpp:2387 +msgid "Percentage" +msgstr "Процент" + +#: src/slic3r/GUI/GCodeViewer.cpp:2390 +msgid "Height (mm)" +msgstr "Висота (мм)" + +#: src/slic3r/GUI/GCodeViewer.cpp:2391 +msgid "Width (mm)" +msgstr "Ширина (мм)" + +#: src/slic3r/GUI/GCodeViewer.cpp:2392 +msgid "Speed (mm/s)" +msgstr "Швидкість (мм/с)" + +#: src/slic3r/GUI/GCodeViewer.cpp:2393 +msgid "Fan Speed (%)" +msgstr "Швидкість вентилятора (%)" + +#: src/slic3r/GUI/GCodeViewer.cpp:2394 +msgid "Volumetric flow rate (mm³/s)" +msgstr "Об'ємна швидкість потоку (мм³/с)" + +#: src/slic3r/GUI/GCodeViewer.cpp:2395 src/slic3r/GUI/GUI_Preview.cpp:220 +#: src/slic3r/GUI/GUI_Preview.cpp:326 src/slic3r/GUI/GUI_Preview.cpp:471 +#: src/slic3r/GUI/GUI_Preview.cpp:532 src/slic3r/GUI/GUI_Preview.cpp:878 +#: src/slic3r/GUI/GUI_Preview.cpp:942 +msgid "Tool" +msgstr "Інструмент" + +#: src/slic3r/GUI/GCodeViewer.cpp:2396 src/slic3r/GUI/GUI_Preview.cpp:221 +#: src/slic3r/GUI/GUI_Preview.cpp:530 src/slic3r/GUI/GUI_Preview.cpp:941 +msgid "Color Print" +msgstr "Кольоровий друк" + +#: src/slic3r/GUI/GCodeViewer.cpp:2432 src/slic3r/GUI/GCodeViewer.cpp:2467 +#: src/slic3r/GUI/GCodeViewer.cpp:2472 src/slic3r/GUI/GUI_ObjectList.cpp:312 +#: src/slic3r/GUI/wxExtensions.cpp:519 src/libslic3r/PrintConfig.cpp:547 msgid "Extruder" msgstr "Екструдер" -#: src/slic3r/GUI/GUI_ObjectList.cpp:683 src/slic3r/GUI/GUI_ObjectList.cpp:963 -#: src/slic3r/GUI/GUI_ObjectList.cpp:969 src/slic3r/GUI/GUI_ObjectList.cpp:1199 +#: src/slic3r/GUI/GCodeViewer.cpp:2443 +msgid "Default color" +msgstr "Колір за замовчуванням" + +#: src/slic3r/GUI/GCodeViewer.cpp:2467 +msgid "default color" +msgstr "колір за замовчуванням" + +#: src/slic3r/GUI/GCodeViewer.cpp:2562 src/slic3r/GUI/GCodeViewer.cpp:2608 +msgid "Color change" +msgstr "Зміна кольору" + +#: src/slic3r/GUI/GCodeViewer.cpp:2581 src/slic3r/GUI/GCodeViewer.cpp:2606 +msgid "Print" +msgstr "Друк" + +#: src/slic3r/GUI/GCodeViewer.cpp:2607 src/slic3r/GUI/GCodeViewer.cpp:2624 +msgid "Pause" +msgstr "Пауза" + +#: src/slic3r/GUI/GCodeViewer.cpp:2612 src/slic3r/GUI/GCodeViewer.cpp:2615 +msgid "Event" +msgstr "Подія" + +#: src/slic3r/GUI/GCodeViewer.cpp:2612 src/slic3r/GUI/GCodeViewer.cpp:2615 +msgid "Remaining time" +msgstr "Час, що залишився" + +#: src/slic3r/GUI/GCodeViewer.cpp:2615 +msgid "Duration" +msgstr "Тривалість" + +#: src/slic3r/GUI/GCodeViewer.cpp:2650 src/slic3r/GUI/GUI_Preview.cpp:1023 +#: src/libslic3r/PrintConfig.cpp:2380 +msgid "Travel" +msgstr "Пересування" + +#: src/slic3r/GUI/GCodeViewer.cpp:2653 +msgid "Movement" +msgstr "Переміщення" + +#: src/slic3r/GUI/GCodeViewer.cpp:2654 +msgid "Extrusion" +msgstr "Екструзія" + +#: src/slic3r/GUI/GCodeViewer.cpp:2655 src/slic3r/GUI/Tab.cpp:1694 +#: src/slic3r/GUI/Tab.cpp:2582 +msgid "Retraction" +msgstr "Переривання" + +#: src/slic3r/GUI/GCodeViewer.cpp:2672 src/slic3r/GUI/GCodeViewer.cpp:2675 +#: src/slic3r/GUI/GUI_Preview.cpp:1024 +msgid "Wipe" +msgstr "Витирання" + +#: src/slic3r/GUI/GCodeViewer.cpp:2706 src/slic3r/GUI/GUI_Preview.cpp:248 +#: src/slic3r/GUI/GUI_Preview.cpp:262 +msgid "Options" +msgstr "Параметри" + +#: src/slic3r/GUI/GCodeViewer.cpp:2709 src/slic3r/GUI/GUI_Preview.cpp:1025 +msgid "Retractions" +msgstr "Переривання" + +#: src/slic3r/GUI/GCodeViewer.cpp:2710 src/slic3r/GUI/GUI_Preview.cpp:1026 +msgid "Deretractions" +msgstr "Зниження" + +#: src/slic3r/GUI/GCodeViewer.cpp:2711 src/slic3r/GUI/GUI_Preview.cpp:1027 +msgid "Tool changes" +msgstr "Зміна інструменту" + +#: src/slic3r/GUI/GCodeViewer.cpp:2712 src/slic3r/GUI/GUI_Preview.cpp:1028 +msgid "Color changes" +msgstr "Зміни кольору" + +#: src/slic3r/GUI/GCodeViewer.cpp:2713 src/slic3r/GUI/GUI_Preview.cpp:1029 +msgid "Print pauses" +msgstr "Паузи друку" + +#: src/slic3r/GUI/GCodeViewer.cpp:2714 src/slic3r/GUI/GUI_Preview.cpp:1030 +msgid "Custom G-codes" +msgstr "Користувацькі G-коди" + +#: src/slic3r/GUI/GCodeViewer.cpp:2725 src/slic3r/GUI/GCodeViewer.cpp:2749 +#: src/slic3r/GUI/Plater.cpp:697 src/libslic3r/PrintConfig.cpp:117 +msgid "Printer" +msgstr "Принтер" + +#: src/slic3r/GUI/GCodeViewer.cpp:2727 src/slic3r/GUI/GCodeViewer.cpp:2754 +#: src/slic3r/GUI/Plater.cpp:693 +msgid "Print settings" +msgstr "Параметри друку" + +#: src/slic3r/GUI/GCodeViewer.cpp:2730 src/slic3r/GUI/GCodeViewer.cpp:2760 +#: src/slic3r/GUI/Plater.cpp:694 src/slic3r/GUI/Tab.cpp:1794 +#: src/slic3r/GUI/Tab.cpp:1795 +msgid "Filament" +msgstr "Філамент" + +#: src/slic3r/GUI/GCodeViewer.cpp:2785 src/slic3r/GUI/GCodeViewer.cpp:2790 +#: src/slic3r/GUI/Plater.cpp:242 src/slic3r/GUI/Plater.cpp:1135 +#: src/slic3r/GUI/Plater.cpp:1220 +msgid "Estimated printing time" +msgstr "Приблизний час друку" + +#: src/slic3r/GUI/GCodeViewer.cpp:2785 +msgid "Normal mode" +msgstr "Нормальний режим" + +#: src/slic3r/GUI/GCodeViewer.cpp:2790 +msgid "Stealth mode" +msgstr "Тихий режим" + +#: src/slic3r/GUI/GCodeViewer.cpp:2817 +msgid "Show stealth mode" +msgstr "Показати тихий режим" + +#: src/slic3r/GUI/GCodeViewer.cpp:2821 +msgid "Show normal mode" +msgstr "Показати нормальний режим" + +#: src/slic3r/GUI/GLCanvas3D.cpp:236 src/slic3r/GUI/GLCanvas3D.cpp:4610 +msgid "Variable layer height" +msgstr "Змінна висота шарів" + +#: src/slic3r/GUI/GLCanvas3D.cpp:238 +msgid "Left mouse button:" +msgstr "Ліва кнопка миші:" + +#: src/slic3r/GUI/GLCanvas3D.cpp:240 +msgid "Add detail" +msgstr "Додати деталь" + +#: src/slic3r/GUI/GLCanvas3D.cpp:242 +msgid "Right mouse button:" +msgstr "Права кнопка миші:" + +#: src/slic3r/GUI/GLCanvas3D.cpp:244 +msgid "Remove detail" +msgstr "Видалити деталь" + +#: src/slic3r/GUI/GLCanvas3D.cpp:246 +msgid "Shift + Left mouse button:" +msgstr "Shift + Ліва кнопка миші:" + +#: src/slic3r/GUI/GLCanvas3D.cpp:248 +msgid "Reset to base" +msgstr "Скинути до базової висоти шару" + +#: src/slic3r/GUI/GLCanvas3D.cpp:250 +msgid "Shift + Right mouse button:" +msgstr "Shift + Права кнопка миші:" + +#: src/slic3r/GUI/GLCanvas3D.cpp:252 +msgid "Smoothing" +msgstr "Згладжування" + +#: src/slic3r/GUI/GLCanvas3D.cpp:254 +msgid "Mouse wheel:" +msgstr "Колесо миші:" + +#: src/slic3r/GUI/GLCanvas3D.cpp:256 +msgid "Increase/decrease edit area" +msgstr "Збільшити/зменшити області редагування" + +#: src/slic3r/GUI/GLCanvas3D.cpp:259 +msgid "Adaptive" +msgstr "Адаптивний" + +#: src/slic3r/GUI/GLCanvas3D.cpp:265 +msgid "Quality / Speed" +msgstr "Якість / Швидкість" + +#: src/slic3r/GUI/GLCanvas3D.cpp:268 +msgid "Higher print quality versus higher print speed." +msgstr "Вища якість друку порівняно з вищою швидкістю друку." + +#: src/slic3r/GUI/GLCanvas3D.cpp:279 +msgid "Smooth" +msgstr "Згладити" + +#: src/slic3r/GUI/GLCanvas3D.cpp:285 src/libslic3r/PrintConfig.cpp:571 +msgid "Radius" +msgstr "Радіус" + +#: src/slic3r/GUI/GLCanvas3D.cpp:295 +msgid "Keep min" +msgstr "Залишити мін" + +#: src/slic3r/GUI/GLCanvas3D.cpp:304 src/slic3r/GUI/GLCanvas3D.cpp:4050 +msgid "Reset" +msgstr "Скинути" + +#: src/slic3r/GUI/GLCanvas3D.cpp:566 +msgid "Variable layer height - Manual edit" +msgstr "Змінна висота шарів - Ручне редагування" + +#: src/slic3r/GUI/GLCanvas3D.cpp:634 +msgid "An object outside the print area was detected." +msgstr "Виявлено об'єкт за межами області друку." + +#: src/slic3r/GUI/GLCanvas3D.cpp:635 +msgid "A toolpath outside the print area was detected." +msgstr "Виявлено траєкторію за межами області друку." + +#: src/slic3r/GUI/GLCanvas3D.cpp:636 +msgid "SLA supports outside the print area were detected." +msgstr "Виявлено SLA-підтримки за межами області друку." + +#: src/slic3r/GUI/GLCanvas3D.cpp:637 +msgid "Some objects are not visible." +msgstr "Деякі об'єкти не видно." + +#: src/slic3r/GUI/GLCanvas3D.cpp:639 +msgid "" +"An object outside the print area was detected.\n" +"Resolve the current problem to continue slicing." +msgstr "" +"Виявлено об’єкт за межами області друку.\n" +"Вирішіть поточну проблему, щоб продовжувати нарізання." + +#: src/slic3r/GUI/GLCanvas3D.cpp:949 +msgid "Seq." +msgstr "Послід." + +#: src/slic3r/GUI/GLCanvas3D.cpp:1455 +msgid "Variable layer height - Reset" +msgstr "Змінна висота шарів - Скасувати" + +#: src/slic3r/GUI/GLCanvas3D.cpp:1463 +msgid "Variable layer height - Adaptive" +msgstr "Змінна висота шарів - Адаптивний" + +#: src/slic3r/GUI/GLCanvas3D.cpp:1471 +msgid "Variable layer height - Smooth all" +msgstr "Змінна висота шарів - Згладити все" + +#: src/slic3r/GUI/GLCanvas3D.cpp:1876 +msgid "Mirror Object" +msgstr "Віддзеркалити об'єкт" + +#: src/slic3r/GUI/GLCanvas3D.cpp:2746 +#: src/slic3r/GUI/Gizmos/GLGizmosManager.cpp:520 +msgid "Gizmo-Move" +msgstr "Gizmo переміщення" + +#: src/slic3r/GUI/GLCanvas3D.cpp:2832 +#: src/slic3r/GUI/Gizmos/GLGizmosManager.cpp:522 +msgid "Gizmo-Rotate" +msgstr "Gizmo обертання" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3388 +msgid "Move Object" +msgstr "Перемістити об'єкт" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3858 src/slic3r/GUI/GLCanvas3D.cpp:4571 +msgid "Switch to Settings" +msgstr "Перейдіть до налаштувань" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3859 src/slic3r/GUI/GLCanvas3D.cpp:4571 +msgid "Print Settings Tab" +msgstr "Вкладка параметрів друку" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3860 src/slic3r/GUI/GLCanvas3D.cpp:4572 +msgid "Filament Settings Tab" +msgstr "Вкладка параметрів філаменту" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3860 src/slic3r/GUI/GLCanvas3D.cpp:4572 +msgid "Material Settings Tab" +msgstr "Вкладка параметрів матеріалу" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3861 src/slic3r/GUI/GLCanvas3D.cpp:4573 +msgid "Printer Settings Tab" +msgstr "Вкладка параметрів принтеру" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3909 +msgid "Undo History" +msgstr "Скасувати історію" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3909 +msgid "Redo History" +msgstr "Повторити історію" + +#: src/slic3r/GUI/GLCanvas3D.cpp:3930 #, c-format -msgid "Quick Add Settings (%s)" -msgstr "" +msgid "Undo %1$d Action" +msgid_plural "Undo %1$d Actions" +msgstr[0] "Скасувати %1$d дію" +msgstr[1] "Скасувати %1$d дії" +msgstr[2] "Скасувати %1$d дій" -#: src/slic3r/GUI/GUI_ObjectList.cpp:746 -msgid "Select showing settings" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:3930 +#, c-format +msgid "Redo %1$d Action" +msgid_plural "Redo %1$d Actions" +msgstr[0] "Повторити %1$d дію" +msgstr[1] "Повторити %1$d дії" +msgstr[2] "Повторити %1$d дій" -#: src/slic3r/GUI/GUI_ObjectList.cpp:874 -msgid "Load" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:3950 src/slic3r/GUI/GLCanvas3D.cpp:4589 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:98 src/slic3r/GUI/Search.cpp:351 +msgid "Search" +msgstr "Пошук" -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 src/slic3r/GUI/GUI_ObjectList.cpp:911 -#: src/slic3r/GUI/GUI_ObjectList.cpp:914 -msgid "Box" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:3964 src/slic3r/GUI/GLCanvas3D.cpp:3972 +#: src/slic3r/GUI/Search.cpp:358 +msgid "Enter a search term" +msgstr "Введіть пошуковий термін" -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Cylinder" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4003 +msgid "Arrange options" +msgstr "Параметри розташування" -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Sphere" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4033 +msgid "Press %1%left mouse button to enter the exact value" +msgstr "Натисніть %1%ліву кнопку миші, щоб ввести точне значення" -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Slab" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4035 +msgid "Spacing" +msgstr "Відстань" -#: src/slic3r/GUI/GUI_ObjectList.cpp:890 src/slic3r/GUI/GUI_ObjectList.cpp:906 -msgid "Add part" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4042 +msgid "Enable rotations (slow)" +msgstr "Увімкнути обертання (повільно)" -#: src/slic3r/GUI/GUI_ObjectList.cpp:891 -msgid "Add modifier" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4060 src/slic3r/GUI/GLCanvas3D.cpp:4481 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:120 src/slic3r/GUI/Plater.cpp:1648 +msgid "Arrange" +msgstr "Розташувати" -#: src/slic3r/GUI/GUI_ObjectList.cpp:892 src/slic3r/GUI/GUI_ObjectList.cpp:910 -msgid "Add support enforcer" -msgstr "" +#: src/slic3r/GUI/GLCanvas3D.cpp:4455 +msgid "Add..." +msgstr "Додати..." -#: src/slic3r/GUI/GUI_ObjectList.cpp:893 src/slic3r/GUI/GUI_ObjectList.cpp:913 -msgid "Add support blocker" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:934 -msgid "Split to parts" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:942 -msgid "Add settings" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1009 -msgid "Change type" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1016 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1153 -msgid "Set as a Separated Object" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1024 -msgid "Rename" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1034 -msgid "Fix through the Netfabb" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1041 src/slic3r/GUI/Plater.cpp:2861 -msgid "Export as STL" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1048 -msgid "Change extruder" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1073 -msgid "Select new extruder for the object/part" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:1079 src/slic3r/GUI/Plater.cpp:2825 -#: src/slic3r/GUI/Plater.cpp:2843 src/slic3r/GUI/Tab.cpp:2860 +#: src/slic3r/GUI/GLCanvas3D.cpp:4463 src/slic3r/GUI/GUI_ObjectList.cpp:1878 +#: src/slic3r/GUI/Plater.cpp:3998 src/slic3r/GUI/Plater.cpp:4022 +#: src/slic3r/GUI/Tab.cpp:3484 msgid "Delete" msgstr "Видалити" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1153 +#: src/slic3r/GUI/GLCanvas3D.cpp:4472 src/slic3r/GUI/KBShortcutsDialog.cpp:88 +#: src/slic3r/GUI/Plater.cpp:5107 +msgid "Delete all" +msgstr "Видалити все" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4481 src/slic3r/GUI/KBShortcutsDialog.cpp:121 +msgid "Arrange selection" +msgstr "Розташувати вибране" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4481 +msgid "Click right mouse button to show arrangement options" +msgstr "Клацніть правою кнопкою миші, щоб показати параметри розташування" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4503 +msgid "Copy" +msgstr "Копіювати" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4512 +msgid "Paste" +msgstr "Вставити" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4524 src/slic3r/GUI/Plater.cpp:3857 +#: src/slic3r/GUI/Plater.cpp:3869 src/slic3r/GUI/Plater.cpp:4007 +msgid "Add instance" +msgstr "Додати екземпляр" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4535 src/slic3r/GUI/Plater.cpp:4009 +msgid "Remove instance" +msgstr "Видалити екземпляр" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4548 +msgid "Split to objects" +msgstr "Розділити на об'єкти" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4558 src/slic3r/GUI/GUI_ObjectList.cpp:1650 +msgid "Split to parts" +msgstr "Розділити на частини" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4660 src/slic3r/GUI/KBShortcutsDialog.cpp:89 +#: src/slic3r/GUI/MainFrame.cpp:1125 +msgid "Undo" +msgstr "Скасувати" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4660 src/slic3r/GUI/GLCanvas3D.cpp:4699 +msgid "Click right mouse button to open/close History" +msgstr "Клацніть правою кнопкою миші, щоб відкрити/закрити історію" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4683 +msgid "Next Undo action: %1%" +msgstr "Скасувати дію: %1%" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4699 src/slic3r/GUI/KBShortcutsDialog.cpp:90 +#: src/slic3r/GUI/MainFrame.cpp:1128 +msgid "Redo" +msgstr "Повторити" + +#: src/slic3r/GUI/GLCanvas3D.cpp:4721 +msgid "Next Redo action: %1%" +msgstr "Повторити дію: %1%" + +#: src/slic3r/GUI/GLCanvas3D.cpp:6345 +msgid "Selection-Add from rectangle" +msgstr "Виділення - Додано прямокутником" + +#: src/slic3r/GUI/GLCanvas3D.cpp:6364 +msgid "Selection-Remove from rectangle" +msgstr "Виділення - Видалено прямокутником" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:54 +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:151 src/libslic3r/PrintConfig.cpp:3690 +msgid "Cut" +msgstr "Розрізати" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:179 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:341 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:418 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:486 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:487 +msgid "in" +msgstr "дюйм" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:185 +msgid "Keep upper part" +msgstr "Залишити верхню частину" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:186 +msgid "Keep lower part" +msgstr "Залишити нижню частину" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:187 +msgid "Rotate lower part upwards" +msgstr "Повернути нижню частину вгору" + +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:192 +msgid "Perform cut" +msgstr "Виконати розріз" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:33 +msgid "Paint-on supports" +msgstr "Малювання підтримок" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:42 +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:49 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:25 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:57 +msgid "Clipping of view" +msgstr "Відсікання площиною" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:43 +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:50 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:26 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:58 +msgid "Reset direction" +msgstr "Скинути напрямок" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:44 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:27 +msgid "Brush size" +msgstr "Розмір пензля" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:45 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:28 +msgid "Brush shape" +msgstr "Форма пензля" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:46 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:29 +msgid "Left mouse button" +msgstr "Ліва кнопка миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:47 +msgid "Enforce supports" +msgstr "Забезпечити підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:48 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:31 +msgid "Right mouse button" +msgstr "Права кнопка миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:49 +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:373 +msgid "Block supports" +msgstr "Блокувати підтрики" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:50 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:33 +msgid "Shift + Left mouse button" +msgstr "Shift + Ліва кнопка миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:51 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:34 +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:368 +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:378 +msgid "Remove selection" +msgstr "Видалити виділене" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:52 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:35 +msgid "Remove all selection" +msgstr "Видалити все, що виділено" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:53 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:36 +msgid "Circle" +msgstr "Коло" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:54 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:37 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +msgid "Sphere" +msgstr "Сфера" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:129 +msgid "Autoset by angle" +msgstr "Автоматичне встановлення під кутом" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:136 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:118 +msgid "Reset selection" +msgstr "Скинути вибір" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:160 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:141 +msgid "Alt + Mouse wheel" +msgstr "Alt + Колесо миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:178 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:159 +msgid "Paints all facets inside, regardless of their orientation." +msgstr "Малює всі грані всередині, незалежно від їх орієнтації." + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:192 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:173 +msgid "Ignores facets facing away from the camera." +msgstr "Ігнорує грані, відвернуті від камери." + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:225 +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:203 +msgid "Ctrl + Mouse wheel" +msgstr "Ctrl + Колесо миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:233 +msgid "Autoset custom supports" +msgstr "Автоматичне встановлення власних підтримок" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:235 +msgid "Threshold:" +msgstr "Порог нависання:" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:242 +msgid "Enforce" +msgstr "Забезпечити" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:245 +msgid "Block" +msgstr "Блокувати" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:295 +msgid "Block supports by angle" +msgstr "Блокувати підтрики під кутом" + +#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:296 +msgid "Add supports by angle" +msgstr "Додати підтримки під кутом" + +#: src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp:40 +msgid "Place on face" +msgstr "Поверхнею на стіл" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:40 +msgid "Hollow this object" +msgstr "Випорожнити цей об'єкт" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:41 +msgid "Preview hollowed and drilled model" +msgstr "Попередній перегляд порожнистої та просвердленої моделі" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:42 +msgid "Offset" +msgstr "Зміщення" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:43 +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:56 +msgid "Quality" +msgstr "Якість" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:44 +#: src/libslic3r/PrintConfig.cpp:3183 +msgid "Closing distance" +msgstr "Відстань закриття" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:45 +msgid "Hole diameter" +msgstr "Діаметр отвору" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:46 +msgid "Hole depth" +msgstr "Глибина отвору" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:47 +msgid "Remove selected holes" +msgstr "Видалити вибрані отвори" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:48 +msgid "Remove all holes" +msgstr "Видалити всі отвори" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:51 +msgid "Show supports" +msgstr "Показувати підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:308 +msgid "Add drainage hole" +msgstr "Додати дренажний отвір" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:424 +msgid "Delete drainage hole" +msgstr "Видалити дренажний отвір" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:624 +msgid "Hollowing parameter change" +msgstr "Зміна параметру порожнистості" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:693 +msgid "Change drainage hole diameter" +msgstr "Змініть діаметр дренажного отвору" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:785 +msgid "Hollow and drill" +msgstr "Порожнистість та свердління" + +#: src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp:835 +msgid "Move drainage hole" +msgstr "Перемістити дренажний отвір" + +#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:64 +msgid "Move" +msgstr "Пересунути" + +#: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:461 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:527 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:546 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:562 +#: src/libslic3r/PrintConfig.cpp:3739 +msgid "Rotate" +msgstr "Обертати" + +#: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:78 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:238 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:547 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:563 +#: src/libslic3r/PrintConfig.cpp:3754 +msgid "Scale" +msgstr "Масштаб" + +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:30 +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:381 +msgid "Enforce seam" +msgstr "Забезпечити шов" + +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:32 +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:383 +msgid "Block seam" +msgstr "Блокувати шов" + +#: src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp:46 +msgid "Seam painting" +msgstr "Малювання шва" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:47 +msgid "Head diameter" +msgstr "Діаметр головки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:48 +msgid "Lock supports under new islands" +msgstr "Зафіксувати підтримки під новими островами" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:49 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1218 +msgid "Remove selected points" +msgstr "Видалити вибрані точки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:50 +msgid "Remove all points" +msgstr "Видалити всі точки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:51 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1221 +msgid "Apply changes" +msgstr "Застосувати зміни" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:52 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1222 +msgid "Discard changes" +msgstr "Відхилити зміни" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:53 +msgid "Minimal points distance" +msgstr "Мінімальна відстань точок" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:54 +#: src/libslic3r/PrintConfig.cpp:3013 +msgid "Support points density" +msgstr "Щільність точок підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:55 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1224 +msgid "Auto-generate points" +msgstr "Генерувати точки автоматично" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:56 +msgid "Manual editing" +msgstr "Ручне редагування" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:374 +msgid "Add support point" +msgstr "Додати точку підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:514 +msgid "Delete support point" +msgstr "Видалити точку підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:694 +msgid "Change point head diameter" +msgstr "Змінити діаметр головки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:762 +msgid "Support parameter change" +msgstr "Зміна параметрів підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:869 +msgid "SLA Support Points" +msgstr "Точки SLA-підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:897 +msgid "SLA gizmo turned on" +msgstr "Ввімкнути SLA гізмо" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:911 +msgid "Do you want to save your manually edited support points?" +msgstr "Ви хочете зберегти відредаговані вручну точки підтримки?" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:912 +msgid "Save changes?" +msgstr "Зберегти зміни?" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:924 +msgid "SLA gizmo turned off" +msgstr "Вимкнути SLA гізмо" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:955 +msgid "Move support point" +msgstr "Перемістити точку підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1048 +msgid "Support points edit" +msgstr "Редагування точок підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1127 +msgid "Autogeneration will erase all manually edited points." +msgstr "Автогенерація видалить всі відредаговані вручну точки." + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1128 +msgid "Are you sure you want to do it?" +msgstr "Ви впевнені, що хочете це зробити?" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1129 src/slic3r/GUI/GUI.cpp:256 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:557 +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:581 +#: src/slic3r/GUI/WipeTowerDialog.cpp:45 src/slic3r/GUI/WipeTowerDialog.cpp:366 +msgid "Warning" +msgstr "Застереження" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1134 +msgid "Autogenerate support points" +msgstr "Автогенерувати точки підтримки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1181 +msgid "SLA gizmo keyboard shortcuts" +msgstr "Комбінації клавіш для SLA гізма" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1192 +msgid "Note: some shortcuts work in (non)editing mode only." +msgstr "Примітка: деякі скорочення працюють лише в режимі (не)редагування." + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1210 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1213 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1214 +msgid "Left click" +msgstr "Ліва кнопка миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1210 +msgid "Add point" +msgstr "Додати точку" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1211 +msgid "Right click" +msgstr "Клік на праву кнопку миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1211 +msgid "Remove point" +msgstr "Видалити точку" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1212 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1215 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1216 +msgid "Drag" +msgstr "Перетягування" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1212 +msgid "Move point" +msgstr "Перемістити точку" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1213 +msgid "Add point to selection" +msgstr "Додати точку до виділення" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1214 +msgid "Remove point from selection" +msgstr "Видалити точку з виділення" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1215 +msgid "Select by rectangle" +msgstr "Виділення прямокутником" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1216 +msgid "Deselect by rectangle" +msgstr "Скасування вибору прямокутником" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1217 +msgid "Select all points" +msgstr "Виділити усі точки" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1219 +msgid "Mouse wheel" +msgstr "Колесо миші" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1219 +msgid "Move clipping plane" +msgstr "Перемістити площину відсікання" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1220 +msgid "Reset clipping plane" +msgstr "Скинути площину відсікання" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1223 +msgid "Switch to editing mode" +msgstr "Перейти в режим редагування" + +#: src/slic3r/GUI/Gizmos/GLGizmosManager.cpp:521 +msgid "Gizmo-Scale" +msgstr "Gizmo масштабування" + +#: src/slic3r/GUI/Gizmos/GLGizmosManager.cpp:630 +msgid "Gizmo-Place on Face" +msgstr "Gizmo \"Поверхнею на стіл\"" + +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:39 +msgid "Entering Paint-on supports" +msgstr "Увійти до режиму малювання підтримок" + +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:40 +msgid "Entering Seam painting" +msgstr "Увійти до режиму малювання шву" + +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:47 +msgid "Leaving Seam painting" +msgstr "Вийти з режиму малювання шву" + +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:48 +msgid "Leaving Paint-on supports" +msgstr "Вийти з режиму малювання підтримок" + +#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:371 +msgid "Add supports" +msgstr "Додати підтримки" + +#: src/slic3r/GUI/GUI_App.cpp:239 +msgid "is based on Slic3r by Alessandro Ranellucci and the RepRap community." +msgstr "заснований на Slic3r від Alessandro Ranellucci та спільноти RepRap." + +#: src/slic3r/GUI/GUI_App.cpp:241 +msgid "" +"Contributions by Vojtech Bubnik, Enrico Turri, Oleksandra Iushchenko, Tamas " +"Meszaros, Lukas Matena, Vojtech Kral, David Kocik and numerous others." +msgstr "" +"Розробки від Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr " +"Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik та багатьох " +"інших." + +#: src/slic3r/GUI/GUI_App.cpp:242 +msgid "Artwork model by Nora Al-Badri and Jan Nikolai Nelles" +msgstr "Модель ілюстрації виконано Nora Al-Badri та Jan Nikolai Nelles" + +#: src/slic3r/GUI/GUI_App.cpp:382 +msgid "" +"Starting with %1% 2.3, configuration directory on Linux has changed " +"(according to XDG Base Directory Specification) to \n" +"%2%.\n" +"\n" +"This directory did not exist yet (maybe you run the new version for the " +"first time).\n" +"However, an old %1% configuration directory was detected in \n" +"%3%.\n" +"\n" +"Consider moving the contents of the old directory to the new location in " +"order to access your profiles, etc.\n" +"Note that if you decide to downgrade %1% in future, it will use the old " +"location again.\n" +"\n" +"What do you want to do now?" +msgstr "" +"Починаючи з %1% 2.3, каталог конфігурації в Linux змінився (відповідно до " +"специфікації базового каталогу XDG) на\n" +"%2%.\n" +"\n" +"Цей каталог ще не існував (можливо, ви запускаєте нову версію вперше).\n" +"Однак у %3% був виявлений старий каталог конфігурації %1%.\n" +"\n" +"Подумайте про переміщення вмісту старого каталогу в нове місце, щоб отримати " +"доступ до ваших профілів тощо.\n" +"Зверніть увагу, що якщо ви вирішите знизити версію %1% у майбутньому, він " +"знову використовуватиме старе місце.\n" +"\n" +"Що ви хочете робити зараз?" + +#: src/slic3r/GUI/GUI_App.cpp:390 +#, c-format +msgid "%s - BREAKING CHANGE" +msgstr "%s - ЗЛАМАНА ЗМІНА" + +#: src/slic3r/GUI/GUI_App.cpp:392 +msgid "Quit, I will move my data now" +msgstr "Вийти, я зараз перенесу свої дані" + +#: src/slic3r/GUI/GUI_App.cpp:392 +msgid "Start the application" +msgstr "Запустити програму" + +#: src/slic3r/GUI/GUI_App.cpp:580 +#, c-format +msgid "" +"%s has encountered an error. It was likely caused by running out of memory. " +"If you are sure you have enough RAM on your system, this may also be a bug " +"and we would be glad if you reported it.\n" +"\n" +"The application will now terminate." +msgstr "" +"%s виявив помилку. Ймовірно, це було пов’язано з закінченням пам’яті. Якщо " +"ви впевнені, що у вашій системі достатньо оперативної пам'яті, це також може " +"бути помилкою, і ми будемо раді, якщо ви нам про це повідомите.\n" +"\n" +"Тепер застосування буде припинено." + +#: src/slic3r/GUI/GUI_App.cpp:583 +msgid "Fatal error" +msgstr "Критична помилка" + +#: src/slic3r/GUI/GUI_App.cpp:587 +msgid "" +"PrusaSlicer has encountered a localization error. Please report to " +"PrusaSlicer team, what language was active and in which scenario this issue " +"happened. Thank you.\n" +"\n" +"The application will now terminate." +msgstr "" +"Виникла помилка локалізації. Будь ласка, повідомте команді PrusaSlicer, яка " +"мова була активною та за якого сценарію сталася ця проблема. Дякую.\n" +"\n" +"Тепер застосування буде припинено." + +#: src/slic3r/GUI/GUI_App.cpp:590 +msgid "Critical error" +msgstr "Критична помилка" + +#: src/slic3r/GUI/GUI_App.cpp:711 +msgid "" +"Error parsing PrusaSlicer config file, it is probably corrupted. Try to " +"manually delete the file to recover from the error. Your user profiles will " +"not be affected." +msgstr "" +"Помилка під час розбору файлу конфігурації PrusaSlicer, можливо, він " +"пошкоджений. Спробуйте вручну видалити файл, щоб оговтатися від помилки. Це " +"не вплине на профілі користувачів." + +#: src/slic3r/GUI/GUI_App.cpp:717 +msgid "" +"Error parsing PrusaGCodeViewer config file, it is probably corrupted. Try to " +"manually delete the file to recover from the error." +msgstr "" +"Помилка під час розбору файлу конфігурації PrusaGCodeViewer, можливо, він " +"пошкоджений. Спробуйте вручну видалити файл, щоб оговтатися від помилки." + +#: src/slic3r/GUI/GUI_App.cpp:771 +#, c-format +msgid "" +"%s\n" +"Do you want to continue?" +msgstr "" +"%s\n" +"Бажаєте продовжити?" + +#: src/slic3r/GUI/GUI_App.cpp:773 src/slic3r/GUI/UnsavedChangesDialog.cpp:665 +msgid "Remember my choice" +msgstr "Пам'ятати мій вибір" + +#: src/slic3r/GUI/GUI_App.cpp:808 +msgid "Loading configuration" +msgstr "Завантаження конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:876 +msgid "Preparing settings tabs" +msgstr "Підготовка вкладок параметрів" + +#: src/slic3r/GUI/GUI_App.cpp:1115 +msgid "" +"You have the following presets with saved options for \"Print Host upload\"" +msgstr "" +"У вас є наступні пресети із збереженими параметрами для \"Завантаження хоста " +"друку(\"Print Host upload\")\"" + +#: src/slic3r/GUI/GUI_App.cpp:1119 +msgid "" +"But since this version of PrusaSlicer we don't show this information in " +"Printer Settings anymore.\n" +"Settings will be available in physical printers settings." +msgstr "" +"Від поточної версії PrusaSlicer ми більше не відображаємо цю інформацію в " +"параметрах принтера.\n" +"Ці параметри будуть доступні у налаштуваннях фізичних принтерів." + +#: src/slic3r/GUI/GUI_App.cpp:1121 +msgid "" +"By default new Printer devices will be named as \"Printer N\" during its " +"creation.\n" +"Note: This name can be changed later from the physical printers settings" +msgstr "" +"За замовчуванням нові друкуючі пристрої будуть названі \"Printer N\" під час " +"їх створення.\n" +"Примітка: Цю назву можна змінити пізніше в налаштуваннях фізичних принтерів" + +#: src/slic3r/GUI/GUI_App.cpp:1124 src/slic3r/GUI/PhysicalPrinterDialog.cpp:626 +msgid "Information" +msgstr "Інформація" + +#: src/slic3r/GUI/GUI_App.cpp:1137 src/slic3r/GUI/GUI_App.cpp:1148 +msgid "Recreating" +msgstr "Пере-створення" + +#: src/slic3r/GUI/GUI_App.cpp:1153 +msgid "Loading of current presets" +msgstr "Завантаження поточних пресетів" + +#: src/slic3r/GUI/GUI_App.cpp:1158 +msgid "Loading of a mode view" +msgstr "Завантаження режиму перегляду" + +#: src/slic3r/GUI/GUI_App.cpp:1234 +msgid "Choose one file (3MF/AMF):" +msgstr "Виберіть один файл (3MF/AMF):" + +#: src/slic3r/GUI/GUI_App.cpp:1246 +msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "Виберіть один чи кілька файлів (STL/OBJ/AMF/PRUSA):" + +#: src/slic3r/GUI/GUI_App.cpp:1258 +msgid "Choose one file (GCODE/.GCO/.G/.ngc/NGC):" +msgstr "Виберіть один файл (GCODE/.GCO/.G/.ngc/NGC):" + +#: src/slic3r/GUI/GUI_App.cpp:1269 +msgid "Changing of an application language" +msgstr "Зміна мови застосування" + +#: src/slic3r/GUI/GUI_App.cpp:1392 +msgid "Select the language" +msgstr "Оберіть мову" + +#: src/slic3r/GUI/GUI_App.cpp:1392 +msgid "Language" +msgstr "Мова" + +#: src/slic3r/GUI/GUI_App.cpp:1541 +msgid "modified" +msgstr "модифікований" + +#: src/slic3r/GUI/GUI_App.cpp:1590 +#, c-format +msgid "Run %s" +msgstr "Запустити %s" + +#: src/slic3r/GUI/GUI_App.cpp:1594 +msgid "&Configuration Snapshots" +msgstr "Знімки конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1594 +msgid "Inspect / activate configuration snapshots" +msgstr "Перегляньте / активізуйте знімки конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1595 +msgid "Take Configuration &Snapshot" +msgstr "Зробіть знімок конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1595 +msgid "Capture a configuration snapshot" +msgstr "Зробіть знімок конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1596 +msgid "Check for updates" +msgstr "Перевірити наявність оновлень" + +#: src/slic3r/GUI/GUI_App.cpp:1596 +msgid "Check for configuration updates" +msgstr "Перевірити наявність оновлень конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1599 +msgid "&Preferences" +msgstr "&Преференції" + +#: src/slic3r/GUI/GUI_App.cpp:1605 +msgid "Application preferences" +msgstr "Преференції застосування" + +#: src/slic3r/GUI/GUI_App.cpp:1610 src/slic3r/GUI/wxExtensions.cpp:685 +msgid "Simple" +msgstr "Простий" + +#: src/slic3r/GUI/GUI_App.cpp:1610 +msgid "Simple View Mode" +msgstr "Простий режим перегляду" + +#: src/slic3r/GUI/GUI_App.cpp:1612 src/slic3r/GUI/wxExtensions.cpp:687 +msgctxt "Mode" +msgid "Advanced" +msgstr "Розширений" + +#: src/slic3r/GUI/GUI_App.cpp:1612 +msgid "Advanced View Mode" +msgstr "Розширений режим перегляду" + +#: src/slic3r/GUI/GUI_App.cpp:1613 src/slic3r/GUI/wxExtensions.cpp:688 +msgid "Expert" +msgstr "Експерт" + +#: src/slic3r/GUI/GUI_App.cpp:1613 +msgid "Expert View Mode" +msgstr "Режим перегляду Експерт" + +#: src/slic3r/GUI/GUI_App.cpp:1618 +msgid "Mode" +msgstr "Режим" + +#: src/slic3r/GUI/GUI_App.cpp:1618 +#, c-format +msgid "%s View Mode" +msgstr "Режим перегляду %s" + +#: src/slic3r/GUI/GUI_App.cpp:1621 +msgid "&Language" +msgstr "Мова" + +#: src/slic3r/GUI/GUI_App.cpp:1624 +msgid "Flash printer &firmware" +msgstr "Прошити принтер" + +#: src/slic3r/GUI/GUI_App.cpp:1624 +msgid "Upload a firmware image into an Arduino based printer" +msgstr "Завантажте імідж прошивки на Arduino-принтер" + +#: src/slic3r/GUI/GUI_App.cpp:1640 +msgid "Taking configuration snapshot" +msgstr "Знімок конфігурації" + +#: src/slic3r/GUI/GUI_App.cpp:1640 +msgid "Snapshot name" +msgstr "Назва знімку" + +#: src/slic3r/GUI/GUI_App.cpp:1669 +msgid "Failed to activate configuration snapshot." +msgstr "Не вдалося активувати знімок конфігурації." + +#: src/slic3r/GUI/GUI_App.cpp:1719 +msgid "Language selection" +msgstr "Вибір мови" + +#: src/slic3r/GUI/GUI_App.cpp:1721 +msgid "" +"Switching the language will trigger application restart.\n" +"You will lose content of the plater." +msgstr "" +"Переключення мови спричинить перезапуск програми.\n" +"Ви втратите вміст платеру." + +#: src/slic3r/GUI/GUI_App.cpp:1723 +msgid "Do you want to proceed?" +msgstr "Ви хочете продовжити?" + +#: src/slic3r/GUI/GUI_App.cpp:1750 +msgid "&Configuration" +msgstr "&Конфігурація" + +#: src/slic3r/GUI/GUI_App.cpp:1781 +msgid "The preset(s) modifications are successfully saved" +msgstr "Модифікації пресетів успішно збережено" + +#: src/slic3r/GUI/GUI_App.cpp:1802 +msgid "The uploads are still ongoing" +msgstr "Завантаження все ще триває" + +#: src/slic3r/GUI/GUI_App.cpp:1802 +msgid "Stop them and continue anyway?" +msgstr "Зупинити їх і продовжувати в будь-якому випадку?" + +#: src/slic3r/GUI/GUI_App.cpp:1805 +msgid "Ongoing uploads" +msgstr "Триває завантаження" + +#: src/slic3r/GUI/GUI_App.cpp:2019 src/slic3r/GUI/Tab.cpp:3242 +msgid "It's impossible to print multi-part object(s) with SLA technology." +msgstr "" +"За технологією SLA неможливо надрукувати об'єкти, що складаються з декількох " +"частин." + +#: src/slic3r/GUI/GUI_App.cpp:2020 +msgid "Please check and fix your object list." +msgstr "Будь ласка, перевірте та виправте свій список об'єктів." + +#: src/slic3r/GUI/GUI_App.cpp:2021 src/slic3r/GUI/Jobs/SLAImportJob.cpp:210 +#: src/slic3r/GUI/Plater.cpp:2359 src/slic3r/GUI/Tab.cpp:3244 +msgid "Attention!" +msgstr "Увага!" + +#: src/slic3r/GUI/GUI_App.cpp:2038 +msgid "Select a gcode file:" +msgstr "Виберіть файл G-коду:" + +#: src/slic3r/GUI/GUI_Init.cpp:73 src/slic3r/GUI/GUI_Init.cpp:76 +msgid "PrusaSlicer GUI initialization failed" +msgstr "Помилка ініціалізації графічного інтерфейсу PrusaSlicer" + +#: src/slic3r/GUI/GUI_Init.cpp:76 +msgid "Fatal error, exception catched: %1%" +msgstr "Фатальна помилка, вилучений виняток: %1%" + +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:29 +msgid "Start at height" +msgstr "Початкова висота" + +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:29 +msgid "Stop at height" +msgstr "Кінцева висота" + +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:161 +msgid "Remove layer range" +msgstr "Видалити діапазон шарів" + +#: src/slic3r/GUI/GUI_ObjectLayers.cpp:165 +msgid "Add layer range" +msgstr "Додати діапазон шарів" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:34 src/slic3r/GUI/GUI_ObjectList.cpp:92 +#: src/slic3r/GUI/GUI_ObjectList.cpp:667 src/libslic3r/PrintConfig.cpp:74 +#: src/libslic3r/PrintConfig.cpp:189 src/libslic3r/PrintConfig.cpp:231 +#: src/libslic3r/PrintConfig.cpp:240 src/libslic3r/PrintConfig.cpp:464 +#: src/libslic3r/PrintConfig.cpp:530 src/libslic3r/PrintConfig.cpp:538 +#: src/libslic3r/PrintConfig.cpp:970 src/libslic3r/PrintConfig.cpp:1219 +#: src/libslic3r/PrintConfig.cpp:1584 src/libslic3r/PrintConfig.cpp:1650 +#: src/libslic3r/PrintConfig.cpp:1835 src/libslic3r/PrintConfig.cpp:2302 +#: src/libslic3r/PrintConfig.cpp:2361 src/libslic3r/PrintConfig.cpp:2370 +msgid "Layers and Perimeters" +msgstr "Шари та периметри" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:36 src/slic3r/GUI/GUI_ObjectList.cpp:95 +#: src/slic3r/GUI/GUI_ObjectList.cpp:670 src/slic3r/GUI/GUI_Preview.cpp:240 +#: src/slic3r/GUI/Tab.cpp:1472 src/slic3r/GUI/Tab.cpp:1474 +#: src/libslic3r/ExtrusionEntity.cpp:320 src/libslic3r/ExtrusionEntity.cpp:352 +#: src/libslic3r/PrintConfig.cpp:426 src/libslic3r/PrintConfig.cpp:1715 +#: src/libslic3r/PrintConfig.cpp:2093 src/libslic3r/PrintConfig.cpp:2099 +#: src/libslic3r/PrintConfig.cpp:2107 src/libslic3r/PrintConfig.cpp:2119 +#: src/libslic3r/PrintConfig.cpp:2129 src/libslic3r/PrintConfig.cpp:2137 +#: src/libslic3r/PrintConfig.cpp:2152 src/libslic3r/PrintConfig.cpp:2173 +#: src/libslic3r/PrintConfig.cpp:2185 src/libslic3r/PrintConfig.cpp:2201 +#: src/libslic3r/PrintConfig.cpp:2210 src/libslic3r/PrintConfig.cpp:2219 +#: src/libslic3r/PrintConfig.cpp:2230 src/libslic3r/PrintConfig.cpp:2244 +#: src/libslic3r/PrintConfig.cpp:2252 src/libslic3r/PrintConfig.cpp:2253 +#: src/libslic3r/PrintConfig.cpp:2262 src/libslic3r/PrintConfig.cpp:2270 +#: src/libslic3r/PrintConfig.cpp:2284 +msgid "Support material" +msgstr "Підтримка" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:39 src/slic3r/GUI/GUI_ObjectList.cpp:99 +#: src/slic3r/GUI/GUI_ObjectList.cpp:674 src/libslic3r/PrintConfig.cpp:2480 +#: src/libslic3r/PrintConfig.cpp:2488 +msgid "Wipe options" +msgstr "Параметри витирання" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:45 +msgid "Pad and Support" +msgstr "Подушка та підтримки" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:51 +msgid "Add part" +msgstr "Додати частину" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:52 +msgid "Add modifier" +msgstr "Додати модифікатор" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:53 +msgid "Add support enforcer" +msgstr "Додати примусову підтримку" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:54 +msgid "Add support blocker" +msgstr "Додати блокувальник підтримок" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:94 src/slic3r/GUI/GUI_ObjectList.cpp:669 +#: src/slic3r/GUI/GUI_Preview.cpp:236 src/slic3r/GUI/Tab.cpp:1442 +#: src/libslic3r/ExtrusionEntity.cpp:316 src/libslic3r/ExtrusionEntity.cpp:344 +#: src/libslic3r/PrintConfig.cpp:1226 src/libslic3r/PrintConfig.cpp:1232 +#: src/libslic3r/PrintConfig.cpp:1246 src/libslic3r/PrintConfig.cpp:1256 +#: src/libslic3r/PrintConfig.cpp:1264 src/libslic3r/PrintConfig.cpp:1266 +msgid "Ironing" +msgstr "Прасування" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:96 src/slic3r/GUI/GUI_ObjectList.cpp:671 +#: src/slic3r/GUI/GUI_Preview.cpp:217 src/slic3r/GUI/Tab.cpp:1498 +#: src/libslic3r/PrintConfig.cpp:291 src/libslic3r/PrintConfig.cpp:518 +#: src/libslic3r/PrintConfig.cpp:1012 src/libslic3r/PrintConfig.cpp:1192 +#: src/libslic3r/PrintConfig.cpp:1265 src/libslic3r/PrintConfig.cpp:1640 +#: src/libslic3r/PrintConfig.cpp:1916 src/libslic3r/PrintConfig.cpp:1968 +#: src/libslic3r/PrintConfig.cpp:2346 +msgid "Speed" +msgstr "Швидкість" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:97 src/slic3r/GUI/GUI_ObjectList.cpp:672 +#: src/slic3r/GUI/Tab.cpp:1534 src/slic3r/GUI/Tab.cpp:2112 +#: src/libslic3r/PrintConfig.cpp:548 src/libslic3r/PrintConfig.cpp:1146 +#: src/libslic3r/PrintConfig.cpp:1618 src/libslic3r/PrintConfig.cpp:1937 +#: src/libslic3r/PrintConfig.cpp:2165 src/libslic3r/PrintConfig.cpp:2192 +msgid "Extruders" +msgstr "Екструдери" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:98 src/slic3r/GUI/GUI_ObjectList.cpp:673 +#: src/libslic3r/PrintConfig.cpp:507 src/libslic3r/PrintConfig.cpp:616 +#: src/libslic3r/PrintConfig.cpp:957 src/libslic3r/PrintConfig.cpp:1154 +#: src/libslic3r/PrintConfig.cpp:1627 src/libslic3r/PrintConfig.cpp:1957 +#: src/libslic3r/PrintConfig.cpp:2174 src/libslic3r/PrintConfig.cpp:2334 +msgid "Extrusion Width" +msgstr "Ширина екструзії" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:102 src/slic3r/GUI/GUI_ObjectList.cpp:677 +#: src/slic3r/GUI/Tab.cpp:1428 src/slic3r/GUI/Tab.cpp:1452 +#: src/slic3r/GUI/Tab.cpp:1555 src/slic3r/GUI/Tab.cpp:1558 +#: src/slic3r/GUI/Tab.cpp:1855 src/slic3r/GUI/Tab.cpp:2197 +#: src/slic3r/GUI/Tab.cpp:4114 src/libslic3r/PrintConfig.cpp:92 +#: src/libslic3r/PrintConfig.cpp:132 src/libslic3r/PrintConfig.cpp:279 +#: src/libslic3r/PrintConfig.cpp:1097 src/libslic3r/PrintConfig.cpp:1181 +#: src/libslic3r/PrintConfig.cpp:2504 src/libslic3r/PrintConfig.cpp:2676 +msgid "Advanced" +msgstr "Розширений" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:104 src/slic3r/GUI/GUI_ObjectList.cpp:679 +#: src/slic3r/GUI/Plater.cpp:357 src/slic3r/GUI/Tab.cpp:4048 +#: src/slic3r/GUI/Tab.cpp:4049 src/libslic3r/PrintConfig.cpp:2842 +#: src/libslic3r/PrintConfig.cpp:2849 src/libslic3r/PrintConfig.cpp:2858 +#: src/libslic3r/PrintConfig.cpp:2867 src/libslic3r/PrintConfig.cpp:2877 +#: src/libslic3r/PrintConfig.cpp:2887 src/libslic3r/PrintConfig.cpp:2924 +#: src/libslic3r/PrintConfig.cpp:2931 src/libslic3r/PrintConfig.cpp:2942 +#: src/libslic3r/PrintConfig.cpp:2952 src/libslic3r/PrintConfig.cpp:2961 +#: src/libslic3r/PrintConfig.cpp:2974 src/libslic3r/PrintConfig.cpp:2984 +#: src/libslic3r/PrintConfig.cpp:2993 src/libslic3r/PrintConfig.cpp:3003 +#: src/libslic3r/PrintConfig.cpp:3014 src/libslic3r/PrintConfig.cpp:3022 +msgid "Supports" +msgstr "Підтримки" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:105 src/slic3r/GUI/GUI_ObjectList.cpp:680 +#: src/slic3r/GUI/Plater.cpp:500 src/slic3r/GUI/Tab.cpp:4089 +#: src/slic3r/GUI/Tab.cpp:4090 src/slic3r/GUI/Tab.cpp:4161 +#: src/libslic3r/PrintConfig.cpp:3030 src/libslic3r/PrintConfig.cpp:3037 +#: src/libslic3r/PrintConfig.cpp:3051 src/libslic3r/PrintConfig.cpp:3062 +#: src/libslic3r/PrintConfig.cpp:3072 src/libslic3r/PrintConfig.cpp:3094 +#: src/libslic3r/PrintConfig.cpp:3105 src/libslic3r/PrintConfig.cpp:3112 +#: src/libslic3r/PrintConfig.cpp:3119 src/libslic3r/PrintConfig.cpp:3130 +#: src/libslic3r/PrintConfig.cpp:3139 src/libslic3r/PrintConfig.cpp:3148 +msgid "Pad" +msgstr "Подушка" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:106 src/slic3r/GUI/Tab.cpp:4107 +#: src/slic3r/GUI/Tab.cpp:4108 src/libslic3r/SLA/Hollowing.cpp:45 +#: src/libslic3r/SLA/Hollowing.cpp:57 src/libslic3r/SLA/Hollowing.cpp:66 +#: src/libslic3r/SLA/Hollowing.cpp:75 src/libslic3r/PrintConfig.cpp:3158 +#: src/libslic3r/PrintConfig.cpp:3165 src/libslic3r/PrintConfig.cpp:3175 +#: src/libslic3r/PrintConfig.cpp:3184 +msgid "Hollowing" +msgstr "Випорожнення" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:300 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:161 +msgid "Name" +msgstr "Ім'я" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:316 src/slic3r/GUI/GUI_ObjectList.cpp:457 +msgid "Editing" +msgstr "Редагування" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:402 +#, c-format +msgid "Auto-repaired (%d errors):" +msgstr "Авто-відновлення (%d помилок):" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:409 +msgid "degenerate facets" +msgstr "вироджені грані" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:410 +msgid "edges fixed" +msgstr "виправлено країв" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:411 +msgid "facets removed" +msgstr "вилучено граней" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:412 +msgid "facets added" +msgstr "додано граней" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:413 +msgid "facets reversed" +msgstr "змінено граней" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:414 +msgid "backwards edges" +msgstr "повернуто країв" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:422 +msgid "Right button click the icon to fix STL through Netfabb" +msgstr "Клацніть правою кнопкою миші, щоб виправити STL за допомогою Netfabb" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:459 +msgid "Right button click the icon to change the object settings" +msgstr "" +"Клацніть правою кнопкою миші на піктограмі, щоб змінити налаштування об'єкта" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:461 +msgid "Click the icon to change the object settings" +msgstr "Клацніть на піктограмі, щоб змінити налаштування об'єкта" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:465 +msgid "Right button click the icon to change the object printable property" +msgstr "" +"Клацніть правою кнопкою миші на піктограмі, щоб змінити властивість друку " +"для об'єкта" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:467 +msgid "Click the icon to change the object printable property" +msgstr "Клацніть на піктограмі, щоб змінити властивість друку для об'єкта" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:590 +msgid "Change Extruder" +msgstr "Змінити екструдер" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:605 +msgid "Rename Object" +msgstr "Перейменувати об'єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:605 +msgid "Rename Sub-object" +msgstr "Перейменувати підоб'єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1247 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4372 +msgid "Instances to Separated Objects" +msgstr "Змінити екземпляри на окремі об'єкти" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1262 +msgid "Volumes in Object reordered" +msgstr "Об’єкт впорядковано" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1262 +msgid "Object reordered" +msgstr "Об’єкт впорядковано" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1338 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1693 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1699 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2081 +#, c-format +msgid "Quick Add Settings (%s)" +msgstr "Швидке додання налаштувань (%s)" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1428 +msgid "Select showing settings" +msgstr "Виберіть налаштування для показу" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1477 +msgid "Add Settings for Layers" +msgstr "Додати налаштування для шарів" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1478 +msgid "Add Settings for Sub-object" +msgstr "Додати налаштування для підоб'єкту" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1479 +msgid "Add Settings for Object" +msgstr "Додати налаштування для об'єкту" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1549 +msgid "Add Settings Bundle for Height range" +msgstr "Додати пакет налаштувань для діапазону висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1550 +msgid "Add Settings Bundle for Sub-object" +msgstr "Додати пакет налаштувань для підоб'єкту" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1551 +msgid "Add Settings Bundle for Object" +msgstr "Додати пакет налаштувань для об'єкту" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1590 +msgid "Load" +msgstr "Завантажити" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1627 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1631 +msgid "Box" +msgstr "Коробка" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +msgid "Cylinder" +msgstr "Циліндр" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1595 +msgid "Slab" +msgstr "Плита" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1663 +msgid "Height range Modifier" +msgstr "Модифікатор діапазону висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1672 +msgid "Add settings" +msgstr "Додати налаштування" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1750 +msgid "Change type" +msgstr "Змінити тип" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1760 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1772 +msgid "Set as a Separated Object" +msgstr "Встановити як окремий об’єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1772 msgid "Set as a Separated Objects" -msgstr "" +msgstr "Встановити як окремі об’єкти" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1374 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1782 +msgid "Printable" +msgstr "Для друку" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1797 +msgid "Rename" +msgstr "Перейменувати" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1808 +msgid "Fix through the Netfabb" +msgstr "Виправити за допомогою NetFabb" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1818 src/slic3r/GUI/Plater.cpp:4035 +msgid "Export as STL" +msgstr "Експортувати як STL" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1825 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4567 src/slic3r/GUI/Plater.cpp:4001 +msgid "Reload the selected volumes from disk" +msgstr "Перезавантажити вибрані часті з диска" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1832 +msgid "Set extruder for selected items" +msgstr "Встановити екструдер для вибраних елементів" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1864 src/libslic3r/PrintConfig.cpp:391 +msgid "Default" +msgstr "За замовчуванням" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1884 +msgid "Scale to print volume" +msgstr "Масштабувати під область друку" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1884 +msgid "Scale the selected object to fit the print volume" +msgstr "Масштабуйте вибраний об'єкт відповідно до об'єму столу" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1913 src/slic3r/GUI/Plater.cpp:5224 +msgid "Convert from imperial units" +msgstr "Конвертувати з імперських одиниць" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1915 src/slic3r/GUI/Plater.cpp:5224 +msgid "Revert conversion from imperial units" +msgstr "Повернути конвертацію з імперських одиниць" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1944 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1952 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2630 src/libslic3r/PrintConfig.cpp:3730 +msgid "Merge" +msgstr "Об’єднати" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1944 +msgid "Merge objects to the one multipart object" +msgstr "Об'єднати об'єкти в один багаточастковий об'єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1952 +msgid "Merge objects to the one single object" +msgstr "Об’єднайте об’єкти в один єдиний об’єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2026 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2283 +msgid "Add Shape" +msgstr "Додати форму" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2111 +msgid "Load Part" +msgstr "Завантажити частину" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2150 +msgid "Error!" +msgstr "Помилка!" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2225 +msgid "Add Generic Subobject" +msgstr "Додати загальний підоб'єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2254 msgid "Generic" -msgstr "" +msgstr "Загальний" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1516 -msgid "You can't delete the last solid part from object." -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:2380 +msgid "Delete Settings" +msgstr "Видалити налаштування" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1533 -msgid "You can't delete the last intance from object." -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:2402 +msgid "Delete All Instances from Object" +msgstr "Видалити всі екземпляри з об’єкта" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1560 src/slic3r/GUI/Plater.cpp:2219 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2418 +msgid "Delete Height Range" +msgstr "Видалити діапазон висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2450 +msgid "From Object List You can't delete the last solid part from object." +msgstr "" +"Зі списку об’єктів Ви не можете видалити останню суцільну частину з об’єкта." + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2454 +msgid "Delete Subobject" +msgstr "Видалити підоб'єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2469 +msgid "Last instance of an object cannot be deleted." +msgstr "Не можна видалити останній екземпляр з об'єкту." + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2473 +msgid "Delete Instance" +msgstr "Видалити екземпляр" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2497 src/slic3r/GUI/Plater.cpp:2865 msgid "" "The selected object couldn't be split because it contains only one part." msgstr "" "Вибраний об'єкт не можна розділити, оскільки він містить лише одну частину." -#: src/slic3r/GUI/GUI_ObjectList.cpp:1676 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2501 +msgid "Split to Parts" +msgstr "Розділити на частини" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2637 +msgid "Merged" +msgstr "Об’єднано" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2721 +msgid "Merge all parts to the one single object" +msgstr "Об’єднати всі частини в єдиний об’єкт" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2753 +msgid "Add Layers" +msgstr "Додати шари" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2907 msgid "Group manipulation" -msgstr "" +msgstr "Маніпулювання групою" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1688 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2919 msgid "Object manipulation" -msgstr "" +msgstr "Маніпулювання об'єктом" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1698 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2932 msgid "Object Settings to modify" -msgstr "" +msgstr "Параметри об'єкту, які можна змінювати" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1702 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2936 msgid "Part Settings to modify" -msgstr "" +msgstr "Параметри частини, які можна змінювати" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1711 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2941 +msgid "Layer range Settings to modify" +msgstr "Пакет налаштувань для діапазону висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2947 msgid "Part manipulation" -msgstr "" +msgstr "Маніпулювання частиною" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1717 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2953 msgid "Instance manipulation" -msgstr "" +msgstr "Маніпулювання екземпляром" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2240 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2960 +msgid "Height ranges" +msgstr "Діапазони висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:2960 +msgid "Settings for height range" +msgstr "Налаштування діапазону висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3144 +msgid "Delete Selected Item" +msgstr "Видалити вибраний елемент" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3332 +msgid "Delete Selected" +msgstr "Видалити вибране" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3408 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3436 +#: src/slic3r/GUI/GUI_ObjectList.cpp:3456 +msgid "Add Height Range" +msgstr "Додати діапазон висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3502 +msgid "" +"Cannot insert a new layer range after the current layer range.\n" +"The next layer range is too thin to be split to two\n" +"without violating the minimum layer height." +msgstr "" +"Не вдається вставити новий діапазон шарів після поточного діапазону шарів.\n" +"Діапазон наступного шару занадто тонкий, щоб його можна було розділити на " +"два\n" +"без порушення мінімальної висоти шару." + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3506 +msgid "" +"Cannot insert a new layer range between the current and the next layer " +"range.\n" +"The gap between the current layer range and the next layer range\n" +"is thinner than the minimum layer height allowed." +msgstr "" +"Не вдається вставити новий діапазон шарів між поточним та наступним " +"діапазоном шарів.\n" +"Розрив між діапазоном поточного шару та діапазоном наступного шару\n" +"тонше мінімально допустимої висоти шару." + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3511 +msgid "" +"Cannot insert a new layer range after the current layer range.\n" +"Current layer range overlaps with the next layer range." +msgstr "" +"Не вдається вставити новий діапазон шарів після поточного діапазону шарів.\n" +"Діапазон поточного шару перекривається з діапазоном наступного шару." + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3570 +msgid "Edit Height Range" +msgstr "Редагування діапазону висот" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3865 +msgid "Selection-Remove from list" +msgstr "Виділення - Видалено зі списку" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:3873 +msgid "Selection-Add from list" +msgstr "Виділення - Додано зі списку" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4008 msgid "Object or Instance" -msgstr "" +msgstr "\"Об’єкт\" або \"Екземпляр\"" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2240 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4009 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 msgid "Part" -msgstr "" +msgstr "\"Частина\"" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2242 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4009 +msgid "Layer" +msgstr "\"Шар\"" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4011 msgid "Unsupported selection" -msgstr "" +msgstr "Непідтримуваний вибір" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2243 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4012 #, c-format msgid "You started your selection with %s Item." -msgstr "" +msgstr "Ви розпочали свій вибір з елемента %s." -#: src/slic3r/GUI/GUI_ObjectList.cpp:2244 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4013 #, c-format msgid "In this mode you can select only other %s Items%s" -msgstr "" +msgstr "В цьому режимі ви можете вибирати тільки інші %s %s" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2247 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4016 msgid "of a current Object" -msgstr "" +msgstr "поточного \"Об'єкта\"" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2252 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2325 src/slic3r/GUI/Plater.cpp:117 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4021 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4096 src/slic3r/GUI/Plater.cpp:143 msgid "Info" msgstr "Інфо" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2366 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4137 msgid "You can't change a type of the last solid part of the object." -msgstr "" +msgstr "Ви не можете змінити тип останньої твердої частини об’єкта." -#: src/slic3r/GUI/GUI_ObjectList.cpp:2373 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +msgid "Modifier" +msgstr "Модифікатор" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +msgid "Support Enforcer" +msgstr "Примусова підтримка" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4142 +msgid "Support Blocker" +msgstr "Блокувальник підтримок" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4144 msgid "Select type of part" -msgstr "" +msgstr "Змінити тип частини" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2538 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4149 +msgid "Change Part Type" +msgstr "Змінити тип деталі" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4394 msgid "Enter new name" -msgstr "" +msgstr "Введіть нову назву" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2538 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4394 msgid "Renaming" -msgstr "" +msgstr "Перейменування" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2554 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2632 src/slic3r/GUI/Tab.cpp:3191 -#: src/slic3r/GUI/Tab.cpp:3195 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4410 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4537 +#: src/slic3r/GUI/SavePresetDialog.cpp:101 +#: src/slic3r/GUI/SavePresetDialog.cpp:109 msgid "The supplied name is not valid;" -msgstr "" +msgstr "Надане ім'я недійсне;" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2555 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2633 src/slic3r/GUI/Tab.cpp:3192 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4411 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4538 +#: src/slic3r/GUI/SavePresetDialog.cpp:102 msgid "the following characters are not allowed:" -msgstr "" +msgstr "такі символи не допускаються:" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2653 -msgid "Set extruder for selected items" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:2654 -msgid "Select extruder number for selected objects and/or parts" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:2667 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4586 msgid "Select extruder number:" -msgstr "" +msgstr "Виберіть номер екструдера:" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2668 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4587 msgid "This extruder will be set for selected items" -msgstr "" +msgstr "Цей екструдер буде встановлений для вибраних елементів" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:25 -msgid "Object Manipulation" -msgstr "" +#: src/slic3r/GUI/GUI_ObjectList.cpp:4612 +msgid "Change Extruders" +msgstr "Змінити екструдери" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:47 +#: src/slic3r/GUI/GUI_ObjectList.cpp:4709 src/slic3r/GUI/Selection.cpp:1485 +msgid "Set Printable" +msgstr "Встановити \"Для друку\"" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:4709 src/slic3r/GUI/Selection.cpp:1485 +msgid "Set Unprintable" +msgstr "Встановити \"Не для друку\"" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:68 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:111 +msgid "World coordinates" +msgstr "Світові координати" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:69 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:112 +msgid "Local coordinates" +msgstr "Локальні координати" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:88 +msgid "Select coordinate space, in which the transformation will be performed." +msgstr "Виберіть простір координат, в якому буде виконуватися перетворення." + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:163 src/libslic3r/GCode.cpp:537 msgid "Object name" -msgstr "" +msgstr "Назва об'єкту" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:115 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:160 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:223 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:505 msgid "Position" -msgstr "" +msgstr "Позиція" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:116 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:161 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:224 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:506 +#: src/slic3r/GUI/Mouse3DController.cpp:486 +#: src/slic3r/GUI/Mouse3DController.cpp:507 msgid "Rotation" -msgstr "" +msgstr "Обертання" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:117 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:201 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:221 -#: src/libslic3r/PrintConfig.cpp:3070 -msgid "Scale" +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:271 +#, c-format +msgid "Toggle %c axis mirroring" +msgstr "Переключити дзеркальне відображення за осею %c" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:305 +msgid "Set Mirror" +msgstr "Встановити віддзеркалення" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:345 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:357 +msgid "Drop to bed" +msgstr "Поставити на стіл" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:372 +msgid "Reset rotation" +msgstr "Скинути обертання" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:394 +msgid "Reset Rotation" +msgstr "Скинути обертання" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:407 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:409 +msgid "Reset scale" +msgstr "Скинути масштаб" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:423 +msgid "Inches" +msgstr "Дюймів" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:507 +msgid "Scale factors" msgstr "Масштаб" -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:162 -msgid "Scale factors" -msgstr "" - -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:200 -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:220 -#: src/libslic3r/PrintConfig.cpp:3055 -msgid "Rotate" -msgstr "Повернути" - -#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:219 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:561 msgid "Translate" -msgstr "" +msgstr "Перемістити" -#: src/slic3r/GUI/GUI_ObjectSettings.cpp:58 +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:625 +msgid "" +"You cannot use non-uniform scaling mode for multiple objects/parts selection" +msgstr "" +"Не можна використовувати нерівномірний режим масштабування, коли вибрано " +"кілька об’єктів/частей" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:797 +msgid "Set Position" +msgstr "Встановити позицію" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:828 +msgid "Set Orientation" +msgstr "Встановити орієнтацію" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:893 +msgid "Set Scale" +msgstr "Встановити масштаб" + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:925 +msgid "" +"The currently manipulated object is tilted (rotation angles are not " +"multiples of 90°).\n" +"Non-uniform scaling of tilted objects is only possible in the World " +"coordinate system,\n" +"once the rotation is embedded into the object coordinates." +msgstr "" +"В даний час маніпульований об'єкт нахилений (кути повороту не кратні 90 °).\n" +"Нерівномірне масштабування нахилених предметів можливе лише у світовій " +"системі координат,\n" +"як тільки обертання буде вбудовано в координати об’єкта." + +#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:928 +msgid "" +"This operation is irreversible.\n" +"Do you want to proceed?" +msgstr "" +"Ця операція незворотна.\n" +"Ви хочете продовжити?" + +#: src/slic3r/GUI/GUI_ObjectSettings.cpp:62 msgid "Additional Settings" -msgstr "" +msgstr "Додаткові налаштування" -#: src/slic3r/GUI/GUI_Preview.cpp:209 +#: src/slic3r/GUI/GUI_ObjectSettings.cpp:98 +msgid "Remove parameter" +msgstr "Видалити параметр" + +#: src/slic3r/GUI/GUI_ObjectSettings.cpp:104 +#, c-format +msgid "Delete Option %s" +msgstr "Видалити параметр %s" + +#: src/slic3r/GUI/GUI_ObjectSettings.cpp:157 +#, c-format +msgid "Change Option %s" +msgstr "Змінити параметр %s" + +#: src/slic3r/GUI/GUI_Preview.cpp:212 msgid "View" msgstr "Вид" -#: src/slic3r/GUI/GUI_Preview.cpp:212 src/slic3r/GUI/GUI_Preview.cpp:525 -#: src/libslic3r/GCode/PreviewData.cpp:394 -msgid "Feature type" -msgstr "Тип ознаки" - -#: src/slic3r/GUI/GUI_Preview.cpp:213 src/libslic3r/PrintConfig.cpp:467 +#: src/slic3r/GUI/GUI_Preview.cpp:215 src/libslic3r/PrintConfig.cpp:560 msgid "Height" msgstr "Висота" -#: src/slic3r/GUI/GUI_Preview.cpp:214 src/libslic3r/PrintConfig.cpp:2135 +#: src/slic3r/GUI/GUI_Preview.cpp:216 src/libslic3r/PrintConfig.cpp:2466 msgid "Width" msgstr "Ширина" -#: src/slic3r/GUI/GUI_Preview.cpp:216 +#: src/slic3r/GUI/GUI_Preview.cpp:218 src/slic3r/GUI/Tab.cpp:1840 +msgid "Fan speed" +msgstr "Швидкість вентилятора" + +#: src/slic3r/GUI/GUI_Preview.cpp:219 msgid "Volumetric flow rate" -msgstr "" +msgstr "Об'ємна швидкість потоку" -#: src/slic3r/GUI/GUI_Preview.cpp:217 src/slic3r/GUI/GUI_Preview.cpp:315 -#: src/slic3r/GUI/GUI_Preview.cpp:469 src/slic3r/GUI/GUI_Preview.cpp:525 -#: src/slic3r/GUI/GUI_Preview.cpp:701 src/libslic3r/GCode/PreviewData.cpp:404 -msgid "Tool" -msgstr "Інструмент" - -#: src/slic3r/GUI/GUI_Preview.cpp:218 src/slic3r/GUI/GUI_Preview.cpp:523 -#: src/libslic3r/GCode/PreviewData.cpp:406 -msgid "Color Print" -msgstr "" - -#: src/slic3r/GUI/GUI_Preview.cpp:221 +#: src/slic3r/GUI/GUI_Preview.cpp:224 msgid "Show" msgstr "Показати" -#: src/slic3r/GUI/GUI_Preview.cpp:224 src/slic3r/GUI/GUI_Preview.cpp:225 +#: src/slic3r/GUI/GUI_Preview.cpp:227 src/slic3r/GUI/GUI_Preview.cpp:245 msgid "Feature types" msgstr "Типи ознак" -#: src/slic3r/GUI/GUI_Preview.cpp:227 src/libslic3r/GCode/PreviewData.cpp:163 +#: src/slic3r/GUI/GUI_Preview.cpp:230 src/libslic3r/ExtrusionEntity.cpp:310 +#: src/libslic3r/ExtrusionEntity.cpp:332 msgid "Perimeter" msgstr "Периметр" -#: src/slic3r/GUI/GUI_Preview.cpp:228 src/libslic3r/GCode/PreviewData.cpp:164 +#: src/slic3r/GUI/GUI_Preview.cpp:231 src/libslic3r/ExtrusionEntity.cpp:311 +#: src/libslic3r/ExtrusionEntity.cpp:334 msgid "External perimeter" msgstr "Зовнішній периметр" -#: src/slic3r/GUI/GUI_Preview.cpp:229 src/libslic3r/GCode/PreviewData.cpp:165 +#: src/slic3r/GUI/GUI_Preview.cpp:232 src/libslic3r/ExtrusionEntity.cpp:312 +#: src/libslic3r/ExtrusionEntity.cpp:336 msgid "Overhang perimeter" msgstr "Нависаючий периметр" -#: src/slic3r/GUI/GUI_Preview.cpp:230 src/libslic3r/GCode/PreviewData.cpp:166 +#: src/slic3r/GUI/GUI_Preview.cpp:233 src/libslic3r/ExtrusionEntity.cpp:313 +#: src/libslic3r/ExtrusionEntity.cpp:338 msgid "Internal infill" msgstr "Внутрішнє наповнення" -#: src/slic3r/GUI/GUI_Preview.cpp:231 src/libslic3r/PrintConfig.cpp:1686 -#: src/libslic3r/PrintConfig.cpp:1696 src/libslic3r/GCode/PreviewData.cpp:167 +#: src/slic3r/GUI/GUI_Preview.cpp:234 src/libslic3r/ExtrusionEntity.cpp:314 +#: src/libslic3r/ExtrusionEntity.cpp:340 src/libslic3r/PrintConfig.cpp:1956 +#: src/libslic3r/PrintConfig.cpp:1967 msgid "Solid infill" msgstr "Суцільне наповнення" -#: src/slic3r/GUI/GUI_Preview.cpp:232 src/libslic3r/PrintConfig.cpp:2016 -#: src/libslic3r/PrintConfig.cpp:2027 src/libslic3r/GCode/PreviewData.cpp:168 +#: src/slic3r/GUI/GUI_Preview.cpp:235 src/libslic3r/ExtrusionEntity.cpp:315 +#: src/libslic3r/ExtrusionEntity.cpp:342 src/libslic3r/PrintConfig.cpp:2333 +#: src/libslic3r/PrintConfig.cpp:2345 msgid "Top solid infill" msgstr "Верхнє суцільне наповнення" -#: src/slic3r/GUI/GUI_Preview.cpp:233 src/libslic3r/GCode/PreviewData.cpp:169 +#: src/slic3r/GUI/GUI_Preview.cpp:237 src/libslic3r/ExtrusionEntity.cpp:317 +#: src/libslic3r/ExtrusionEntity.cpp:346 msgid "Bridge infill" msgstr "Мостове наповнення" -#: src/slic3r/GUI/GUI_Preview.cpp:234 src/libslic3r/PrintConfig.cpp:869 -#: src/libslic3r/GCode/PreviewData.cpp:170 +#: src/slic3r/GUI/GUI_Preview.cpp:238 src/libslic3r/ExtrusionEntity.cpp:318 +#: src/libslic3r/ExtrusionEntity.cpp:348 src/libslic3r/PrintConfig.cpp:1011 msgid "Gap fill" msgstr "Заповнення розриву" -#: src/slic3r/GUI/GUI_Preview.cpp:235 src/slic3r/GUI/Tab.cpp:1001 -#: src/libslic3r/GCode/PreviewData.cpp:171 +#: src/slic3r/GUI/GUI_Preview.cpp:239 src/slic3r/GUI/Tab.cpp:1462 +#: src/libslic3r/ExtrusionEntity.cpp:319 src/libslic3r/ExtrusionEntity.cpp:350 msgid "Skirt" msgstr "Плінтус" -#: src/slic3r/GUI/GUI_Preview.cpp:237 src/libslic3r/PrintConfig.cpp:1903 -#: src/libslic3r/GCode/PreviewData.cpp:173 +#: src/slic3r/GUI/GUI_Preview.cpp:241 src/libslic3r/ExtrusionEntity.cpp:321 +#: src/libslic3r/ExtrusionEntity.cpp:354 src/libslic3r/PrintConfig.cpp:2218 msgid "Support material interface" msgstr "Інтерфейс підтримуючого матеріалу" -#: src/slic3r/GUI/GUI_Preview.cpp:238 src/slic3r/GUI/Tab.cpp:1081 -#: src/libslic3r/GCode/PreviewData.cpp:174 +#: src/slic3r/GUI/GUI_Preview.cpp:242 src/slic3r/GUI/Tab.cpp:1545 +#: src/libslic3r/ExtrusionEntity.cpp:322 src/libslic3r/ExtrusionEntity.cpp:356 msgid "Wipe tower" -msgstr "Вежа вичищування" +msgstr "Вежа витирання" -#: src/slic3r/GUI/GUI_Preview.cpp:243 src/libslic3r/PrintConfig.cpp:2049 -msgid "Travel" -msgstr "Пересування" - -#: src/slic3r/GUI/GUI_Preview.cpp:244 -msgid "Retractions" -msgstr "Переривання" - -#: src/slic3r/GUI/GUI_Preview.cpp:245 -msgid "Unretractions" -msgstr "Непереривання" - -#: src/slic3r/GUI/GUI_Preview.cpp:246 +#: src/slic3r/GUI/GUI_Preview.cpp:1031 msgid "Shells" msgstr "Оболонки" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:13 -msgid "Slic3r Prusa Edition - Keyboard Shortcuts" +#: src/slic3r/GUI/GUI_Preview.cpp:1032 +msgid "Tool marker" +msgstr "Маркер інструменту" + +#: src/slic3r/GUI/GUI_Preview.cpp:1033 +msgid "Legend/Estimated printing time" +msgstr "Легенда / Приблизний час друку" + +#: src/slic3r/GUI/ImGuiWrapper.cpp:804 src/slic3r/GUI/Search.cpp:389 +msgid "Use for search" +msgstr "Використовуйте для пошуку" + +#: src/slic3r/GUI/ImGuiWrapper.cpp:805 src/slic3r/GUI/Search.cpp:383 +msgid "Category" +msgstr "Категорія" + +#: src/slic3r/GUI/ImGuiWrapper.cpp:807 src/slic3r/GUI/Search.cpp:385 +msgid "Search in English" +msgstr "Шукати англійською мовою" + +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:145 +msgid "Arranging" +msgstr "Розташування" + +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:175 +msgid "Could not arrange model objects! Some geometries may be invalid." msgstr "" +"Не вдалося розташувати об’єкти моделі! Деякі геометрії можуть бути невірними." + +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:181 +msgid "Arranging canceled." +msgstr "Розташування скасовано." + +#: src/slic3r/GUI/Jobs/ArrangeJob.cpp:182 +msgid "Arranging done." +msgstr "Розташування виконано." + +#: src/slic3r/GUI/Jobs/Job.cpp:75 +msgid "ERROR: not enough resources to execute a new job." +msgstr "ПОМИЛКА: недостатньо ресурсів для виконання нового завдання." + +#: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:41 +msgid "Searching for optimal orientation" +msgstr "Пошук оптимальної орієнтації" + +#: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:73 +msgid "Orientation search canceled." +msgstr "Пошук орієнтації скасовано." + +#: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:74 +msgid "Orientation found." +msgstr "Орієнтація знайдена." + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:35 +msgid "Choose SLA archive:" +msgstr "Виберіть SLA-архів:" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:39 +msgid "Import file" +msgstr "Імпорт файлу" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:46 +msgid "Import model and profile" +msgstr "Імпорт моделі та профілю" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:47 +msgid "Import profile only" +msgstr "Імпорт тільки профілю" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:48 +msgid "Import model only" +msgstr "Імпорт тільки моделі" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:59 +msgid "Accurate" +msgstr "Точний" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:60 +msgid "Balanced" +msgstr "Збалансований" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:61 +msgid "Quick" +msgstr "Швидко" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:135 +msgid "Importing SLA archive" +msgstr "Імпорт SLA-архіву" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:159 +msgid "Importing canceled." +msgstr "Імпорт скасовано." + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:160 +msgid "Importing done." +msgstr "Імпорт виконано." + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:208 src/slic3r/GUI/Plater.cpp:2357 +msgid "You cannot load SLA project with a multi-part object on the bed" +msgstr "" +"Ви не можете завантажувати SLA-проект, що містить об'єкт, який складається з " +"кількох частин" + +#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:209 src/slic3r/GUI/Plater.cpp:2358 +#: src/slic3r/GUI/Tab.cpp:3243 +msgid "Please check your object list before preset changing." +msgstr "" +"Будь ласка, перевірте свій список об'єктів перед тим, як змінити пресет." + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:17 src/slic3r/GUI/MainFrame.cpp:894 +msgid "Keyboard Shortcuts" +msgstr "Гарячі клавіши" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:69 +msgid "New project, clear plater" +msgstr "Новий проект, очистити платер" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:70 +msgid "Open project STL/OBJ/AMF/3MF with config, clear plater" +msgstr "Відкрити проект STL / OBJ / AMF / 3MF з конфігурацією, очистити стіл" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:71 +msgid "Save project (3mf)" +msgstr "Зберегти проект (3mf)" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:72 +msgid "Save project as (3mf)" +msgstr "Зберегти проект як (3mf)" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:73 +msgid "(Re)slice" +msgstr "(Пере)Нарізати" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:75 +msgid "Import STL/OBJ/AMF/3MF without config, keep plater" +msgstr "Імпорт STL/OBJ/AMF/3MF без конфігурації зі збереженням платеру" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:76 +msgid "Import Config from ini/amf/3mf/gcode" +msgstr "Імпорт конфігурації з INI/AMF/3MF/GCODE" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:77 +msgid "Load Config from ini/amf/3mf/gcode and merge" +msgstr "Завантажити конфігурацію з INI/AMF/3MF/GCODE та об’єднати" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:79 src/slic3r/GUI/Plater.cpp:770 +#: src/slic3r/GUI/Plater.cpp:6054 src/libslic3r/PrintConfig.cpp:3635 +msgid "Export G-code" +msgstr "Експорт G-коду" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:80 src/slic3r/GUI/Plater.cpp:6055 +msgid "Send G-code" +msgstr "Надіслання G-коду" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:81 +msgid "Export config" +msgstr "Експорт конфігурації" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:82 src/slic3r/GUI/Plater.cpp:758 +msgid "Export to SD card / Flash drive" +msgstr "Експорт на SD-карту/флешку" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:83 +msgid "Eject SD card / Flash drive" +msgstr "Від'єднати SD-карту/флешку" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:85 +msgid "Select all objects" +msgstr "Вибрати всі об'єкти" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:86 +msgid "Deselect all" +msgstr "Скасувати весь вибір" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:87 +msgid "Delete selected" +msgstr "Видалити вибране" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:91 +msgid "Copy to clipboard" +msgstr "Скопіювати в буфер обміну" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:92 +msgid "Paste from clipboard" +msgstr "Вставити з буферу обміну" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:94 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:96 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:187 +msgid "Reload plater from disk" +msgstr "Перезавантажити стіл з диска" #: src/slic3r/GUI/KBShortcutsDialog.cpp:100 -msgid "Open project STL/OBJ/AMF/3MF with config, delete bed" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:101 -msgid "Import STL/OBJ/AMF/3MF without config, keep bed" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:102 -msgid "Load Config from .ini/amf/3mf/gcode" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:103 src/slic3r/GUI/Plater.cpp:725 -#: src/slic3r/GUI/Plater.cpp:3673 src/libslic3r/PrintConfig.cpp:2957 -msgid "Export G-code" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:104 -msgid "Save project (3MF)" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:105 -msgid "Load Config from .ini/amf/3mf/gcode and merge" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:106 -msgid "(Re)slice" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:107 -msgid "Quick slice" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:108 src/slic3r/GUI/MainFrame.cpp:326 -msgid "Repeat last quick slice" -msgstr "Повторити останнє швидке нарізання" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:109 msgid "Select Plater Tab" msgstr "Вибрати вкладку Plater" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:110 -msgid "Quick slice and Save as" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:111 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:101 msgid "Select Print Settings Tab" msgstr "Вибрати вкладку параметрів друку" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:112 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:102 msgid "Select Filament Settings Tab" msgstr "Вибрати вкладку параметрів філаменту" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:113 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:103 msgid "Select Printer Settings Tab" msgstr "Вибрати вкладку параметрів принтеру" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:114 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:104 msgid "Switch to 3D" -msgstr "" +msgstr "Переключити на 3D" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:115 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:105 msgid "Switch to Preview" -msgstr "" +msgstr "Переключити на Перегляд" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:116 src/slic3r/GUI/Preferences.cpp:10 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:106 +#: src/slic3r/GUI/PrintHostDialogs.cpp:165 +msgid "Print host upload queue" +msgstr "Черга завантаження хоста друку" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:107 src/slic3r/GUI/MainFrame.cpp:65 +#: src/slic3r/GUI/MainFrame.cpp:1191 +msgid "Open new instance" +msgstr "Відкрити новий екземпляр" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:109 +msgid "Camera view" +msgstr "Вид камери" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:110 +msgid "Show/Hide object/instance labels" +msgstr "Показати/сховати мітки об’єктів/екземплярів" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:112 src/slic3r/GUI/Preferences.cpp:13 msgid "Preferences" msgstr "Преференції" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:117 -#: src/slic3r/GUI/PrintHostDialogs.cpp:134 -msgid "Print host upload queue" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:118 -msgid "Camera view " -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:119 -msgid "Add Instance to selected object " -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:120 -msgid "Remove Instance from selected object" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:121 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:114 msgid "Show keyboard shortcuts list" -msgstr "" +msgstr "Показати список гарячих клавіш" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:117 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:191 +msgid "Commands" +msgstr "Команди" #: src/slic3r/GUI/KBShortcutsDialog.cpp:122 -msgid "Select multiple object/Move multiple object" -msgstr "" +msgid "Add Instance of the selected object" +msgstr "Додати екземпляр вибраного об’єкта" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:123 +msgid "Remove Instance of the selected object" +msgstr "Видалити екземпляр вибраного об’єкта" #: src/slic3r/GUI/KBShortcutsDialog.cpp:124 -msgid "Main Shortcuts" +msgid "" +"Press to select multiple objects\n" +"or move multiple objects with mouse" msgstr "" +"Натисніть, щоб вибрати кілька об'єктів\n" +"або переміщуйте кілька об’єктів за допомогою миші" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:125 +msgid "Press to activate selection rectangle" +msgstr "Натисніть, щоб активувати прямокутник виділення" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:126 +msgid "Press to activate deselection rectangle" +msgstr "Натисніть, щоб активувати прямокутник скасування вибору" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:127 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:196 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:207 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:219 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:226 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:243 +msgid "Arrow Up" +msgstr "Стрілка вгору" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:127 +msgid "Move selection 10 mm in positive Y direction" +msgstr "Перемістити виділення на 10 мм у позитивному напрямку за Y" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:128 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:197 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:208 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:220 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:227 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:244 +msgid "Arrow Down" +msgstr "Стрілка вниз" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:128 +msgid "Move selection 10 mm in negative Y direction" +msgstr "Перемістити виділення на 10 мм у негативному напрямку за Y" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:129 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:198 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:221 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:228 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:241 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:246 +msgid "Arrow Left" +msgstr "Стрілка вліво" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:129 +msgid "Move selection 10 mm in negative X direction" +msgstr "Перемістити виділення на 10 мм у негативному напрямку за X" #: src/slic3r/GUI/KBShortcutsDialog.cpp:130 -msgid "Arrange" -msgstr "Організувати" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:199 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:222 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:229 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:242 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:247 +msgid "Arrow Right" +msgstr "Стрілка вправо" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:130 +msgid "Move selection 10 mm in positive X direction" +msgstr "Перемістити виділення на 10 мм у позитивному напрямку за X" #: src/slic3r/GUI/KBShortcutsDialog.cpp:131 -msgid "Select All objects" -msgstr "" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:132 +msgid "Any arrow" +msgstr "Будь-яка стрілка" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:131 +msgid "Movement step set to 1 mm" +msgstr "Встановити крок переміщення на 1 мм" #: src/slic3r/GUI/KBShortcutsDialog.cpp:132 -msgid "Delete selected" -msgstr "" +msgid "Movement in camera space" +msgstr "Переміщення відносно камери" #: src/slic3r/GUI/KBShortcutsDialog.cpp:133 -msgid "Delete All" -msgstr "Видалити все" +msgid "Page Up" +msgstr "Попередня сторінка" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:133 +msgid "Rotate selection 45 degrees CCW" +msgstr "Повернути вибране на 45 градусів за годинниковою стрілкою" #: src/slic3r/GUI/KBShortcutsDialog.cpp:134 -msgid "Gizmo move" -msgstr "" +msgid "Page Down" +msgstr "Наступна сторінка" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:134 +msgid "Rotate selection 45 degrees CW" +msgstr "Повернути вибране на 45 градусів проти годинникової стрілки" #: src/slic3r/GUI/KBShortcutsDialog.cpp:135 -msgid "Gizmo scale" -msgstr "" +msgid "Gizmo move" +msgstr "Gizmo переміщення" #: src/slic3r/GUI/KBShortcutsDialog.cpp:136 -msgid "Gizmo rotate" -msgstr "" +msgid "Gizmo scale" +msgstr "Gizmo масштабування" #: src/slic3r/GUI/KBShortcutsDialog.cpp:137 -msgid "Gizmo cut" -msgstr "" +msgid "Gizmo rotate" +msgstr "Gizmo обертання" #: src/slic3r/GUI/KBShortcutsDialog.cpp:138 -msgid "Gizmo Place face on bed" -msgstr "" +msgid "Gizmo cut" +msgstr "Gizmo розрізання" #: src/slic3r/GUI/KBShortcutsDialog.cpp:139 -msgid "Gizmo SLA support points" -msgstr "" +msgid "Gizmo Place face on bed" +msgstr "Gizmo \"Поверхнею на стіл\"" #: src/slic3r/GUI/KBShortcutsDialog.cpp:140 -#, no-c-format -msgid "" -"Press to snap by 5% in Gizmo scale\n" -"or by 1mm in Gizmo move" -msgstr "" +msgid "Gizmo SLA hollow" +msgstr "Gizmo SLA-порожнистість" #: src/slic3r/GUI/KBShortcutsDialog.cpp:141 -msgid "" -"Press to scale or rotate selected objects\n" -"around their own center" -msgstr "" +msgid "Gizmo SLA support points" +msgstr "Gizmo точки SLA-підтримок" #: src/slic3r/GUI/KBShortcutsDialog.cpp:142 -msgid "Zoom to Bed" -msgstr "" +msgid "Unselect gizmo or clear selection" +msgstr "Скасуйте вибір gizmo або очистіть виділення" #: src/slic3r/GUI/KBShortcutsDialog.cpp:143 -msgid "Zoom to all objects in scene, if none selected" -msgstr "" +msgid "Change camera type (perspective, orthographic)" +msgstr "Зміна типу камери (перспективна, орфографічна)" #: src/slic3r/GUI/KBShortcutsDialog.cpp:144 -msgid "Zoom to selected object" -msgstr "" +msgid "Zoom to Bed" +msgstr "Приблизити до розміру столу" #: src/slic3r/GUI/KBShortcutsDialog.cpp:145 -msgid "Zoom in" +msgid "" +"Zoom to selected object\n" +"or all objects in scene, if none selected" msgstr "" +"Приблизити до розміру об'єкту\n" +"або до всіх об'єктів сцени, якщо жоден не вибрано" #: src/slic3r/GUI/KBShortcutsDialog.cpp:146 -msgid "Zoom out" -msgstr "" +msgid "Zoom in" +msgstr "Приблизити" #: src/slic3r/GUI/KBShortcutsDialog.cpp:147 -msgid "Unselect gizmo, keep object selection" -msgstr "" +msgid "Zoom out" +msgstr "Віддалити" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:148 +msgid "Switch between Editor/Preview" +msgstr "Перемикання між Редактором та Попереднім переглядом" #: src/slic3r/GUI/KBShortcutsDialog.cpp:149 -msgid "Plater Shortcuts" +msgid "Collapse/Expand the sidebar" +msgstr "Згорнути/Розгорнути бічну панель" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:152 +msgid "Show/Hide 3Dconnexion devices settings dialog, if enabled" msgstr "" +"Показати/сховати діалогове вікно налаштувань пристроїв 3Dconnexion, якщо " +"такі існують" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:164 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:175 -msgid "Arrow Up" -msgstr "" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:154 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:158 +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "Показати/сховати діалогове вікно налаштувань пристроїв 3Dconnexion" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:164 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:166 -msgid "Upper Layer" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:165 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:176 -msgid "Arrow Down" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:165 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:167 -msgid "Lower Layer" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:169 -msgid "Preview Shortcuts" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:175 -msgid "Move current slider thump Up" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:176 -msgid "Move current slider thump Down" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:177 -msgid "Arrow Left" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:177 -msgid "Set upper thumb to current slider thumb" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:178 -msgid "Arrow Right" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:178 -msgid "Set lower thumb to current slider thumb" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:179 -msgid "Add color change marker for current layer" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:180 -msgid "Delete color change marker for current layer" -msgstr "" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:182 -msgid "Layers Slider Shortcuts" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:54 -msgid "" -" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases" -msgstr " - Пам'ятайте оновлювати з http://github.com/prusa3d/slic3r/releases" - -#: src/slic3r/GUI/MainFrame.cpp:160 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:167 src/slic3r/GUI/MainFrame.cpp:331 +#: src/slic3r/GUI/MainFrame.cpp:343 msgid "Plater" msgstr "Платер" -#: src/slic3r/GUI/MainFrame.cpp:273 -msgid "&Open Project" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:170 +msgid "All gizmos: Rotate - left mouse button; Pan - right mouse button" msgstr "" +"Всі gizmos: Обертати — ліва кнопка миші; Панорамування — права кнопка миші" -#: src/slic3r/GUI/MainFrame.cpp:273 -msgid "Open a project file" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:171 +msgid "Gizmo move: Press to snap by 1mm" +msgstr "Gizmo переміщення: Натисніть, щоб зафіксувати переміщення через 1 мм" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:172 +msgid "Gizmo scale: Press to snap by 5%" +msgstr "Gizmo масштабування: Натисніть, щоб зафіксувати обертання на 5%" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:173 +msgid "Gizmo scale: Scale selection to fit print volume" +msgstr "Gizmo масштабування: Масштабуйте вибране відповідно до об'єму столу" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:174 +msgid "Gizmo scale: Press to activate one direction scaling" msgstr "" +"Gizmo масштабування: Натисніть, щоб активувати масштабування в одному " +"напрямку" -#: src/slic3r/GUI/MainFrame.cpp:275 -msgid "&Save Project" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:175 +msgid "Gizmo scale: Press to scale selected objects around their own center" msgstr "" +"Gizmo масштабування: Натисніть, щоб масштабувати вибрані об'єкти навколо їх " +"власного центру" -#: src/slic3r/GUI/MainFrame.cpp:275 -msgid "Save current project file" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:176 +msgid "Gizmo rotate: Press to rotate selected objects around their own center" msgstr "" +"Gizmo обертання: Натисніть, щоб обертати вибрані об'єкти навколо їх власного " +"центру" -#: src/slic3r/GUI/MainFrame.cpp:277 -msgid "Save Project &as" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:179 +msgid "Gizmos" +msgstr "Всі gizmos" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:179 +msgid "" +"The following shortcuts are applicable when the specified gizmo is active" +msgstr "Наступні гарячі клавіші застосовуються, коли активне вказане gizmo" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:183 src/slic3r/GUI/MainFrame.cpp:1244 +msgid "Open a G-code file" +msgstr "Відкрити файл G-кода" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:185 src/slic3r/GUI/MainFrame.cpp:1142 +#: src/slic3r/GUI/MainFrame.cpp:1146 src/slic3r/GUI/MainFrame.cpp:1249 +#: src/slic3r/GUI/MainFrame.cpp:1253 +msgid "Reload the plater from disk" +msgstr "Перезавантажити стіл з диска" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:196 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:200 +msgid "Vertical slider - Move active thumb Up" +msgstr "Вертикальний повзунок - Перемістити активний повзунок вгору" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:197 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:201 +msgid "Vertical slider - Move active thumb Down" +msgstr "Вертикальний повзунок - Перемістити активний повзунок вниз" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:198 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:202 +msgid "Horizontal slider - Move active thumb Left" +msgstr "Горизонтальний повзунок - Перемістити активний повзунок вліво" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:199 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:203 +msgid "Horizontal slider - Move active thumb Right" +msgstr "Горизонтальний повзунок - Перемістити активний повзунок вправо" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:204 +msgid "On/Off one layer mode of the vertical slider" +msgstr "Увімкнути/Вимкнути одношаровий режим вертикального повзунка" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:205 +msgid "Show/Hide Legend and Estimated printing time" +msgstr "Показати / Сховати легенду та приблизний час друку" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:207 +msgid "Upper layer" +msgstr "Верхній шар" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:208 +msgid "Lower layer" +msgstr "Нижній шар" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:209 +msgid "Upper Layer" +msgstr "Верхній шар" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:210 +msgid "Lower Layer" +msgstr "Нижній шар" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:211 +msgid "Show/Hide Legend & Estimated printing time" +msgstr "Показати / Сховати легенду та приблизний час друку" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:215 src/slic3r/GUI/Plater.cpp:4200 +#: src/slic3r/GUI/Tab.cpp:2602 +msgid "Preview" +msgstr "Попередній перегляд" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:219 +msgid "Move active thumb Up" +msgstr "Перемістити активний повзунок вгору" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:220 +msgid "Move active thumb Down" +msgstr "Перемістити активний повзунок вниз" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:221 +msgid "Set upper thumb as active" +msgstr "Встановити активним верхній повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:222 +msgid "Set lower thumb as active" +msgstr "Встановити активним нижній повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:223 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:230 +msgid "Add color change marker for current layer" +msgstr "Додати маркер зміни кольору для поточного шару" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:224 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:231 +msgid "Delete color change marker for current layer" +msgstr "Видалити маркер зміни кольору для поточного шару" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:226 +msgid "Move current slider thumb Up" +msgstr "Перемістити активний повзунок вгору" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:227 +msgid "Move current slider thumb Down" +msgstr "Перемістити активний повзунок вниз" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:228 +msgid "Set upper thumb to current slider thumb" +msgstr "Встановити верхній повзунок на поточну позицію" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:229 +msgid "Set lower thumb to current slider thumb" +msgstr "Встановити нижній повзунок на поточну позицію" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:233 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:234 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:249 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:250 +msgid "" +"Press to speed up 5 times while moving thumb\n" +"with arrow keys or mouse wheel" msgstr "" +"Натисніть, щоб мати 5-кратне прискорення під час руху повзунка\n" +"за допомогою клавіш зі стрілками або колеса миші" -#: src/slic3r/GUI/MainFrame.cpp:277 -msgid "Save current project file as" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:237 +msgid "Vertical Slider" +msgstr "Вертикальний повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:237 +msgid "" +"The following shortcuts are applicable in G-code preview when the vertical " +"slider is active" msgstr "" +"Наведені нижче гарячі клавіші застосовуються у перегляді G-коду, коли " +"вертикальний повзунок активний" -#: src/slic3r/GUI/MainFrame.cpp:283 -msgid "Import STL/OBJ/AM&F/3MF" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:241 +msgid "Move active thumb Left" +msgstr "Перемістити активний повзунок вліво" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:242 +msgid "Move active thumb Right" +msgstr "Перемістити активний повзунок вправо" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:243 +msgid "Set left thumb as active" +msgstr "Встановити активним лівий повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:244 +msgid "Set right thumb as active" +msgstr "Встановити активним правий повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:246 +msgid "Move active slider thumb Left" +msgstr "Перемістити активний повзунок вліво" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:247 +msgid "Move active slider thumb Right" +msgstr "Перемістити активний повзунок вправо" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:253 +msgid "Horizontal Slider" +msgstr "Горизонтальний повзунок" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:253 +msgid "" +"The following shortcuts are applicable in G-code preview when the horizontal " +"slider is active" msgstr "" +"Наведені нижче гарячі клавіші застосовуються у перегляді G-коду, коли " +"горизонтальний повзунок активний" -#: src/slic3r/GUI/MainFrame.cpp:283 -msgid "Load a model" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:276 +msgid "Keyboard shortcuts" +msgstr "Гарячі клавіши" + +#: src/slic3r/GUI/MainFrame.cpp:65 src/slic3r/GUI/MainFrame.cpp:79 +#: src/slic3r/GUI/MainFrame.cpp:1191 +msgid "Open a new PrusaSlicer instance" +msgstr "Відкрити новий екземпляр PrusaSlicer" + +#: src/slic3r/GUI/MainFrame.cpp:68 src/slic3r/GUI/MainFrame.cpp:81 +msgid "G-code preview" +msgstr "Перегляд G-коду" + +#: src/slic3r/GUI/MainFrame.cpp:68 src/slic3r/GUI/MainFrame.cpp:1091 +msgid "Open G-code viewer" +msgstr "Відкрити переглядач G-коду" + +#: src/slic3r/GUI/MainFrame.cpp:79 src/slic3r/GUI/MainFrame.cpp:1260 +msgid "Open PrusaSlicer" +msgstr "Відкрити PrusaSlicer" + +#: src/slic3r/GUI/MainFrame.cpp:81 +msgid "Open new G-code viewer" +msgstr "Відкрити новий переглядач G-коду" + +#: src/slic3r/GUI/MainFrame.cpp:153 +msgid "" +"Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/" +"releases" msgstr "" +"Не забудьте перевірити наявність оновлень на https://github.com/prusa3d/" +"PrusaSlicer/releases" -#: src/slic3r/GUI/MainFrame.cpp:286 -msgid "Import &Config" -msgstr "" +#: src/slic3r/GUI/MainFrame.cpp:510 +msgid "based on Slic3r" +msgstr "на основі Slic3r" -#: src/slic3r/GUI/MainFrame.cpp:286 -msgid "Load exported configuration file" -msgstr "Завантажити експортований файл конфігурації" - -#: src/slic3r/GUI/MainFrame.cpp:288 -msgid "Import Config from &project" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:288 -msgid "Load configuration from project file" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:291 -msgid "Import Config &Bundle" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:291 -msgid "Load presets from a bundle" -msgstr "Завантажити налаштування з пакету" - -#: src/slic3r/GUI/MainFrame.cpp:293 -msgid "&Import" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:296 -msgid "Export &G-code" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:296 -msgid "Export current plate as G-code" -msgstr "Експорт поточної пластини як G-код" - -#: src/slic3r/GUI/MainFrame.cpp:299 -msgid "Export plate as &STL" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:299 -msgid "Export current plate as STL" -msgstr "Експорт поточної пластини як STL" - -#: src/slic3r/GUI/MainFrame.cpp:301 -msgid "Export plate as &AMF" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:301 -msgid "Export current plate as AMF" -msgstr "Експорт поточної пластини як AMF" - -#: src/slic3r/GUI/MainFrame.cpp:304 -msgid "Export &Config" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:304 -msgid "Export current configuration to file" -msgstr "Експортувати поточну конфігурацію в файл" - -#: src/slic3r/GUI/MainFrame.cpp:306 -msgid "Export Config &Bundle" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:306 -msgid "Export all presets to file" -msgstr "Експортувати всі налаштування у файл" - -#: src/slic3r/GUI/MainFrame.cpp:308 -msgid "&Export" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:314 -msgid "Quick Slice" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:314 -msgid "Slice a file into a G-code" -msgstr "Нарізати файл у G-код" - -#: src/slic3r/GUI/MainFrame.cpp:320 -msgid "Quick Slice and Save As" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:320 -msgid "Slice a file into a G-code, save as" -msgstr "Нарізати файл у G-код, зберегти як" - -#: src/slic3r/GUI/MainFrame.cpp:326 -msgid "Repeat Last Quick Slice" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:334 -msgid "(Re)Slice &Now" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:334 -msgid "Start new slicing process" -msgstr "Почати новий процес нарізання" - -#: src/slic3r/GUI/MainFrame.cpp:337 -msgid "&Repair STL file" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:337 -msgid "Automatically repair an STL file" -msgstr "Автоматично відновити як STL-файл" - -#: src/slic3r/GUI/MainFrame.cpp:340 -msgid "&Quit" -msgstr "Вихід" - -#: src/slic3r/GUI/MainFrame.cpp:340 -msgid "Quit Slic3r" -msgstr "Вийти зі Slic3r" - -#: src/slic3r/GUI/MainFrame.cpp:374 -msgid "&Select all" -msgstr "Вибрати все" - -#: src/slic3r/GUI/MainFrame.cpp:374 -msgid "Selects all objects" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:377 -msgid "&Delete selected" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:377 -msgid "Deletes the current selection" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:379 -msgid "Delete &all" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:379 -msgid "Deletes all objects" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:392 -msgid "&Plater Tab" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:392 -msgid "Show the plater" -msgstr "Показати plater" - -#: src/slic3r/GUI/MainFrame.cpp:399 -msgid "P&rint Settings Tab" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:399 -msgid "Show the print settings" -msgstr "Показати параметри друку" - -#: src/slic3r/GUI/MainFrame.cpp:401 -msgid "&Filament Settings Tab" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:401 -msgid "Show the filament settings" -msgstr "Показати параметри філаменту" - -#: src/slic3r/GUI/MainFrame.cpp:403 -msgid "Print&er Settings Tab" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:403 -msgid "Show the printer settings" -msgstr "Показати параметри принтеру" - -#: src/slic3r/GUI/MainFrame.cpp:407 -msgid "3&D" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:407 -msgid "Show the 3D editing view" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:409 -msgid "Pre&view" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:409 -msgid "Show the 3D slices preview" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:430 -msgid "Print &Host Upload Queue" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:430 -msgid "Display the Print Host Upload Queue window" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:439 -msgid "Iso" -msgstr "Iso" - -#: src/slic3r/GUI/MainFrame.cpp:439 -msgid "Iso View" -msgstr "Вид Iso" - -#: src/slic3r/GUI/MainFrame.cpp:441 -msgid "Top" -msgstr "Зверху" - -#: src/libslic3r/PrintConfig.cpp:2041 -msgctxt "Layers" -msgid "Top" -msgstr "Верхні" - -#: src/slic3r/GUI/MainFrame.cpp:441 -msgid "Top View" -msgstr "Вид зверху" - -#: src/slic3r/GUI/MainFrame.cpp:442 -msgid "Bottom" -msgstr "Знизу" - -#: src/libslic3r/PrintConfig.cpp:148 -msgctxt "Layers" -msgid "Bottom" -msgstr "Нижні" - -#: src/slic3r/GUI/MainFrame.cpp:442 -msgid "Bottom View" -msgstr "Вид знизу" - -#: src/slic3r/GUI/MainFrame.cpp:443 -msgid "Front" -msgstr "Спереду" - -#: src/slic3r/GUI/MainFrame.cpp:443 -msgid "Front View" -msgstr "Вид спереду" - -#: src/slic3r/GUI/MainFrame.cpp:444 src/libslic3r/PrintConfig.cpp:1561 -msgid "Rear" -msgstr "Ззаду" - -#: src/slic3r/GUI/MainFrame.cpp:444 -msgid "Rear View" -msgstr "Вид ззаду" - -#: src/slic3r/GUI/MainFrame.cpp:445 -msgid "Left" -msgstr "З лівого боку" - -#: src/slic3r/GUI/MainFrame.cpp:445 -msgid "Left View" -msgstr "Вид з лівого боку" - -#: src/slic3r/GUI/MainFrame.cpp:446 -msgid "Right" -msgstr "З правого боку" - -#: src/slic3r/GUI/MainFrame.cpp:446 -msgid "Right View" -msgstr "Вид з правого боку" - -#: src/slic3r/GUI/MainFrame.cpp:460 +#: src/slic3r/GUI/MainFrame.cpp:866 msgid "Prusa 3D &Drivers" -msgstr "" +msgstr "Драйвери Prusa3D" -#: src/slic3r/GUI/MainFrame.cpp:460 +#: src/slic3r/GUI/MainFrame.cpp:866 msgid "Open the Prusa3D drivers download page in your browser" msgstr "Відкрити сторінку завантаження драйверів Prusa3D у своєму браузері" -#: src/slic3r/GUI/MainFrame.cpp:462 -msgid "Prusa Edition &Releases" -msgstr "" +#: src/slic3r/GUI/MainFrame.cpp:868 +msgid "Software &Releases" +msgstr "Релізи ПЗ" -#: src/slic3r/GUI/MainFrame.cpp:462 -msgid "Open the Prusa Edition releases page in your browser" -msgstr "Відкрити сторінку релізів Prusa Edition у своєму браузері" +#: src/slic3r/GUI/MainFrame.cpp:868 +msgid "Open the software releases page in your browser" +msgstr "Відкрити сторінку релізів PrusaEdition у своєму браузері" -#: src/slic3r/GUI/MainFrame.cpp:468 -msgid "Slic3r &Website" -msgstr "Веб-сайт Slic3r" +#: src/slic3r/GUI/MainFrame.cpp:874 +#, c-format +msgid "%s &Website" +msgstr "Веб-сайт %s" -#: src/slic3r/GUI/MainFrame.cpp:468 -msgid "Open the Slic3r website in your browser" -msgstr "Відкрити сторінку Slic3r у своєму браузері" +#: src/slic3r/GUI/MainFrame.cpp:875 +#, c-format +msgid "Open the %s website in your browser" +msgstr "Відкрити сторінку %s у своєму браузері" -#: src/slic3r/GUI/MainFrame.cpp:470 -msgid "Slic3r &Manual" -msgstr "Посібник до Slic3r" - -#: src/slic3r/GUI/MainFrame.cpp:470 -msgid "Open the Slic3r manual in your browser" -msgstr "Відкрити сторінку посібнику до Slic3r у своєму браузері" - -#: src/slic3r/GUI/MainFrame.cpp:473 +#: src/slic3r/GUI/MainFrame.cpp:881 msgid "System &Info" -msgstr "" +msgstr "Інформація про систему" -#: src/slic3r/GUI/MainFrame.cpp:473 +#: src/slic3r/GUI/MainFrame.cpp:881 msgid "Show system information" msgstr "Показати інформацію про систему" -#: src/slic3r/GUI/MainFrame.cpp:475 +#: src/slic3r/GUI/MainFrame.cpp:883 msgid "Show &Configuration Folder" -msgstr "" +msgstr "Показати папку конфігурації" -#: src/slic3r/GUI/MainFrame.cpp:475 +#: src/slic3r/GUI/MainFrame.cpp:883 msgid "Show user configuration folder (datadir)" -msgstr "" +msgstr "Показати папку користувацької конфігурації (datadir)" -#: src/slic3r/GUI/MainFrame.cpp:477 +#: src/slic3r/GUI/MainFrame.cpp:885 msgid "Report an I&ssue" -msgstr "" +msgstr "Повідомити про проблему" -#: src/slic3r/GUI/MainFrame.cpp:477 -msgid "Report an issue on the Slic3r Prusa Edition" -msgstr "Повідомити про проблему на Slic3r Prusa Edition" +#: src/slic3r/GUI/MainFrame.cpp:885 +#, c-format +msgid "Report an issue on %s" +msgstr "Повідомити про проблему на %s" -#: src/slic3r/GUI/MainFrame.cpp:479 -msgid "&About Slic3r" -msgstr "&Про Slic3r" +#: src/slic3r/GUI/MainFrame.cpp:888 src/slic3r/GUI/MainFrame.cpp:891 +#, c-format +msgid "&About %s" +msgstr "О %s" -#: src/slic3r/GUI/MainFrame.cpp:479 +#: src/slic3r/GUI/MainFrame.cpp:888 src/slic3r/GUI/MainFrame.cpp:891 msgid "Show about dialog" msgstr "Показати діалог Про Slic3r" -#: src/slic3r/GUI/MainFrame.cpp:482 -msgid "Keyboard Shortcuts" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:482 +#: src/slic3r/GUI/MainFrame.cpp:894 msgid "Show the list of the keyboard shortcuts" +msgstr "Показати список гарячих клавіш" + +#: src/slic3r/GUI/MainFrame.cpp:908 +msgid "Iso" +msgstr "Iso" + +#: src/slic3r/GUI/MainFrame.cpp:908 +msgid "Iso View" +msgstr "Вид Iso" + +#. TRN To be shown in the main menu View->Top +#. TRN To be shown in Print Settings "Top solid layers" +#: src/slic3r/GUI/MainFrame.cpp:912 src/libslic3r/PrintConfig.cpp:2360 +#: src/libslic3r/PrintConfig.cpp:2369 +msgid "Top" +msgstr "Зверху" + +#: src/slic3r/GUI/MainFrame.cpp:912 +msgid "Top View" +msgstr "Вид зверху" + +#. TRN To be shown in the main menu View->Bottom +#. TRN To be shown in Print Settings "Bottom solid layers" +#. TRN To be shown in Print Settings "Top solid layers" +#: src/slic3r/GUI/MainFrame.cpp:915 src/libslic3r/PrintConfig.cpp:230 +#: src/libslic3r/PrintConfig.cpp:239 +msgid "Bottom" +msgstr "Знизу" + +#: src/slic3r/GUI/MainFrame.cpp:915 +msgid "Bottom View" +msgstr "Вид знизу" + +#: src/slic3r/GUI/MainFrame.cpp:917 +msgid "Front" +msgstr "Спереду" + +#: src/slic3r/GUI/MainFrame.cpp:917 +msgid "Front View" +msgstr "Вид спереду" + +#: src/slic3r/GUI/MainFrame.cpp:919 src/libslic3r/PrintConfig.cpp:1845 +msgid "Rear" +msgstr "Ззаду" + +#: src/slic3r/GUI/MainFrame.cpp:919 +msgid "Rear View" +msgstr "Вид ззаду" + +#: src/slic3r/GUI/MainFrame.cpp:921 +msgid "Left" +msgstr "З лівого боку" + +#: src/slic3r/GUI/MainFrame.cpp:921 +msgid "Left View" +msgstr "Вид з лівого боку" + +#: src/slic3r/GUI/MainFrame.cpp:923 +msgid "Right" +msgstr "З правого боку" + +#: src/slic3r/GUI/MainFrame.cpp:923 +msgid "Right View" +msgstr "Вид з правого боку" + +#: src/slic3r/GUI/MainFrame.cpp:936 +msgid "&New Project" +msgstr "Новий проект" + +#: src/slic3r/GUI/MainFrame.cpp:936 +msgid "Start a new project" +msgstr "Почати новий проект" + +#: src/slic3r/GUI/MainFrame.cpp:939 +msgid "&Open Project" +msgstr "Відкрити проект" + +#: src/slic3r/GUI/MainFrame.cpp:939 +msgid "Open a project file" +msgstr "Відкрити файл проекту" + +#: src/slic3r/GUI/MainFrame.cpp:944 +msgid "Recent projects" +msgstr "Останні проекти" + +#: src/slic3r/GUI/MainFrame.cpp:953 +msgid "" +"The selected project is no longer available.\n" +"Do you want to remove it from the recent projects list?" msgstr "" +"Вибраний проект більше не доступний.\n" +"Видалити його зі списку останніх проектів?" -#: src/slic3r/GUI/MainFrame.cpp:490 -msgid "&File" -msgstr "Файл" - -#: src/slic3r/GUI/MainFrame.cpp:491 -msgid "&Edit" -msgstr "" - -#: src/slic3r/GUI/MainFrame.cpp:492 -msgid "&Window" -msgstr "Вікно" - -#: src/slic3r/GUI/MainFrame.cpp:493 -msgid "&View" -msgstr "Вид" - -#: src/slic3r/GUI/MainFrame.cpp:496 -msgid "&Help" -msgstr "Допомога" - -#: src/slic3r/GUI/MainFrame.cpp:524 -msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Вибрати файл для нарізання (STL/OBJ/AMF/3MF/PRUSA):" - -#: src/slic3r/GUI/MainFrame.cpp:538 -msgid "No previously sliced file." -msgstr "Немає попередньо нарізаного файлу." - -#: src/slic3r/GUI/MainFrame.cpp:539 src/slic3r/GUI/PrintHostDialogs.cpp:219 +#: src/slic3r/GUI/MainFrame.cpp:953 src/slic3r/GUI/MainFrame.cpp:1343 +#: src/slic3r/GUI/PrintHostDialogs.cpp:263 msgid "Error" msgstr "Помилка" -#: src/slic3r/GUI/MainFrame.cpp:544 +#: src/slic3r/GUI/MainFrame.cpp:978 +msgid "&Save Project" +msgstr "Зберегти проект" + +#: src/slic3r/GUI/MainFrame.cpp:978 +msgid "Save current project file" +msgstr "Зберегти файл поточного проекту" + +#: src/slic3r/GUI/MainFrame.cpp:982 src/slic3r/GUI/MainFrame.cpp:984 +msgid "Save Project &as" +msgstr "Зберегти проект як" + +#: src/slic3r/GUI/MainFrame.cpp:982 src/slic3r/GUI/MainFrame.cpp:984 +msgid "Save current project file as" +msgstr "Зберегти файл поточного проекту як" + +#: src/slic3r/GUI/MainFrame.cpp:992 +msgid "Import STL/OBJ/AM&F/3MF" +msgstr "Імпорт STL/OBJ/AMF/3MF" + +#: src/slic3r/GUI/MainFrame.cpp:992 +msgid "Load a model" +msgstr "Завантажити модель" + +#: src/slic3r/GUI/MainFrame.cpp:996 +msgid "Import STL (imperial units)" +msgstr "Імпорт SТL (в імперських одиницях)" + +#: src/slic3r/GUI/MainFrame.cpp:996 +msgid "Load an model saved with imperial units" +msgstr "Завантажити модель, збережену в імперських одиницях" + +#: src/slic3r/GUI/MainFrame.cpp:1000 +msgid "Import SL1 archive" +msgstr "Імпорт SL1-архіву" + +#: src/slic3r/GUI/MainFrame.cpp:1000 +msgid "Load an SL1 archive" +msgstr "Завантажити SL1-архів" + +#: src/slic3r/GUI/MainFrame.cpp:1005 +msgid "Import &Config" +msgstr "Імпорт конфігурації" + +#: src/slic3r/GUI/MainFrame.cpp:1005 +msgid "Load exported configuration file" +msgstr "Завантажити експортований файл конфігурації" + +#: src/slic3r/GUI/MainFrame.cpp:1008 +msgid "Import Config from &project" +msgstr "Імпорт конфігурації з проекту" + +#: src/slic3r/GUI/MainFrame.cpp:1008 +msgid "Load configuration from project file" +msgstr "Завантажити конфігурацію з файлу проекту" + +#: src/slic3r/GUI/MainFrame.cpp:1012 +msgid "Import Config &Bundle" +msgstr "Імпорт пакету конфігурацій" + +#: src/slic3r/GUI/MainFrame.cpp:1012 +msgid "Load presets from a bundle" +msgstr "Завантажити налаштування з пакету" + +#: src/slic3r/GUI/MainFrame.cpp:1015 +msgid "&Import" +msgstr "Імпорт" + +#: src/slic3r/GUI/MainFrame.cpp:1018 src/slic3r/GUI/MainFrame.cpp:1305 +msgid "Export &G-code" +msgstr "Експортувати G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1018 +msgid "Export current plate as G-code" +msgstr "Експорт поточної пластини як G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1022 src/slic3r/GUI/MainFrame.cpp:1306 +msgid "S&end G-code" +msgstr "Надіслати G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1022 +msgid "Send to print current plate as G-code" +msgstr "Надіслати на принтер поточний стіл як G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1026 +msgid "Export G-code to SD card / Flash drive" +msgstr "Експорт G-коду на SD-карту / Флешку" + +#: src/slic3r/GUI/MainFrame.cpp:1026 +msgid "Export current plate as G-code to SD card / Flash drive" +msgstr "Експорт поточного столу як G-код на SD-карту / Флешку" + +#: src/slic3r/GUI/MainFrame.cpp:1030 +msgid "Export plate as &STL" +msgstr "Експорт столу як STL" + +#: src/slic3r/GUI/MainFrame.cpp:1030 +msgid "Export current plate as STL" +msgstr "Експорт поточної пластини як STL" + +#: src/slic3r/GUI/MainFrame.cpp:1033 +msgid "Export plate as STL &including supports" +msgstr "Експорт столу як STL, включаючи підтримку" + +#: src/slic3r/GUI/MainFrame.cpp:1033 +msgid "Export current plate as STL including supports" +msgstr "Експорт поточного столу як STL, включаючи підтримку" + +#: src/slic3r/GUI/MainFrame.cpp:1036 +msgid "Export plate as &AMF" +msgstr "Експорт столу як AMF" + +#: src/slic3r/GUI/MainFrame.cpp:1036 +msgid "Export current plate as AMF" +msgstr "Експорт поточної пластини як AMF" + +#: src/slic3r/GUI/MainFrame.cpp:1040 src/slic3r/GUI/MainFrame.cpp:1257 +msgid "Export &toolpaths as OBJ" +msgstr "Експорт шляхів інструментів як OBJ" + +#: src/slic3r/GUI/MainFrame.cpp:1040 src/slic3r/GUI/MainFrame.cpp:1257 +msgid "Export toolpaths as OBJ" +msgstr "Експорт шляхів інструментів як OBJ" + +#: src/slic3r/GUI/MainFrame.cpp:1044 +msgid "Export &Config" +msgstr "Експортувати конфігурацію" + +#: src/slic3r/GUI/MainFrame.cpp:1044 +msgid "Export current configuration to file" +msgstr "Експортувати поточну конфігурацію в файл" + +#: src/slic3r/GUI/MainFrame.cpp:1047 +msgid "Export Config &Bundle" +msgstr "Експортувати пакет конфігурації" + +#: src/slic3r/GUI/MainFrame.cpp:1047 +msgid "Export all presets to file" +msgstr "Експортувати всі налаштування у файл" + +#: src/slic3r/GUI/MainFrame.cpp:1050 +msgid "Export Config Bundle With Physical Printers" +msgstr "Експортувати пакет конфігурації, включаючи фізичні принтери" + +#: src/slic3r/GUI/MainFrame.cpp:1050 +msgid "Export all presets including physical printers to file" +msgstr "Експортуйте всі пресети, включаючи фізичні принтери, у файл" + +#: src/slic3r/GUI/MainFrame.cpp:1053 +msgid "&Export" +msgstr "Експорт" + +#: src/slic3r/GUI/MainFrame.cpp:1055 +msgid "Ejec&t SD card / Flash drive" +msgstr "Від'єднати SD-карту/флешку" + +#: src/slic3r/GUI/MainFrame.cpp:1055 +msgid "Eject SD card / Flash drive after the G-code was exported to it." +msgstr "" +"Від'єднати SD-карту / Флешку після того, як на неї був експортований G-код." + +#: src/slic3r/GUI/MainFrame.cpp:1063 +msgid "Quick Slice" +msgstr "Швидке нарізання" + +#: src/slic3r/GUI/MainFrame.cpp:1063 +msgid "Slice a file into a G-code" +msgstr "Нарізати файл у G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1069 +msgid "Quick Slice and Save As" +msgstr "Швидко нарізати та зберегти як" + +#: src/slic3r/GUI/MainFrame.cpp:1069 +msgid "Slice a file into a G-code, save as" +msgstr "Нарізати файл у G-код, зберегти як" + +#: src/slic3r/GUI/MainFrame.cpp:1075 +msgid "Repeat Last Quick Slice" +msgstr "Повторити останнє швидке нарізання" + +#: src/slic3r/GUI/MainFrame.cpp:1075 +msgid "Repeat last quick slice" +msgstr "Повторити останнє швидке нарізання" + +#: src/slic3r/GUI/MainFrame.cpp:1083 +msgid "(Re)Slice No&w" +msgstr "(Пере)Нарізати зараз" + +#: src/slic3r/GUI/MainFrame.cpp:1083 +msgid "Start new slicing process" +msgstr "Почати новий процес нарізання" + +#: src/slic3r/GUI/MainFrame.cpp:1087 +msgid "&Repair STL file" +msgstr "Відновити STL-файл" + +#: src/slic3r/GUI/MainFrame.cpp:1087 +msgid "Automatically repair an STL file" +msgstr "Автоматично відновити як STL-файл" + +#: src/slic3r/GUI/MainFrame.cpp:1091 +msgid "&G-code preview" +msgstr "Перегляд G-коду" + +#: src/slic3r/GUI/MainFrame.cpp:1094 src/slic3r/GUI/MainFrame.cpp:1264 +msgid "&Quit" +msgstr "Вихід" + +#: src/slic3r/GUI/MainFrame.cpp:1094 src/slic3r/GUI/MainFrame.cpp:1264 +#, c-format +msgid "Quit %s" +msgstr "Вийти з %s" + +#: src/slic3r/GUI/MainFrame.cpp:1109 +msgid "&Select all" +msgstr "Вибрати все" + +#: src/slic3r/GUI/MainFrame.cpp:1110 +msgid "Selects all objects" +msgstr "Видалити всі об'єкти" + +#: src/slic3r/GUI/MainFrame.cpp:1112 +msgid "D&eselect all" +msgstr "Скасувати вибір усіх" + +#: src/slic3r/GUI/MainFrame.cpp:1113 +msgid "Deselects all objects" +msgstr "Скасовує вибір усіх об’єктів" + +#: src/slic3r/GUI/MainFrame.cpp:1116 +msgid "&Delete selected" +msgstr "Видалити вибране" + +#: src/slic3r/GUI/MainFrame.cpp:1117 +msgid "Deletes the current selection" +msgstr "Видаляє поточний вибір" + +#: src/slic3r/GUI/MainFrame.cpp:1119 +msgid "Delete &all" +msgstr "Видалити все" + +#: src/slic3r/GUI/MainFrame.cpp:1120 +msgid "Deletes all objects" +msgstr "Видалити всі об'єкти" + +#: src/slic3r/GUI/MainFrame.cpp:1124 +msgid "&Undo" +msgstr "Відмінити" + +#: src/slic3r/GUI/MainFrame.cpp:1127 +msgid "&Redo" +msgstr "Повторити" + +#: src/slic3r/GUI/MainFrame.cpp:1132 +msgid "&Copy" +msgstr "Копіювати" + +#: src/slic3r/GUI/MainFrame.cpp:1133 +msgid "Copy selection to clipboard" +msgstr "Скопіювати вибране в буфер обміну" + +#: src/slic3r/GUI/MainFrame.cpp:1135 +msgid "&Paste" +msgstr "Вставити" + +#: src/slic3r/GUI/MainFrame.cpp:1136 +msgid "Paste clipboard" +msgstr "Вставити буфер обміну" + +#: src/slic3r/GUI/MainFrame.cpp:1141 src/slic3r/GUI/MainFrame.cpp:1145 +#: src/slic3r/GUI/MainFrame.cpp:1248 src/slic3r/GUI/MainFrame.cpp:1252 +msgid "Re&load from disk" +msgstr "Перезавантажити з диска" + +#: src/slic3r/GUI/MainFrame.cpp:1151 +msgid "Searc&h" +msgstr "Пошук" + +#: src/slic3r/GUI/MainFrame.cpp:1152 +msgid "Search in settings" +msgstr "Шукайте в налаштуваннях" + +#: src/slic3r/GUI/MainFrame.cpp:1160 +msgid "&Plater Tab" +msgstr "Вкладка Платер" + +#: src/slic3r/GUI/MainFrame.cpp:1160 +msgid "Show the plater" +msgstr "Показати plater" + +#: src/slic3r/GUI/MainFrame.cpp:1165 +msgid "P&rint Settings Tab" +msgstr "Вкладка параметрів друку" + +#: src/slic3r/GUI/MainFrame.cpp:1165 +msgid "Show the print settings" +msgstr "Показати параметри друку" + +#: src/slic3r/GUI/MainFrame.cpp:1168 src/slic3r/GUI/MainFrame.cpp:1308 +msgid "&Filament Settings Tab" +msgstr "Вкладка параметрів філаменту" + +#: src/slic3r/GUI/MainFrame.cpp:1168 +msgid "Show the filament settings" +msgstr "Показати параметри філаменту" + +#: src/slic3r/GUI/MainFrame.cpp:1172 +msgid "Print&er Settings Tab" +msgstr "Вкладка параметрів принтеру" + +#: src/slic3r/GUI/MainFrame.cpp:1172 +msgid "Show the printer settings" +msgstr "Показати параметри принтеру" + +#: src/slic3r/GUI/MainFrame.cpp:1178 +msgid "3&D" +msgstr "3&D" + +#: src/slic3r/GUI/MainFrame.cpp:1178 +msgid "Show the 3D editing view" +msgstr "Показати режим 3D-редагування" + +#: src/slic3r/GUI/MainFrame.cpp:1181 +msgid "Pre&view" +msgstr "Попередній перегляд" + +#: src/slic3r/GUI/MainFrame.cpp:1181 +msgid "Show the 3D slices preview" +msgstr "Показати попередній перегляд 3D нарізки" + +#: src/slic3r/GUI/MainFrame.cpp:1187 +msgid "Print &Host Upload Queue" +msgstr "Черга завантаження хоста друку" + +#: src/slic3r/GUI/MainFrame.cpp:1187 +msgid "Display the Print Host Upload Queue window" +msgstr "Показати вікна черги завантаження хоста друку" + +#: src/slic3r/GUI/MainFrame.cpp:1201 +msgid "Show &labels" +msgstr "Показувати мітки" + +#: src/slic3r/GUI/MainFrame.cpp:1201 +msgid "Show object/instance labels in 3D scene" +msgstr "Показувати мітки об’єктів/екземплярів у 3D-сцені" + +#: src/slic3r/GUI/MainFrame.cpp:1204 +msgid "&Collapse sidebar" +msgstr "Згорнути бічну панель" + +#: src/slic3r/GUI/MainFrame.cpp:1204 src/slic3r/GUI/Plater.cpp:2247 +msgid "Collapse sidebar" +msgstr "Згорнути бічну панель" + +#: src/slic3r/GUI/MainFrame.cpp:1216 src/slic3r/GUI/MainFrame.cpp:1279 +msgid "&File" +msgstr "Файл" + +#: src/slic3r/GUI/MainFrame.cpp:1217 +msgid "&Edit" +msgstr "&Редагування" + +#: src/slic3r/GUI/MainFrame.cpp:1218 +msgid "&Window" +msgstr "Вікно" + +#: src/slic3r/GUI/MainFrame.cpp:1219 src/slic3r/GUI/MainFrame.cpp:1280 +msgid "&View" +msgstr "Вид" + +#: src/slic3r/GUI/MainFrame.cpp:1222 src/slic3r/GUI/MainFrame.cpp:1283 +msgid "&Help" +msgstr "Допомога" + +#: src/slic3r/GUI/MainFrame.cpp:1244 +msgid "&Open G-code" +msgstr "Відкрити G-код" + +#: src/slic3r/GUI/MainFrame.cpp:1260 +msgid "Open &PrusaSlicer" +msgstr "Відкрити PrusaSlicer" + +#: src/slic3r/GUI/MainFrame.cpp:1305 +msgid "E&xport" +msgstr "Експорт" + +#: src/slic3r/GUI/MainFrame.cpp:1306 +msgid "S&end to print" +msgstr "Надіслати на принтер" + +#: src/slic3r/GUI/MainFrame.cpp:1308 +msgid "Mate&rial Settings Tab" +msgstr "Вкладка параметрів матеріалу" + +#: src/slic3r/GUI/MainFrame.cpp:1331 +msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "Вибрати файл для нарізання (STL/OBJ/AMF/3MF/PRUSA):" + +#: src/slic3r/GUI/MainFrame.cpp:1342 +msgid "No previously sliced file." +msgstr "Немає попередньо нарізаного файлу." + +#: src/slic3r/GUI/MainFrame.cpp:1348 msgid "Previously sliced file (" msgstr "Попередньо нарізаний файл (" -#: src/slic3r/GUI/MainFrame.cpp:544 +#: src/slic3r/GUI/MainFrame.cpp:1348 msgid ") not found." msgstr ") не знайдено." -#: src/slic3r/GUI/MainFrame.cpp:545 +#: src/slic3r/GUI/MainFrame.cpp:1349 msgid "File Not Found" msgstr "Файл не знайдено" -#: src/slic3r/GUI/MainFrame.cpp:580 src/slic3r/GUI/Tab.cpp:3152 -msgid "Save " -msgstr "Зберегти " +#: src/slic3r/GUI/MainFrame.cpp:1384 +#, c-format +msgid "Save %s file as:" +msgstr "Зберегти файл %s як:" -#: src/slic3r/GUI/MainFrame.cpp:580 +#: src/slic3r/GUI/MainFrame.cpp:1384 msgid "SVG" -msgstr "" +msgstr "SVG" -#: src/slic3r/GUI/MainFrame.cpp:580 +#: src/slic3r/GUI/MainFrame.cpp:1384 msgid "G-code" msgstr "G-код" -#: src/slic3r/GUI/MainFrame.cpp:580 -msgid " file as:" -msgstr " файл як:" - -#: src/slic3r/GUI/MainFrame.cpp:595 +#: src/slic3r/GUI/MainFrame.cpp:1396 msgid "Save zip file as:" -msgstr "" +msgstr "Зберегти zip-файл як:" -#: src/slic3r/GUI/MainFrame.cpp:607 src/slic3r/GUI/Plater.cpp:2352 -#: src/slic3r/GUI/Plater.cpp:3467 src/slic3r/GUI/Tab.cpp:1110 -#: src/slic3r/GUI/Tab.cpp:3348 +#: src/slic3r/GUI/MainFrame.cpp:1405 src/slic3r/GUI/Plater.cpp:3009 +#: src/slic3r/GUI/Plater.cpp:5581 src/slic3r/GUI/Tab.cpp:1575 +#: src/slic3r/GUI/Tab.cpp:4115 msgid "Slicing" -msgstr "" +msgstr "Нарізання" -#: src/slic3r/GUI/MainFrame.cpp:607 -msgid "Processing " -msgstr "Обробка " +#. TRN "Processing input_file_basename" +#: src/slic3r/GUI/MainFrame.cpp:1407 +#, c-format +msgid "Processing %s" +msgstr "Обробка %s" -#: src/slic3r/GUI/MainFrame.cpp:630 -msgid " was successfully sliced." -msgstr " був успішно нарізаний." +#: src/slic3r/GUI/MainFrame.cpp:1430 +msgid "%1% was successfully sliced." +msgstr "%1% був успішно нарізаний." -#: src/slic3r/GUI/MainFrame.cpp:632 +#: src/slic3r/GUI/MainFrame.cpp:1432 msgid "Slicing Done!" msgstr "Нарізання завершено!" -#: src/slic3r/GUI/MainFrame.cpp:647 +#: src/slic3r/GUI/MainFrame.cpp:1447 msgid "Select the STL file to repair:" msgstr "Вибрати STL-файл для відновлення:" -#: src/slic3r/GUI/MainFrame.cpp:661 +#: src/slic3r/GUI/MainFrame.cpp:1457 msgid "Save OBJ file (less prone to coordinate errors than STL) as:" msgstr "Зберегти OBJ-файл (менш схильний координувати помилки, ніж STL) як:" -#: src/slic3r/GUI/MainFrame.cpp:676 +#: src/slic3r/GUI/MainFrame.cpp:1469 msgid "Your file was repaired." msgstr "Ваш файл було відновлено." -#: src/slic3r/GUI/MainFrame.cpp:676 src/libslic3r/PrintConfig.cpp:3051 +#: src/slic3r/GUI/MainFrame.cpp:1469 src/libslic3r/PrintConfig.cpp:3735 msgid "Repair" msgstr "Відновити" -#: src/slic3r/GUI/MainFrame.cpp:690 +#: src/slic3r/GUI/MainFrame.cpp:1483 msgid "Save configuration as:" msgstr "Зберегти конфігурацію як:" -#: src/slic3r/GUI/MainFrame.cpp:710 src/slic3r/GUI/MainFrame.cpp:774 +#: src/slic3r/GUI/MainFrame.cpp:1502 src/slic3r/GUI/MainFrame.cpp:1564 msgid "Select configuration to load:" msgstr "Вибрати конфігурацію для завантаження:" -#: src/slic3r/GUI/MainFrame.cpp:747 +#: src/slic3r/GUI/MainFrame.cpp:1538 msgid "Save presets bundle as:" msgstr "Зберегти набір налаштувань як:" -#: src/slic3r/GUI/MainFrame.cpp:798 +#: src/slic3r/GUI/MainFrame.cpp:1585 #, c-format msgid "%d presets successfully imported." msgstr "%d налаштувань успішно імпортовано." -#: src/slic3r/GUI/MsgDialog.cpp:71 -msgid "Slic3r error" -msgstr "" +#: src/slic3r/GUI/Mouse3DController.cpp:461 +msgid "3Dconnexion settings" +msgstr "Параметри 3Dconnexion" + +#: src/slic3r/GUI/Mouse3DController.cpp:472 +msgid "Device:" +msgstr "Пристрій:" + +#: src/slic3r/GUI/Mouse3DController.cpp:477 +msgid "Speed:" +msgstr "Швидкість:" + +#: src/slic3r/GUI/Mouse3DController.cpp:480 +#: src/slic3r/GUI/Mouse3DController.cpp:501 +msgid "Translation" +msgstr "Переміщення" + +#: src/slic3r/GUI/Mouse3DController.cpp:492 +#: src/slic3r/GUI/Mouse3DController.cpp:501 +msgid "Zoom" +msgstr "Масштабування" + +#: src/slic3r/GUI/Mouse3DController.cpp:498 +msgid "Deadzone:" +msgstr "Мертва зона:" + +#: src/slic3r/GUI/Mouse3DController.cpp:513 +msgid "Options:" +msgstr "Параметри:" + +#: src/slic3r/GUI/Mouse3DController.cpp:516 +msgid "Swap Y/Z axes" +msgstr "Поміняти місцями осі Y/Z" + +#: src/slic3r/GUI/MsgDialog.cpp:70 +#, c-format +msgid "%s error" +msgstr "помилка %s" #: src/slic3r/GUI/MsgDialog.cpp:71 -msgid "Slic3r has encountered an error" -msgstr "" +#, c-format +msgid "%s has encountered an error" +msgstr "%s виявив помилку" -#: src/slic3r/GUI/Plater.cpp:137 +#: src/slic3r/GUI/NotificationManager.hpp:471 +msgid "3D Mouse disconnected." +msgstr "3D миша відключена." + +#: src/slic3r/GUI/NotificationManager.hpp:474 +msgid "Configuration update is available." +msgstr "Доступне оновлення конфігурації." + +#: src/slic3r/GUI/NotificationManager.hpp:474 +msgid "See more." +msgstr "Див. докладніше." + +#: src/slic3r/GUI/NotificationManager.hpp:476 +msgid "New version is available." +msgstr "Доступна нова версія." + +#: src/slic3r/GUI/NotificationManager.hpp:476 +msgid "See Releases page." +msgstr "Див. Сторінку випусків." + +#: src/slic3r/GUI/NotificationManager.hpp:479 +msgid "" +"You have just added a G-code for color change, but its value is empty.\n" +"To export the G-code correctly, check the \"Color Change G-code\" in " +"\"Printer Settings > Custom G-code\"" +msgstr "" +"Ви щойно додали G-код для зміни кольору, але його значення порожнє.\n" +"Щоб правильно експортувати G-код, перевірте значення параметру «G-коду зміни " +"кольору» в «Параметри принтера > Користувацький G-код»" + +#: src/slic3r/GUI/NotificationManager.cpp:490 +#: src/slic3r/GUI/NotificationManager.cpp:500 +msgid "More" +msgstr "Більше" + +#: src/slic3r/GUI/NotificationManager.cpp:864 +#: src/slic3r/GUI/NotificationManager.cpp:1141 +msgid "Export G-Code." +msgstr "Експортувати G-код." + +#: src/slic3r/GUI/NotificationManager.cpp:908 +msgid "Open Folder." +msgstr "Відкрити папку." + +#: src/slic3r/GUI/NotificationManager.cpp:946 +msgid "Eject drive" +msgstr "Від'єднати диск" + +#: src/slic3r/GUI/NotificationManager.cpp:1060 +#: src/slic3r/GUI/NotificationManager.cpp:1076 +#: src/slic3r/GUI/NotificationManager.cpp:1087 +msgid "ERROR:" +msgstr "ПОМИЛКА:" + +#: src/slic3r/GUI/NotificationManager.cpp:1065 +#: src/slic3r/GUI/NotificationManager.cpp:1080 +#: src/slic3r/GUI/NotificationManager.cpp:1095 +msgid "WARNING:" +msgstr "ЗАСТЕРЕЖЕННЯ:" + +#: src/slic3r/GUI/NotificationManager.cpp:1144 +msgid "Slicing finished." +msgstr "Нарізання завершено." + +#: src/slic3r/GUI/NotificationManager.cpp:1186 +msgid "Exporting finished." +msgstr "Експорт завершено." + +#: src/slic3r/GUI/ObjectDataViewModel.cpp:58 +msgid "Instances" +msgstr "Екземпляри" + +#: src/slic3r/GUI/ObjectDataViewModel.cpp:62 +#: src/slic3r/GUI/ObjectDataViewModel.cpp:225 +#, c-format +msgid "Instance %d" +msgstr "Екземпляр %d" + +#: src/slic3r/GUI/ObjectDataViewModel.cpp:69 src/slic3r/GUI/Tab.cpp:3962 +#: src/slic3r/GUI/Tab.cpp:4044 +msgid "Layers" +msgstr "Шари" + +#: src/slic3r/GUI/ObjectDataViewModel.cpp:96 +msgid "Range" +msgstr "Діапазон" + +#: src/slic3r/GUI/OpenGLManager.cpp:259 +#, c-format +msgid "" +"PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" +"while OpenGL version %s, render %s, vendor %s was detected." +msgstr "" +"PrusaSlicer вимагає, щоб графічний драйвер, що підтримує OpenGL 2.0, " +"працював правильно,\n" +"але було виявлено OpenGL версії %s, відтворення %s, постачальника %s." + +#: src/slic3r/GUI/OpenGLManager.cpp:262 +msgid "You may need to update your graphics card driver." +msgstr "Можливо, вам доведеться оновити драйвер відеокарти." + +#: src/slic3r/GUI/OpenGLManager.cpp:265 +msgid "" +"As a workaround, you may run PrusaSlicer with a software rendered 3D " +"graphics by running prusa-slicer.exe with the --sw_renderer parameter." +msgstr "" +"Як спосіб вирішення, ви можете запустити PrusaSlicer з програмним " +"забезпеченням, що рендерить 3D-графіку, за допомогою старту prusa-slicer.exe " +"з параметром --sw_renderer." + +#: src/slic3r/GUI/OpenGLManager.cpp:267 +msgid "Unsupported OpenGL version" +msgstr "Непідтримувана версія OpenGL" + +#: src/slic3r/GUI/OpenGLManager.cpp:275 +#, c-format +msgid "" +"Unable to load the following shaders:\n" +"%s" +msgstr "" +"Не вдається завантажити такі шейдери:\n" +"%s" + +#: src/slic3r/GUI/OpenGLManager.cpp:276 +msgid "Error loading shaders" +msgstr "Помилка завантаження шейдерів" + +#: src/slic3r/GUI/OptionsGroup.cpp:335 +msgctxt "Layers" +msgid "Top" +msgstr "Верхні" + +#: src/slic3r/GUI/OptionsGroup.cpp:335 +msgctxt "Layers" +msgid "Bottom" +msgstr "Нижні" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:51 +msgid "Delete this preset from this printer device" +msgstr "Видаліть цей пресет з цього принтера" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:81 +msgid "This printer will be shown in the presets list as" +msgstr "Цей принтер буде відображатися у списку пресетів як" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:155 +msgid "Physical Printer" +msgstr "Фізичний принтер" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:161 +msgid "Type here the name of your printer device" +msgstr "Введіть тут назву вашого принтера" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:172 +msgid "Descriptive name for the printer" +msgstr "Описова назва принтера" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:176 +msgid "Add preset for this printer device" +msgstr "Додати пресет для цього пристрою принтера" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:205 src/slic3r/GUI/Tab.cpp:2064 +msgid "Print Host upload" +msgstr "Завантаження хоста друку" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:260 +msgid "Connection to printers connected via the print host failed." +msgstr "Помилка підключення до принтерів, підключених через хост друку." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:302 +msgid "Test" +msgstr "Перевірити" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:307 +msgid "Could not get a valid Printer Host reference" +msgstr "Не вдалося отримати дійсне посилання на хост принтера" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:319 +msgid "Success!" +msgstr "Успіх!" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:329 +msgid "Refresh Printers" +msgstr "Оновити принтери" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:356 +msgid "" +"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-" +"signed certificate." +msgstr "" +"Файл HTTPS CA не є обов'язковим. Це потрібно, лише якщо ви використовуєте " +"HTTPS із самопідписаним сертифікатом." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:366 +msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*" +msgstr "Файли сертифікатів (*.crt, *.pem)|*.crt;*.pem|Усі файли|*.*" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:367 +msgid "Open CA certificate file" +msgstr "Відкрити файл CA сертифікату" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:395 +#: src/libslic3r/PrintConfig.cpp:124 +msgid "HTTPS CA File" +msgstr "Файл CA сертифікату" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:396 +#, c-format +msgid "" +"On this system, %s uses HTTPS certificates from the system Certificate Store " +"or Keychain." +msgstr "" +"На цій системі, %s використовує HTTPS-сертифікати з системного сховища " +"сертифікатів або Keychain." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:397 +msgid "" +"To use a custom CA file, please import your CA file into Certificate Store / " +"Keychain." +msgstr "" +"Щоб використовувати власний CA файл, будь-ласка, імпортуйте його у сховища " +"сертифікатів / Keychain." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:543 +msgid "The supplied name is empty. It can't be saved." +msgstr "Надане ім'я порожнє. Не вдається зберегти." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:547 +msgid "You should to change a name of your printer device. It can't be saved." +msgstr "Вам слід змінити назву принтера. Задану назву неможливо зберегти." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:555 +msgid "Printer with name \"%1%\" already exists." +msgstr "Принтер з ім'ям \"%1%\" вже існує." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:556 +msgid "Replace?" +msgstr "Замінити?" + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:579 +msgid "" +"Following printer preset(s) is duplicated:%1%The above preset for printer " +"\"%2%\" will be used just once." +msgstr "" +"Наступні пресети принтера повторюються:%1%Вищезазначений пресет принтера " +"\"%2%\" буде використано лише один раз." + +#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:625 +msgid "It's not possible to delete the last related preset for the printer." +msgstr "Неможливо видалити останній пресет для принтера." + +#: src/slic3r/GUI/Plater.cpp:163 msgid "Volume" msgstr "Обсяг" -#: src/slic3r/GUI/Plater.cpp:138 +#: src/slic3r/GUI/Plater.cpp:164 msgid "Facets" msgstr "Грані" -#: src/slic3r/GUI/Plater.cpp:139 +#: src/slic3r/GUI/Plater.cpp:165 msgid "Materials" msgstr "Матеріали" -#: src/slic3r/GUI/Plater.cpp:142 +#: src/slic3r/GUI/Plater.cpp:168 msgid "Manifold" msgstr "Різноманіття" -#: src/slic3r/GUI/Plater.cpp:188 +#: src/slic3r/GUI/Plater.cpp:218 msgid "Sliced Info" msgstr "Інформація з нарізання" -#: src/slic3r/GUI/Plater.cpp:207 src/slic3r/GUI/Plater.cpp:998 +#: src/slic3r/GUI/Plater.cpp:237 src/slic3r/GUI/Plater.cpp:1151 msgid "Used Filament (m)" msgstr "Використано філаметну (м)" -#: src/slic3r/GUI/Plater.cpp:208 +#: src/slic3r/GUI/Plater.cpp:238 src/slic3r/GUI/Plater.cpp:1163 msgid "Used Filament (mm³)" msgstr "Використано філаметну (мм³)" -#: src/slic3r/GUI/Plater.cpp:209 +#: src/slic3r/GUI/Plater.cpp:239 src/slic3r/GUI/Plater.cpp:1170 msgid "Used Filament (g)" msgstr "Використано філаметну (г)" -#: src/slic3r/GUI/Plater.cpp:210 +#: src/slic3r/GUI/Plater.cpp:240 msgid "Used Material (unit)" -msgstr "" +msgstr "Використано матеріалу (одиниць)" -#: src/slic3r/GUI/Plater.cpp:211 src/slic3r/GUI/Plater.cpp:1013 -#: src/libslic3r/PrintConfig.cpp:716 -msgid "Cost" -msgstr "Вартість" +#: src/slic3r/GUI/Plater.cpp:241 +msgid "Cost (money)" +msgstr "Вартість (г.о.)" -#: src/slic3r/GUI/Plater.cpp:212 src/slic3r/GUI/Plater.cpp:985 -#: src/slic3r/GUI/Plater.cpp:1027 -msgid "Estimated printing time" -msgstr "Приблизний час друку" - -#: src/slic3r/GUI/Plater.cpp:213 +#: src/slic3r/GUI/Plater.cpp:243 msgid "Number of tool changes" -msgstr "" +msgstr "Кількість змін інструменту" -#: src/slic3r/GUI/Plater.cpp:290 -msgid "Click to edit preset" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:413 +#: src/slic3r/GUI/Plater.cpp:360 msgid "Select what kind of support do you need" -msgstr "" +msgstr "Виберіть необхідну вам підтримку" -#: src/slic3r/GUI/Plater.cpp:415 src/libslic3r/PrintConfig.cpp:1814 -#: src/libslic3r/PrintConfig.cpp:2419 +#: src/slic3r/GUI/Plater.cpp:362 src/libslic3r/PrintConfig.cpp:2128 +#: src/libslic3r/PrintConfig.cpp:2923 msgid "Support on build plate only" -msgstr "Підтримка тільки на збірній пластині" +msgstr "Підтримки тільки на столі" -#: src/slic3r/GUI/Plater.cpp:416 +#: src/slic3r/GUI/Plater.cpp:363 src/slic3r/GUI/Plater.cpp:489 +msgid "For support enforcers only" +msgstr "Тільки примусові підтримки" + +#: src/slic3r/GUI/Plater.cpp:364 msgid "Everywhere" -msgstr "" +msgstr "Всюди" -#: src/slic3r/GUI/Plater.cpp:438 src/slic3r/GUI/Tab.cpp:1007 +#: src/slic3r/GUI/Plater.cpp:396 src/slic3r/GUI/Tab.cpp:1469 msgid "Brim" msgstr "Край" -#: src/slic3r/GUI/Plater.cpp:440 +#: src/slic3r/GUI/Plater.cpp:398 msgid "" "This flag enables the brim that will be printed around each object on the " "first layer." msgstr "" +"Цей прапорець дозволяє позначити край, який буде надруковано навколо кожного " +"об'єкта на першому шарі." -#: src/slic3r/GUI/Plater.cpp:448 +#: src/slic3r/GUI/Plater.cpp:406 msgid "Purging volumes" -msgstr "" +msgstr "Обсяги очищення" -#: src/slic3r/GUI/Plater.cpp:673 -msgid "Print settings" -msgstr "Параметри друку" +#: src/slic3r/GUI/Plater.cpp:503 +msgid "Select what kind of pad do you need" +msgstr "Виберіть необхідну вам подушку" -#: src/slic3r/GUI/Plater.cpp:674 src/slic3r/GUI/Tab.cpp:1421 -#: src/slic3r/GUI/Tab.cpp:1422 -msgid "Filament" -msgstr "Філамент" +#: src/slic3r/GUI/Plater.cpp:505 +msgid "Below object" +msgstr "Під об’єктем" -#: src/slic3r/GUI/Plater.cpp:675 src/slic3r/GUI/Preset.cpp:1252 -msgid "SLA print" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:506 +msgid "Around object" +msgstr "Навколо об'єкта" -#: src/slic3r/GUI/Plater.cpp:676 src/slic3r/GUI/Preset.cpp:1253 -msgid "SLA material" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:695 +msgid "SLA print settings" +msgstr "Параметри SLA-друку" -#: src/slic3r/GUI/Plater.cpp:677 -msgid "Printer" -msgstr "Принтер" - -#: src/slic3r/GUI/Plater.cpp:707 src/slic3r/GUI/Plater.cpp:3674 +#: src/slic3r/GUI/Plater.cpp:756 src/slic3r/GUI/Plater.cpp:6055 msgid "Send to printer" msgstr "Надіслати на принтер" -#: src/slic3r/GUI/Plater.cpp:727 src/slic3r/GUI/Plater.cpp:2352 -#: src/slic3r/GUI/Plater.cpp:3470 +#: src/slic3r/GUI/Plater.cpp:771 src/slic3r/GUI/Plater.cpp:3009 +#: src/slic3r/GUI/Plater.cpp:5584 msgid "Slice now" msgstr "Нарізати зараз" -#: src/slic3r/GUI/Plater.cpp:860 +#: src/slic3r/GUI/Plater.cpp:926 msgid "Hold Shift to Slice & Export G-code" -msgstr "" +msgstr "Утримуйте Shift, щоб нарізати та експортувати G-код" -#: src/slic3r/GUI/Plater.cpp:931 +#: src/slic3r/GUI/Plater.cpp:1071 #, c-format msgid "%d (%d shells)" msgstr "%d (%d оболонок)" -#: src/slic3r/GUI/Plater.cpp:936 +#: src/slic3r/GUI/Plater.cpp:1076 #, c-format msgid "Auto-repaired (%d errors)" -msgstr "Автоматичне відновлення (%d помилок)" +msgstr "Авто-відновлення (%d помилок)" -#: src/slic3r/GUI/Plater.cpp:939 +#: src/slic3r/GUI/Plater.cpp:1079 #, c-format msgid "" "%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d " @@ -2355,93 +5569,214 @@ msgstr "" "вироджено %d грані, виправлено %d країв, вилучено %d грані, додано %d грані, " "змінено %d грані, повернуто %d країв" -#: src/slic3r/GUI/Plater.cpp:949 +#: src/slic3r/GUI/Plater.cpp:1089 msgid "Yes" msgstr "Так" -#: src/slic3r/GUI/Plater.cpp:972 +#: src/slic3r/GUI/Plater.cpp:1110 msgid "Used Material (ml)" -msgstr "" +msgstr "Використано матеріалу (мл)" -#: src/slic3r/GUI/Plater.cpp:975 +#: src/slic3r/GUI/Plater.cpp:1113 msgid "object(s)" -msgstr "" +msgstr "об'єкт(и)" -#: src/slic3r/GUI/Plater.cpp:975 +#: src/slic3r/GUI/Plater.cpp:1113 msgid "supports and pad" -msgstr "" +msgstr "підтримки та подушка" -#: src/slic3r/GUI/Plater.cpp:1000 src/slic3r/GUI/Plater.cpp:1015 +#: src/slic3r/GUI/Plater.cpp:1151 +msgid "Used Filament (in)" +msgstr "Використано філаметну (дюйми)" + +#: src/slic3r/GUI/Plater.cpp:1153 src/slic3r/GUI/Plater.cpp:1206 msgid "objects" -msgstr "" +msgstr "об'єкти" -#: src/slic3r/GUI/Plater.cpp:1000 src/slic3r/GUI/Plater.cpp:1015 +#: src/slic3r/GUI/Plater.cpp:1153 src/slic3r/GUI/Plater.cpp:1206 msgid "wipe tower" -msgstr "" +msgstr "вежа витирання" -#: src/slic3r/GUI/Plater.cpp:1030 +#: src/slic3r/GUI/Plater.cpp:1163 +msgid "Used Filament (in³)" +msgstr "Використано філаметну (дюйми³)" + +#: src/slic3r/GUI/Plater.cpp:1189 +msgid "Filament at extruder %1%" +msgstr "Філамент екструдеру %1%" + +#: src/slic3r/GUI/Plater.cpp:1195 +msgid "(including spool)" +msgstr "(включаючи котушку)" + +#: src/slic3r/GUI/Plater.cpp:1204 src/libslic3r/PrintConfig.cpp:822 +#: src/libslic3r/PrintConfig.cpp:2738 src/libslic3r/PrintConfig.cpp:2739 +msgid "Cost" +msgstr "Вартість" + +#: src/slic3r/GUI/Plater.cpp:1222 msgid "normal mode" -msgstr "" +msgstr "нормальний режим" -#: src/slic3r/GUI/Plater.cpp:1034 -msgid "silent mode" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:1232 +msgid "stealth mode" +msgstr "тихий режим" -#: src/slic3r/GUI/Plater.cpp:1544 -msgid "Loading" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:1554 +#: src/slic3r/GUI/Plater.cpp:1403 src/slic3r/GUI/Plater.cpp:4923 #, c-format -msgid "Processing input file %s\n" -msgstr "" +msgid "%s - Drop project file" +msgstr "%s - Перетягнути файл проекту" -#: src/slic3r/GUI/Plater.cpp:1612 +#: src/slic3r/GUI/Plater.cpp:1410 src/slic3r/GUI/Plater.cpp:4930 +msgid "Open as project" +msgstr "Відкрити як проект" + +#: src/slic3r/GUI/Plater.cpp:1411 src/slic3r/GUI/Plater.cpp:4931 +msgid "Import geometry only" +msgstr "Імпорт тільки геометрії" + +#: src/slic3r/GUI/Plater.cpp:1412 src/slic3r/GUI/Plater.cpp:4932 +msgid "Import config only" +msgstr "Імпорт тільки конфігурації" + +#: src/slic3r/GUI/Plater.cpp:1415 src/slic3r/GUI/Plater.cpp:4935 +msgid "Select an action to apply to the file" +msgstr "Виберіть дію, яку потрібно застосувати до файлу" + +#: src/slic3r/GUI/Plater.cpp:1416 src/slic3r/GUI/Plater.cpp:4936 +msgid "Action" +msgstr "Дія" + +#: src/slic3r/GUI/Plater.cpp:1424 src/slic3r/GUI/Plater.cpp:4944 +msgid "Don't show again" +msgstr "Не показувати знову" + +#: src/slic3r/GUI/Plater.cpp:1469 src/slic3r/GUI/Plater.cpp:4981 +msgid "You can open only one .gcode file at a time." +msgstr "Одночасно можна відкрити лише один файл .gcode." + +#: src/slic3r/GUI/Plater.cpp:1470 src/slic3r/GUI/Plater.cpp:4982 +msgid "Drag and drop G-code file" +msgstr "Перетягування файлу G-коду" + +#: src/slic3r/GUI/Plater.cpp:1524 src/slic3r/GUI/Plater.cpp:4796 +#: src/slic3r/GUI/Plater.cpp:5036 +msgid "Import Object" +msgstr "Імпорт об'єкту" + +#: src/slic3r/GUI/Plater.cpp:1546 src/slic3r/GUI/Plater.cpp:5058 +msgid "Load File" +msgstr "Завантажити файл" + +#: src/slic3r/GUI/Plater.cpp:1551 src/slic3r/GUI/Plater.cpp:5063 +msgid "Load Files" +msgstr "Завантажити файли" + +#: src/slic3r/GUI/Plater.cpp:1654 +msgid "Fill bed" +msgstr "Заповнити стіл" + +#: src/slic3r/GUI/Plater.cpp:1660 +msgid "Optimize Rotation" +msgstr "Оптимізувати обертання" + +#: src/slic3r/GUI/Plater.cpp:1666 +msgid "Import SLA archive" +msgstr "Імпорт SLА-архіву" + +#: src/slic3r/GUI/Plater.cpp:2129 +#, c-format msgid "" -"This file contains several objects positioned at multiple heights. Instead " -"of considering them as multiple objects, should I consider\n" -"this file as a single object having multiple parts?\n" +"Successfully unmounted. The device %s(%s) can now be safely removed from the " +"computer." msgstr "" -"Цей файл містить кілька об'єктів, розташованих на декількох висотах. Замість " -"того, щоб розглядати їх як кілька об'єктів, чи потрібно розглянути\n" -"цей файл як єдиний об'єкт, що має декілька частин?\n" +"Успішно від'єднано. Пристрій %s(%s) тепер можна безпечно вилучити з " +"комп’ютера." -#: src/slic3r/GUI/Plater.cpp:1615 src/slic3r/GUI/Plater.cpp:1707 +#: src/slic3r/GUI/Plater.cpp:2134 +#, c-format +msgid "Ejecting of device %s(%s) has failed." +msgstr "Не вдалося від'єднати пристрій %s (%s)." + +#: src/slic3r/GUI/Plater.cpp:2153 +msgid "New Project" +msgstr "Новий проект" + +#: src/slic3r/GUI/Plater.cpp:2246 +msgid "Expand sidebar" +msgstr "Розгорнути бічну панель" + +#: src/slic3r/GUI/Plater.cpp:2319 +msgid "Loading" +msgstr "Завантаження" + +#: src/slic3r/GUI/Plater.cpp:2329 +msgid "Loading file" +msgstr "Завантаження файлу" + +#: src/slic3r/GUI/Plater.cpp:2415 +#, c-format +msgid "" +"Some object(s) in file %s looks like saved in inches.\n" +"Should I consider them as a saved in inches and convert them?" +msgstr "" +"Схоже на те, що деякі об’єкти у файлі %s збережені в дюймах.\n" +"Чи слід розглядати їх як збережені в дюймах і конвертувати?" + +#: src/slic3r/GUI/Plater.cpp:2417 +msgid "The object appears to be saved in inches" +msgstr "Здається, об’єкт був збережений у дюймах" + +#: src/slic3r/GUI/Plater.cpp:2425 +msgid "" +"This file contains several objects positioned at multiple heights.\n" +"Instead of considering them as multiple objects, should I consider\n" +"this file as a single object having multiple parts?" +msgstr "" +"Цей файл містить кілька об'єктів, розташованих на декількох висотах. \n" +"Замість того, щоб розглядати їх як кілька об'єктів, чи потрібно розглянути\n" +"цей файл як єдиний об'єкт, що має декілька частин?" + +#: src/slic3r/GUI/Plater.cpp:2428 src/slic3r/GUI/Plater.cpp:2481 msgid "Multi-part object detected" msgstr "Виявлено об'єкт, що складається з кількох частин" -#: src/slic3r/GUI/Plater.cpp:1650 +#: src/slic3r/GUI/Plater.cpp:2435 msgid "" -"This file cannot be loaded in simple mode. Do you want to switch to expert " -"mode?\n" +"This file cannot be loaded in a simple mode. Do you want to switch to an " +"advanced mode?" msgstr "" +"Цей файл не можна завантажити у простому режимі. Ви хочете перейти в " +"розширений режим?" -#: src/slic3r/GUI/Plater.cpp:1651 +#: src/slic3r/GUI/Plater.cpp:2436 msgid "Detected advanced data" -msgstr "" +msgstr "Виявлено розширені дані" -#: src/slic3r/GUI/Plater.cpp:1684 +#: src/slic3r/GUI/Plater.cpp:2458 #, c-format msgid "" "You can't to add the object(s) from %s because of one or some of them " "is(are) multi-part" msgstr "" +"Ви не можете додати об’єкт(и) із %s через те, що один або деякі з них " +"складається з декількох частин" -#: src/slic3r/GUI/Plater.cpp:1704 +#: src/slic3r/GUI/Plater.cpp:2478 msgid "" "Multiple objects were loaded for a multi-material printer.\n" "Instead of considering them as multiple objects, should I consider\n" -"these files to represent a single object having multiple parts?\n" +"these files to represent a single object having multiple parts?" msgstr "" "До мульти-матеріального принтеру завантажено кілька об'єктів.\n" "Замість того, щоб розглядати їх як кілька об'єктів, чи потрібно розглянути\n" -"ці файл як єдиний об'єкт, що має декілька частин?\n" +"ці файл як єдиний об'єкт, що має декілька частин?" -#: src/slic3r/GUI/Plater.cpp:1720 +#: src/slic3r/GUI/Plater.cpp:2494 msgid "Loaded" -msgstr "" +msgstr "Завантажено" -#: src/slic3r/GUI/Plater.cpp:1812 +#: src/slic3r/GUI/Plater.cpp:2596 msgid "" "Your object appears to be too large, so it was automatically scaled down to " "fit your print bed." @@ -2449,51 +5784,35 @@ msgstr "" "Ваш об'єкт видався занадто великим, тому він автоматично зменшився " "відповідно до вашої полотна друку." -#: src/slic3r/GUI/Plater.cpp:1813 +#: src/slic3r/GUI/Plater.cpp:2597 msgid "Object too large?" msgstr "Об'єкт занадто великий?" -#: src/slic3r/GUI/Plater.cpp:1863 +#: src/slic3r/GUI/Plater.cpp:2659 msgid "Export STL file:" -msgstr "" +msgstr "Експорт STL-файлу:" -#: src/slic3r/GUI/Plater.cpp:1870 +#: src/slic3r/GUI/Plater.cpp:2666 msgid "Export AMF file:" -msgstr "" +msgstr "Експортувати AMF-файл:" -#: src/slic3r/GUI/Plater.cpp:1876 +#: src/slic3r/GUI/Plater.cpp:2672 msgid "Save file as:" -msgstr "" +msgstr "Зберегти файл як:" -#: src/slic3r/GUI/Plater.cpp:2042 -msgid "Arranging canceled" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:2678 +msgid "Export OBJ file:" +msgstr "Експорт OBJ-файлу:" -#: src/slic3r/GUI/Plater.cpp:2045 -msgid "Arranging" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:2774 +msgid "Delete Object" +msgstr "Видалити об'єкт" -#: src/slic3r/GUI/Plater.cpp:2079 -msgid "Could not arrange model objects! Some geometries may be invalid." -msgstr "" +#: src/slic3r/GUI/Plater.cpp:2785 +msgid "Reset Project" +msgstr "Скинути проект" -#: src/slic3r/GUI/Plater.cpp:2083 -msgid "Arranging done." -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:2124 -msgid "Orientation search canceled" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:2129 -msgid "Searching for optimal orientation" -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:2190 -msgid "Orientation found." -msgstr "" - -#: src/slic3r/GUI/Plater.cpp:2211 +#: src/slic3r/GUI/Plater.cpp:2857 msgid "" "The selected object can't be split because it contains more than one volume/" "material." @@ -2501,187 +5820,300 @@ msgstr "" "Вибраний об'єкт не можна розділити, оскільки містить більше одного об'єму/" "матеріалу." -#: src/slic3r/GUI/Plater.cpp:2337 +#: src/slic3r/GUI/Plater.cpp:2868 +msgid "Split to Objects" +msgstr "Розділити на об'єкти" + +#: src/slic3r/GUI/Plater.cpp:2993 src/slic3r/GUI/Plater.cpp:3723 msgid "Invalid data" -msgstr "" +msgstr "Некоректні дані" -#: src/slic3r/GUI/Plater.cpp:2346 +#: src/slic3r/GUI/Plater.cpp:3003 msgid "Ready to slice" -msgstr "" +msgstr "Готово до нарізки" -#: src/slic3r/GUI/Plater.cpp:2379 src/slic3r/GUI/PrintHostDialogs.cpp:220 +#: src/slic3r/GUI/Plater.cpp:3041 src/slic3r/GUI/PrintHostDialogs.cpp:264 msgid "Cancelling" -msgstr "" +msgstr "Скасування" -#: src/slic3r/GUI/Plater.cpp:2396 +#: src/slic3r/GUI/Plater.cpp:3060 msgid "Another export job is currently running." msgstr "На даний час виконується інший експорт." -#: src/slic3r/GUI/Plater.cpp:2656 -msgid "Export failed" -msgstr "Експортувати не вдалося" +#: src/slic3r/GUI/Plater.cpp:3177 +msgid "Please select the file to reload" +msgstr "Будь ласка, виберіть файл для перезавантаження" -#: src/slic3r/GUI/Plater.cpp:2661 src/slic3r/GUI/PrintHostDialogs.cpp:221 -msgid "Cancelled" +#: src/slic3r/GUI/Plater.cpp:3212 +msgid "It is not allowed to change the file to reload" +msgstr "Не дозволяється змінювати файл для перезавантаження" + +#: src/slic3r/GUI/Plater.cpp:3212 +msgid "Do you want to retry" +msgstr "Повторити спробу" + +#: src/slic3r/GUI/Plater.cpp:3230 +msgid "Reload from:" +msgstr "Перезавантажити з:" + +#: src/slic3r/GUI/Plater.cpp:3323 +msgid "Unable to reload:" +msgstr "Не вдається перезавантажити:" + +#: src/slic3r/GUI/Plater.cpp:3328 +msgid "Error during reload" +msgstr "Помилка під час перезавантаження" + +#: src/slic3r/GUI/Plater.cpp:3347 +msgid "Reload all from disk" +msgstr "Перезавантажити все з диска" + +#: src/slic3r/GUI/Plater.cpp:3374 +msgid "" +"ERROR: Please close all manipulators available from the left toolbar before " +"fixing the mesh." msgstr "" +"ПОМИЛКА: Будь ласка, закрийте всі маніпулятори, доступні на лівій панелі " +"інструментів, перш ніж фіксувати сітку." -#: src/slic3r/GUI/Plater.cpp:2747 src/slic3r/GUI/Plater.cpp:2759 -#: src/slic3r/GUI/Plater.cpp:2831 -msgid "Increase copies" -msgstr "Збільшити копії" +#: src/slic3r/GUI/Plater.cpp:3380 +msgid "Fix through NetFabb" +msgstr "Виправити за допомогою NetFabb" -#: src/slic3r/GUI/Plater.cpp:2825 src/slic3r/GUI/Plater.cpp:2843 +#: src/slic3r/GUI/Plater.cpp:3397 +msgid "Custom supports and seams were removed after repairing the mesh." +msgstr "Користувацькі підтримки та шви були видалені після ремонту сітки." + +#: src/slic3r/GUI/Plater.cpp:3680 +msgid "There are active warnings concerning sliced models:" +msgstr "Існують активні попередження щодо нарізаних моделей:" + +#: src/slic3r/GUI/Plater.cpp:3691 +msgid "generated warnings" +msgstr "згенеровані попередження" + +#: src/slic3r/GUI/Plater.cpp:3731 src/slic3r/GUI/PrintHostDialogs.cpp:265 +msgid "Cancelled" +msgstr "Скасовано" + +#: src/slic3r/GUI/Plater.cpp:3998 src/slic3r/GUI/Plater.cpp:4022 msgid "Remove the selected object" msgstr "Видалити вибраний об'єкт" -#: src/slic3r/GUI/Plater.cpp:2831 -msgid "Place one more copy of the selected object" -msgstr "Розташувати ще одну копію обраного об'єкта" +#: src/slic3r/GUI/Plater.cpp:4007 +msgid "Add one more instance of the selected object" +msgstr "Додати ще один екземпляр вибраного об’єкта" -#: src/slic3r/GUI/Plater.cpp:2833 -msgid "Decrease copies" -msgstr "Зменшити копії" +#: src/slic3r/GUI/Plater.cpp:4009 +msgid "Remove one instance of the selected object" +msgstr "Видалити один екземпляр вибраного об’єкта" -#: src/slic3r/GUI/Plater.cpp:2833 -msgid "Remove one copy of the selected object" -msgstr "Вилучіть одну копію обраного об'єкта" +#: src/slic3r/GUI/Plater.cpp:4011 +msgid "Set number of instances" +msgstr "Встановити кількість екземплярів" -#: src/slic3r/GUI/Plater.cpp:2835 -msgid "Set number of copies" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:4011 +msgid "Change the number of instances of the selected object" +msgstr "Змінити кількість екземплярів виділеного об'єкта" -#: src/slic3r/GUI/Plater.cpp:2835 -msgid "Change the number of copies of the selected object" -msgstr "Змінити кількість копій обраного об'єкта" +#: src/slic3r/GUI/Plater.cpp:4013 +msgid "Fill bed with instances" +msgstr "Заповнити стіл екземплярами" -#: src/slic3r/GUI/Plater.cpp:2858 -msgid "Reload from Disk" -msgstr "Перезавантажити з диска" +#: src/slic3r/GUI/Plater.cpp:4013 +msgid "Fill the remaining area of bed with instances of the selected object" +msgstr "Заповнити залишок столу екземплярами обраного об'єкта" -#: src/slic3r/GUI/Plater.cpp:2858 -msgid "Reload the selected file from Disk" -msgstr "Перезавантажити вибраний файл із диска" +#: src/slic3r/GUI/Plater.cpp:4032 +msgid "Reload the selected object from disk" +msgstr "Перезавантажити вибраний об'єкт із диска" -#: src/slic3r/GUI/Plater.cpp:2861 +#: src/slic3r/GUI/Plater.cpp:4035 msgid "Export the selected object as STL file" -msgstr "" +msgstr "Експорт вибраного об'єкту як STL-файл" -#: src/slic3r/GUI/Plater.cpp:2873 +#: src/slic3r/GUI/Plater.cpp:4065 msgid "Along X axis" -msgstr "" +msgstr "Уздовж осі X" -#: src/slic3r/GUI/Plater.cpp:2873 +#: src/slic3r/GUI/Plater.cpp:4065 msgid "Mirror the selected object along the X axis" msgstr "Віддзеркалити виділений об'єкт уздовж осі Х" -#: src/slic3r/GUI/Plater.cpp:2875 +#: src/slic3r/GUI/Plater.cpp:4067 msgid "Along Y axis" -msgstr "" +msgstr "Уздовж осі Y" -#: src/slic3r/GUI/Plater.cpp:2875 +#: src/slic3r/GUI/Plater.cpp:4067 msgid "Mirror the selected object along the Y axis" msgstr "Віддзеркалити виділений об'єкт уздовж осі Y" -#: src/slic3r/GUI/Plater.cpp:2877 +#: src/slic3r/GUI/Plater.cpp:4069 msgid "Along Z axis" -msgstr "" +msgstr "Уздовж осі Z" -#: src/slic3r/GUI/Plater.cpp:2877 +#: src/slic3r/GUI/Plater.cpp:4069 msgid "Mirror the selected object along the Z axis" msgstr "Віддзеркалити виділений об'єкт уздовж осі Z" -#: src/slic3r/GUI/Plater.cpp:2880 +#: src/slic3r/GUI/Plater.cpp:4072 msgid "Mirror" msgstr "Віддзеркалити" -#: src/slic3r/GUI/Plater.cpp:2880 +#: src/slic3r/GUI/Plater.cpp:4072 msgid "Mirror the selected object" msgstr "Віддзеркалити виділений об'єкт" -#: src/slic3r/GUI/Plater.cpp:2898 +#: src/slic3r/GUI/Plater.cpp:4084 msgid "To objects" -msgstr "" +msgstr "На об'єкти" -#: src/slic3r/GUI/Plater.cpp:2898 src/slic3r/GUI/Plater.cpp:2920 +#: src/slic3r/GUI/Plater.cpp:4084 src/slic3r/GUI/Plater.cpp:4104 msgid "Split the selected object into individual objects" -msgstr "" +msgstr "Розділити вибраний об'єкт на окремі об'єкти" -#: src/slic3r/GUI/Plater.cpp:2900 +#: src/slic3r/GUI/Plater.cpp:4086 msgid "To parts" -msgstr "" +msgstr "На частини" -#: src/slic3r/GUI/Plater.cpp:2900 src/slic3r/GUI/Plater.cpp:2940 +#: src/slic3r/GUI/Plater.cpp:4086 src/slic3r/GUI/Plater.cpp:4122 msgid "Split the selected object into individual sub-parts" -msgstr "" +msgstr "Розділити вибраний об'єкт на окремі частини" -#: src/slic3r/GUI/Plater.cpp:2903 src/slic3r/GUI/Plater.cpp:2920 -#: src/slic3r/GUI/Plater.cpp:2940 src/libslic3r/PrintConfig.cpp:3075 +#: src/slic3r/GUI/Plater.cpp:4089 src/slic3r/GUI/Plater.cpp:4104 +#: src/slic3r/GUI/Plater.cpp:4122 src/libslic3r/PrintConfig.cpp:3759 msgid "Split" msgstr "Розділити" -#: src/slic3r/GUI/Plater.cpp:2903 +#: src/slic3r/GUI/Plater.cpp:4089 msgid "Split the selected object" -msgstr "" +msgstr "Розділити вибраний об'єкт" -#: src/slic3r/GUI/Plater.cpp:2926 +#: src/slic3r/GUI/Plater.cpp:4111 msgid "Optimize orientation" -msgstr "" +msgstr "Оптимізувати орієнтацію" -#: src/slic3r/GUI/Plater.cpp:2926 +#: src/slic3r/GUI/Plater.cpp:4112 msgid "Optimize the rotation of the object for better print results." -msgstr "" +msgstr "Оптимізуйте обертання об’єкта для кращих результатів друку." -#: src/slic3r/GUI/Plater.cpp:3342 +#: src/slic3r/GUI/Plater.cpp:4192 +msgid "3D editor view" +msgstr "Перегляд у 3D-редакторі" + +#: src/slic3r/GUI/Plater.cpp:4564 +msgid "" +"%1% printer was active at the time the target Undo / Redo snapshot was " +"taken. Switching to %1% printer requires reloading of %1% presets." +msgstr "" +"На момент створення Undo/Redo знімка був активний принтер %1%. Для " +"переключення на принтер %1% потрібно перезавантажити пресет %1%." + +#: src/slic3r/GUI/Plater.cpp:4768 +msgid "Load Project" +msgstr "Завантажити проект" + +#: src/slic3r/GUI/Plater.cpp:4800 +msgid "Import Objects" +msgstr "Імпорт об'єктів" + +#: src/slic3r/GUI/Plater.cpp:4868 +msgid "The selected file" +msgstr "Вибраний файл" + +#: src/slic3r/GUI/Plater.cpp:4868 +msgid "does not contain valid gcode." +msgstr "не містить дійсного G-коду." + +#: src/slic3r/GUI/Plater.cpp:4869 +msgid "Error while loading .gcode file" +msgstr "Помилка під час завантаження GCODE-файлу" + +#: src/slic3r/GUI/Plater.cpp:5107 +msgid "All objects will be removed, continue?" +msgstr "Усі об’єкти буде видалено, продовжити?" + +#: src/slic3r/GUI/Plater.cpp:5115 +msgid "Delete Selected Objects" +msgstr "Видалити вибрані об'єкти" + +#: src/slic3r/GUI/Plater.cpp:5123 +msgid "Increase Instances" +msgstr "Збільшити кількість копій" + +#: src/slic3r/GUI/Plater.cpp:5157 +msgid "Decrease Instances" +msgstr "Зменшити кількість копій" + +#: src/slic3r/GUI/Plater.cpp:5188 +msgid "Enter the number of copies:" +msgstr "Введіть кількість копій об'єкта:" + +#: src/slic3r/GUI/Plater.cpp:5189 +msgid "Copies of the selected object" +msgstr "Кількість копій обраного об'єкта" + +#: src/slic3r/GUI/Plater.cpp:5193 +#, c-format +msgid "Set numbers of copies to %d" +msgstr "Встановити кількість копій на %d" + +#: src/slic3r/GUI/Plater.cpp:5259 +msgid "Cut by Plane" +msgstr "Вирізати площиною" + +#: src/slic3r/GUI/Plater.cpp:5316 msgid "Save G-code file as:" -msgstr "" +msgstr "Зберегти G-код файл як:" -#: src/slic3r/GUI/Plater.cpp:3342 +#: src/slic3r/GUI/Plater.cpp:5316 msgid "Save SL1 file as:" -msgstr "" +msgstr "Зберегти SL1-файл як:" -#: src/slic3r/GUI/Plater.cpp:3397 +#: src/slic3r/GUI/Plater.cpp:5463 #, c-format msgid "STL file exported to %s" -msgstr "" +msgstr "STL-файл експортовано в %s" -#: src/slic3r/GUI/Plater.cpp:3413 +#: src/slic3r/GUI/Plater.cpp:5480 #, c-format msgid "AMF file exported to %s" -msgstr "" +msgstr "AMF-файл експортовано в %s" -#: src/slic3r/GUI/Plater.cpp:3416 +#: src/slic3r/GUI/Plater.cpp:5483 #, c-format msgid "Error exporting AMF file %s" -msgstr "" +msgstr "Помилка експортування AMF-файлу %s" -#: src/slic3r/GUI/Plater.cpp:3442 +#: src/slic3r/GUI/Plater.cpp:5512 #, c-format msgid "3MF file exported to %s" -msgstr "" +msgstr "3MF-файл експортовано в %s" -#: src/slic3r/GUI/Plater.cpp:3445 +#: src/slic3r/GUI/Plater.cpp:5517 #, c-format msgid "Error exporting 3MF file %s" -msgstr "" +msgstr "Помилка експортування 3MF-файлу %s" -#: src/slic3r/GUI/Plater.cpp:3673 +#: src/slic3r/GUI/Plater.cpp:6054 msgid "Export" -msgstr "" +msgstr "Експорт" -#: src/slic3r/GUI/Plater.cpp:3674 -msgid "Send G-code" -msgstr "" +#: src/slic3r/GUI/Plater.cpp:6149 +msgid "Paste From Clipboard" +msgstr "Вставити з буферу обміну" -#: src/slic3r/GUI/Preferences.cpp:17 src/slic3r/GUI/Tab.cpp:1762 -#: src/slic3r/GUI/Tab.cpp:1963 +#: src/slic3r/GUI/Preferences.cpp:56 src/slic3r/GUI/Tab.cpp:2098 +#: src/slic3r/GUI/Tab.cpp:2285 src/slic3r/GUI/Tab.cpp:2393 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1080 msgid "General" msgstr "Загальне" -#: src/slic3r/GUI/Preferences.cpp:34 +#: src/slic3r/GUI/Preferences.cpp:69 msgid "Remember output directory" msgstr "Пам'ятати вихідний каталог" -#: src/slic3r/GUI/Preferences.cpp:36 +#: src/slic3r/GUI/Preferences.cpp:71 msgid "" "If this is enabled, Slic3r will prompt the last output directory instead of " "the one containing the input files." @@ -2689,22 +6121,22 @@ msgstr "" "Якщо вибрано, Slic3r запропонує останню вихідну директорію замість тої, що " "вказана у вхідному файлі." -#: src/slic3r/GUI/Preferences.cpp:42 +#: src/slic3r/GUI/Preferences.cpp:77 msgid "Auto-center parts" msgstr "Автоцентрувати частини" -#: src/slic3r/GUI/Preferences.cpp:44 +#: src/slic3r/GUI/Preferences.cpp:79 msgid "" "If this is enabled, Slic3r will auto-center objects around the print bed " "center." msgstr "" "Якщо вибрано, Slic3r автоматично орієнтує об'єкти навколо центру друку." -#: src/slic3r/GUI/Preferences.cpp:50 +#: src/slic3r/GUI/Preferences.cpp:85 msgid "Background processing" msgstr "Фонова обробка" -#: src/slic3r/GUI/Preferences.cpp:52 +#: src/slic3r/GUI/Preferences.cpp:87 msgid "" "If this is enabled, Slic3r will pre-process objects as soon as they're " "loaded in order to save time when exporting G-code." @@ -2712,11 +6144,58 @@ msgstr "" "Якщо вибрано, Slic3r буде попередньо обробляти об'єкти, як тільки вони " "будуть завантажені, щоб заощадити час при експорті G-коду." -#: src/slic3r/GUI/Preferences.cpp:74 +#: src/slic3r/GUI/Preferences.cpp:96 +msgid "" +"If enabled, PrusaSlicer will check for the new versions of itself online. " +"When a new version becomes available a notification is displayed at the next " +"application startup (never during program usage). This is only a " +"notification mechanisms, no automatic installation is done." +msgstr "" +"Якщо увімкнено, PrusaSlicer перевірить наявність нових версій в Інтернеті. " +"Коли нова версія стає доступною, під час наступного запуску програми " +"з'явиться сповіщення (ніколи під час використання програми). Це лише " +"механізми сповіщення, автоматична установка не виконується." + +#: src/slic3r/GUI/Preferences.cpp:102 +msgid "Export sources full pathnames to 3mf and amf" +msgstr "Експортувати повні назви шляхів до 3MF та amf" + +#: src/slic3r/GUI/Preferences.cpp:104 +msgid "" +"If enabled, allows the Reload from disk command to automatically find and " +"load the files when invoked." +msgstr "" +"Якщо увімкнено, дозволяє команді Перезавантажити з диска автоматично " +"знаходити і завантажувати файли під час виклику." + +#: src/slic3r/GUI/Preferences.cpp:114 +msgid "If enabled, sets PrusaSlicer as default application to open .3mf files." +msgstr "" +"Якщо увімкнено, встановлює PrusaSlicer як типову програму для відкриття 3MF-" +"файлів." + +#: src/slic3r/GUI/Preferences.cpp:121 +msgid "If enabled, sets PrusaSlicer as default application to open .stl files." +msgstr "" +"Якщо ввімкнено, програма PrusaSlicer за промовчанням відкриває STL-файли." + +#: src/slic3r/GUI/Preferences.cpp:131 +msgid "" +"If enabled, Slic3r downloads updates of built-in system presets in the " +"background. These updates are downloaded into a separate temporary location. " +"When a new preset version becomes available it is offered at application " +"startup." +msgstr "" +"Якщо цей параметр увімкнено, Slic3r завантажує оновлення вбудованих пресетів " +"системи у фоновому режимі. Ці оновлення завантажуються в окреме тимчасове " +"місце розташування. Коли нова версія пресетів стає доступною, вона " +"пропонується під час запуску додатка." + +#: src/slic3r/GUI/Preferences.cpp:136 msgid "Suppress \" - default - \" presets" msgstr "Заборонити налаштування \"- за замовчуванням -\"" -#: src/slic3r/GUI/Preferences.cpp:76 +#: src/slic3r/GUI/Preferences.cpp:138 msgid "" "Suppress \" - default - \" presets in the Print / Filament / Printer " "selections once there are any other valid presets available." @@ -2724,806 +6203,1205 @@ msgstr "" "Заборонити налаштування \"- за замовчуванням -\" у параметрах Друк / " "Філамент / Принтер, якщо доступні інші діючі налаштування." -#: src/slic3r/GUI/Preferences.cpp:82 +#: src/slic3r/GUI/Preferences.cpp:144 msgid "Show incompatible print and filament presets" msgstr "Показувати несумісні налаштування друку та філаменту" -#: src/slic3r/GUI/Preferences.cpp:84 +#: src/slic3r/GUI/Preferences.cpp:146 msgid "" "When checked, the print and filament presets are shown in the preset editor " "even if they are marked as incompatible with the active printer" msgstr "" -"Якщо вибрано, налаштування друку та філаменту відображаються у списку " -"налаштувань, навіть якщо вони позначені як несумісні з активним принтером" +"Якщо вибрано, пресети для друку та філаменту відображаються у списку " +"пресетів, навіть якщо вони позначені як несумісні з активним принтером" -#: src/slic3r/GUI/Preferences.cpp:91 -msgid "Use legacy OpenGL 1.1 rendering" -msgstr "Використовувати застарілий OpenGL 1.1 рендеринг" +#: src/slic3r/GUI/Preferences.cpp:152 +msgid "Show drop project dialog" +msgstr "Показати діалогове вікно при перетягуванні проекту" -#: src/slic3r/GUI/Preferences.cpp:93 +#: src/slic3r/GUI/Preferences.cpp:154 msgid "" -"If you have rendering issues caused by a buggy OpenGL 2.0 driver, you may " -"try to check this checkbox. This will disable the layer height editing and " -"anti aliasing, so it is likely better to upgrade your graphics driver." +"When checked, whenever dragging and dropping a project file on the " +"application, shows a dialog asking to select the action to take on the file " +"to load." msgstr "" -"Якщо у вас виникають проблеми з візуалізацією, спричинені помилковим " -"драйвером OpenGL 2.0, спробуйте вибрати цю опцію. Це призведе до вимкнення " -"редагування висоти шару та згладжування, тому краще оновити графічний " -"драйвер." +"Якщо вибрано, при перетягуванні файлу проекту у програмі відображається " +"діалогове вікно із запитом вибрати дію щодо файлу, який потрібно завантажити." -#: src/slic3r/GUI/Preferences.cpp:101 +#: src/slic3r/GUI/Preferences.cpp:161 src/slic3r/GUI/Preferences.cpp:165 +msgid "Allow just a single PrusaSlicer instance" +msgstr "Дозволити лише один екземпляр PrusaSlicer" + +#: src/slic3r/GUI/Preferences.cpp:163 +msgid "" +"On OSX there is always only one instance of app running by default. However " +"it is allowed to run multiple instances of same app from the command line. " +"In such case this settings will allow only one instance." +msgstr "" +"На OSX завжди є лише один екземпляр програми, який працює за замовчуванням. " +"Однак дозволяється запускати кілька екземплярів одного додатка з командного " +"рядка. У такому випадку ці налаштування дозволять лише один екземпляр." + +#: src/slic3r/GUI/Preferences.cpp:167 +msgid "" +"If this is enabled, when starting PrusaSlicer and another instance of the " +"same PrusaSlicer is already running, that instance will be reactivated " +"instead." +msgstr "" +"Якщо увімкнено, то під час запуску нового екземпляра PrusaSlicer при " +"наявності вже запущеного того самого PrusaSlicer, буде тільки повторно " +"активовано старий екземпляр." + +#: src/slic3r/GUI/Preferences.cpp:173 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:671 +msgid "Ask for unsaved changes when closing application" +msgstr "Питати про незбережені зміни при закритті програми" + +#: src/slic3r/GUI/Preferences.cpp:175 +msgid "When closing the application, always ask for unsaved changes" +msgstr "Завжди питати про незбережені зміни при закритті програми" + +#: src/slic3r/GUI/Preferences.cpp:180 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:672 +msgid "Ask for unsaved changes when selecting new preset" +msgstr "Питати про незбережені зміни при виборі нового пресету" + +#: src/slic3r/GUI/Preferences.cpp:182 +msgid "Always ask for unsaved changes when selecting new preset" +msgstr "Завжди запитуйте про незбережені зміни при виборі нового пресету" + +#: src/slic3r/GUI/Preferences.cpp:190 +msgid "Associate .gcode files to PrusaSlicer G-code Viewer" +msgstr "Зв’язати gcode-файли з PrusaSlicer Переглядачем G-коду" + +#: src/slic3r/GUI/Preferences.cpp:192 +msgid "" +"If enabled, sets PrusaSlicer G-code Viewer as default application to open ." +"gcode files." +msgstr "" +"Якщо увімкнено, встановлює \"PrusaSlicer Переглядач G-коду\" як програму за " +"замовчуванням для відкриття GCODE-файлів." + +#: src/slic3r/GUI/Preferences.cpp:201 msgid "Use Retina resolution for the 3D scene" -msgstr "" +msgstr "Використовувати роздільну здатність Retina для 3D сцени" -#: src/slic3r/GUI/Preferences.cpp:103 +#: src/slic3r/GUI/Preferences.cpp:203 msgid "" "If enabled, the 3D scene will be rendered in Retina resolution. If you are " "experiencing 3D performance problems, disabling this option may help." msgstr "" +"Якщо увімкнено, 3D-сцена відображатиметься з роздільною здатністю Retina. " +"Якщо у вас виникають проблеми з продуктивністю 3D, вимкнення цієї опції може " +"допомогти." -#: src/slic3r/GUI/Preferences.cpp:126 -msgid "You need to restart Slic3r to make the changes effective." -msgstr "З метою ефективності зміни, Вам потрібно буде перезапустити Slic3r." +#: src/slic3r/GUI/Preferences.cpp:211 src/slic3r/GUI/Preferences.cpp:213 +msgid "Show splash screen" +msgstr "Показувати заставку" -#: src/slic3r/GUI/Preset.cpp:207 -msgid "modified" -msgstr "модифікований" +#: src/slic3r/GUI/Preferences.cpp:220 +msgid "Enable support for legacy 3DConnexion devices" +msgstr "Увімкнути підтримку застарілих пристроїв 3DConnexion" -#: src/slic3r/GUI/Preset.cpp:918 src/slic3r/GUI/Preset.cpp:958 -#: src/slic3r/GUI/Preset.cpp:1011 src/slic3r/GUI/Preset.cpp:1043 -#: src/slic3r/GUI/PresetBundle.cpp:1484 src/slic3r/GUI/PresetBundle.cpp:1537 +#: src/slic3r/GUI/Preferences.cpp:222 +msgid "" +"If enabled, the legacy 3DConnexion devices settings dialog is available by " +"pressing CTRL+M" +msgstr "" +"Якщо увімкнено, діалогове вікно налаштувань пристроїв 3DConnexion доступне, " +"натиснувши CTRL+M" + +#: src/slic3r/GUI/Preferences.cpp:232 +msgid "Camera" +msgstr "Камера" + +#: src/slic3r/GUI/Preferences.cpp:237 +msgid "Use perspective camera" +msgstr "Використовувати перспективну камеру" + +#: src/slic3r/GUI/Preferences.cpp:239 +msgid "" +"If enabled, use perspective camera. If not enabled, use orthographic camera." +msgstr "" +"Якщо увімкнено, використовуватиметься перспективна камера. Якщо вимкнено, " +"використовуватиметься ортографічна камера." + +#: src/slic3r/GUI/Preferences.cpp:244 +msgid "Use free camera" +msgstr "Використовувати вільну камеру" + +#: src/slic3r/GUI/Preferences.cpp:246 +msgid "If enabled, use free camera. If not enabled, use constrained camera." +msgstr "" +"Якщо увімкнено, використовуватиметься вільна камера. Якщо вимкнено, " +"використовуватиметься камера з обмеженими можливостями." + +#: src/slic3r/GUI/Preferences.cpp:251 +msgid "Reverse direction of zoom with mouse wheel" +msgstr "Зворотний напрямок масштабування за допомогою колеса миші" + +#: src/slic3r/GUI/Preferences.cpp:253 +msgid "If enabled, reverses the direction of zoom with mouse wheel" +msgstr "Якщо увімкнено, змінює напрямок масштабування за допомогою колеса миші" + +#: src/slic3r/GUI/Preferences.cpp:261 +msgid "GUI" +msgstr "Графічний інтерфейс" + +#: src/slic3r/GUI/Preferences.cpp:276 +msgid "Sequential slider applied only to top layer" +msgstr "Послідовний повзунок застосовується лише до верхнього шару" + +#: src/slic3r/GUI/Preferences.cpp:278 +msgid "" +"If enabled, changes made using the sequential slider, in preview, apply only " +"to gcode top layer. If disabled, changes made using the sequential slider, " +"in preview, apply to the whole gcode." +msgstr "" +"Якщо увімкнено, зміни, внесені за допомогою послідовного повзунка, у " +"попередньому перегляді застосовуються лише до верхнього шару G-коду. Якщо " +"вимкнено, зміни, внесені за допомогою послідовного повзунка, у попередньому " +"перегляді застосовуються до цілого G-коду." + +#: src/slic3r/GUI/Preferences.cpp:285 +msgid "Show sidebar collapse/expand button" +msgstr "Показувати кнопку згортання/розгортання бічної панелі" + +#: src/slic3r/GUI/Preferences.cpp:287 +msgid "" +"If enabled, the button for the collapse sidebar will be appeared in top " +"right corner of the 3D Scene" +msgstr "" +"Якщо увімкнено, у верхньому правому куті 3D-сцени з’явиться кнопка згортання " +"бічної панелі" + +#: src/slic3r/GUI/Preferences.cpp:292 +msgid "Suppress to open hyperlink in browser" +msgstr "Заборонити відкриття гіперпосилань у браузері" + +#: src/slic3r/GUI/Preferences.cpp:294 +msgid "" +"If enabled, the descriptions of configuration parameters in settings tabs " +"wouldn't work as hyperlinks. If disabled, the descriptions of configuration " +"parameters in settings tabs will work as hyperlinks." +msgstr "" +"Якщо увімкнено, описи параметрів конфігурації на вкладках параметрів не " +"працюватимуть як гіперпосилання. Якщо вимкнено, описи параметрів " +"конфігурації на вкладках параметрів працюватимуть як гіперпосилання." + +#: src/slic3r/GUI/Preferences.cpp:300 +msgid "Use custom size for toolbar icons" +msgstr "" +"Використовуйте користувацький розмір для піктограм на панелі інструментів" + +#: src/slic3r/GUI/Preferences.cpp:302 +msgid "If enabled, you can change size of toolbar icons manually." +msgstr "" +"Якщо увімкнено, ви можете змінювати розмір піктограм на панелі інструментів " +"вручну." + +#: src/slic3r/GUI/Preferences.cpp:320 +msgid "Render" +msgstr "Візуалізувати" + +#: src/slic3r/GUI/Preferences.cpp:325 +msgid "Use environment map" +msgstr "Використовуйте карту середовища" + +#: src/slic3r/GUI/Preferences.cpp:327 +msgid "If enabled, renders object using the environment map." +msgstr "Якщо увімкнено, візуалізує об’єкт за допомогою карти середовища." + +#: src/slic3r/GUI/Preferences.cpp:352 +#, c-format +msgid "You need to restart %s to make the changes effective." +msgstr "З метою ефективності зміни, Вам потрібно буде перезапустити %s." + +#: src/slic3r/GUI/Preferences.cpp:427 +msgid "Icon size in a respect to the default size" +msgstr "Розмір піктограми відносно розміру за промовчанням" + +#: src/slic3r/GUI/Preferences.cpp:442 +msgid "Select toolbar icon size in respect to the default one." +msgstr "" +"Виберіть розмір піктограми панелі інструментів щодо розміру за замовчуванням." + +#: src/slic3r/GUI/Preferences.cpp:473 +msgid "Old regular layout with the tab bar" +msgstr "Старий звичайний макет із панеллю вкладок" + +#: src/slic3r/GUI/Preferences.cpp:474 +msgid "New layout, access via settings button in the top menu" +msgstr "Нове розташування, доступ через кнопку налаштувань у верхньому меню" + +#: src/slic3r/GUI/Preferences.cpp:475 +msgid "Settings in non-modal window" +msgstr "Налаштування у немодальному вікні" + +#: src/slic3r/GUI/Preferences.cpp:484 +msgid "Layout Options" +msgstr "Параметри розташування" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:197 +#: src/slic3r/GUI/PresetComboBoxes.cpp:235 +#: src/slic3r/GUI/PresetComboBoxes.cpp:761 +#: src/slic3r/GUI/PresetComboBoxes.cpp:811 +#: src/slic3r/GUI/PresetComboBoxes.cpp:925 +#: src/slic3r/GUI/PresetComboBoxes.cpp:969 msgid "System presets" msgstr "Системні налаштування" -#: src/slic3r/GUI/Preset.cpp:962 src/slic3r/GUI/Preset.cpp:1047 -#: src/slic3r/GUI/PresetBundle.cpp:1542 +#: src/slic3r/GUI/PresetComboBoxes.cpp:239 +#: src/slic3r/GUI/PresetComboBoxes.cpp:815 +#: src/slic3r/GUI/PresetComboBoxes.cpp:973 msgid "User presets" msgstr "Налаштування користувача" -#: src/slic3r/GUI/Preset.cpp:991 src/slic3r/GUI/Tab.cpp:247 -msgid "Add a new printer" -msgstr "" +#: src/slic3r/GUI/PresetComboBoxes.cpp:250 +msgid "Incompatible presets" +msgstr "Несумісні пресети" -#: src/slic3r/GUI/Preset.cpp:1251 -msgid "filament" -msgstr "" +#: src/slic3r/GUI/PresetComboBoxes.cpp:285 +msgid "Are you sure you want to delete \"%1%\" printer?" +msgstr "Ви впевнені, що хочете видалити принтер \"%1%\"?" -#: src/slic3r/GUI/PresetHints.cpp:28 -#, c-format -msgid "" -"If estimated layer time is below ~%ds, fan will run at %d%% and print speed " -"will be reduced so that no less than %ds are spent on that layer (however, " -"speed will never be reduced below %dmm/s)." -msgstr "" -"Якщо запланований час друку шару нижче ~%dс, вентилятор буде працювати на%d" -"%%, і швидкість друку буде зменшена, так що на цей шар витрачається не менше " -"%dс (однак швидкість ніколи не зменшиться нижче %d mm/s) ." +#: src/slic3r/GUI/PresetComboBoxes.cpp:287 +msgid "Delete Physical Printer" +msgstr "Видалити фізичний принтер" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:624 +msgid "Click to edit preset" +msgstr "Клацніть, щоб змінити пресет" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:680 +#: src/slic3r/GUI/PresetComboBoxes.cpp:710 +msgid "Add/Remove presets" +msgstr "Додати/Видалити пресети" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:685 +#: src/slic3r/GUI/PresetComboBoxes.cpp:715 src/slic3r/GUI/Tab.cpp:2990 +msgid "Add physical printer" +msgstr "Додати фізичний принтер" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:699 +msgid "Edit preset" +msgstr "Редагувати пресет" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:703 src/slic3r/GUI/Tab.cpp:2990 +msgid "Edit physical printer" +msgstr "Редагувати фізичний принтер" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:706 +msgid "Delete physical printer" +msgstr "Видалити фізичний принтер" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:826 +#: src/slic3r/GUI/PresetComboBoxes.cpp:987 +msgid "Physical printers" +msgstr "Фізичний принтер" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:850 +msgid "Add/Remove filaments" +msgstr "Додати/Видалити філаменти" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:852 +msgid "Add/Remove materials" +msgstr "Додати/Видалити матеріали" + +#: src/slic3r/GUI/PresetComboBoxes.cpp:854 +#: src/slic3r/GUI/PresetComboBoxes.cpp:1011 +msgid "Add/Remove printers" +msgstr "Додати/Видалити прінтери" #: src/slic3r/GUI/PresetHints.cpp:32 -#, c-format msgid "" -"\n" -"If estimated layer time is greater, but still below ~%ds, fan will run at a " -"proportionally decreasing speed between %d%% and %d%%." +"If estimated layer time is below ~%1%s, fan will run at %2%%% and print " +"speed will be reduced so that no less than %3%s are spent on that layer " +"(however, speed will never be reduced below %4%mm/s)." msgstr "" -"\n" -"Якщо запланований час друку шару більше, але все ще нижче ~%dс, вентилятор " -"буде працювати з пропорційно зменшуваною швидкістю між %d%% та %d%%." +"Якщо передбачуваний час шару менше ~%1%s, вентилятор працюватиме на %2%%% і " +"швидкість друку буде зменшена, так що на цей шар буде витрачено не менше " +"%3%s (однак швидкість ніколи не зменшиться нижче %4%мм/с)." -#: src/slic3r/GUI/PresetHints.cpp:36 +#: src/slic3r/GUI/PresetHints.cpp:39 msgid "" -"\n" -"During the other layers, fan " +"If estimated layer time is greater, but still below ~%1%s, fan will run at a " +"proportionally decreasing speed between %2%%% and %3%%%." msgstr "" -"\n" -"Під час друку інших шарів вентилятор " +"Якщо передбачуваний час шару більше, але все ще менше ~%1%s, вентилятор " +"працюватиме із пропорційно зменшуваною швидкістю між %2%%% і %3%%%." -#: src/slic3r/GUI/PresetHints.cpp:38 -msgid "Fan " -msgstr "Вентилятор " +#: src/slic3r/GUI/PresetHints.cpp:49 +msgid "Fan speed will be ramped from zero at layer %1% to %2%%% at layer %3%." +msgstr "" +"Швидкість вентилятора буде збільшена з нуля на шарі %1% до %2%%% на шарі %3%." -#: src/slic3r/GUI/PresetHints.cpp:43 -#, c-format -msgid "will always run at %d%% " -msgstr "буде завжди працювати на %d%% " +#: src/slic3r/GUI/PresetHints.cpp:51 +msgid "During the other layers, fan will always run at %1%%%" +msgstr "Під час інших шарів вентилятор завжди працюватиме на %1%%%" -#: src/slic3r/GUI/PresetHints.cpp:46 -#, c-format -msgid "except for the first %d layers" -msgstr "за винятком перших %d шарів" +#: src/slic3r/GUI/PresetHints.cpp:51 +msgid "Fan will always run at %1%%%" +msgstr "Вентилятор завжди працюватиме на %1%%%" -#: src/slic3r/GUI/PresetHints.cpp:50 -msgid "except for the first layer" -msgstr "за винятком першого шару" +#: src/slic3r/GUI/PresetHints.cpp:53 +msgid "except for the first %1% layers." +msgstr "за винятком перших %1% шарів." -#: src/slic3r/GUI/PresetHints.cpp:52 -msgid "will be turned off." -msgstr "буде вимкнено." +#: src/slic3r/GUI/PresetHints.cpp:55 +msgid "except for the first layer." +msgstr "за винятком першого шару." -#: src/slic3r/GUI/PresetHints.cpp:153 +#: src/slic3r/GUI/PresetHints.cpp:58 +msgid "During the other layers, fan will be turned off." +msgstr "Під час інших шарів вентилятор буде вимкнено." + +#: src/slic3r/GUI/PresetHints.cpp:58 +msgid "Fan will be turned off." +msgstr "Вентилятор буде вимкнено." + +#: src/slic3r/GUI/PresetHints.cpp:159 msgid "external perimeters" msgstr "зовнішні периметри" -#: src/slic3r/GUI/PresetHints.cpp:162 +#: src/slic3r/GUI/PresetHints.cpp:168 msgid "perimeters" msgstr "периметри" -#: src/slic3r/GUI/PresetHints.cpp:171 +#: src/slic3r/GUI/PresetHints.cpp:177 msgid "infill" msgstr "наповнення" -#: src/slic3r/GUI/PresetHints.cpp:181 +#: src/slic3r/GUI/PresetHints.cpp:187 msgid "solid infill" msgstr "суцільне наповнення" -#: src/slic3r/GUI/PresetHints.cpp:189 +#: src/slic3r/GUI/PresetHints.cpp:195 msgid "top solid infill" msgstr "верхній суцільне наповнення" -#: src/slic3r/GUI/PresetHints.cpp:200 +#: src/slic3r/GUI/PresetHints.cpp:206 msgid "support" msgstr "підтримка" -#: src/slic3r/GUI/PresetHints.cpp:210 +#: src/slic3r/GUI/PresetHints.cpp:216 msgid "support interface" msgstr "інтерфейс підтримки" -#: src/slic3r/GUI/PresetHints.cpp:216 +#: src/slic3r/GUI/PresetHints.cpp:222 msgid "First layer volumetric" msgstr "Об'єм першого шару" -#: src/slic3r/GUI/PresetHints.cpp:216 +#: src/slic3r/GUI/PresetHints.cpp:222 msgid "Bridging volumetric" msgstr "Об'єм мостів" -#: src/slic3r/GUI/PresetHints.cpp:216 +#: src/slic3r/GUI/PresetHints.cpp:222 msgid "Volumetric" msgstr "Об'ємний" -#: src/slic3r/GUI/PresetHints.cpp:217 -msgid " flow rate is maximized " -msgstr " швидкість потоку максимізується " +#: src/slic3r/GUI/PresetHints.cpp:223 +msgid "flow rate is maximized" +msgstr "швидкість потоку максимізується" -#: src/slic3r/GUI/PresetHints.cpp:220 +#: src/slic3r/GUI/PresetHints.cpp:226 msgid "by the print profile maximum" msgstr "за профілем друку максимум" -#: src/slic3r/GUI/PresetHints.cpp:221 -msgid "when printing " -msgstr "коли друкуємо " - -#: src/slic3r/GUI/PresetHints.cpp:222 -msgid " with a volumetric rate " -msgstr " з об'ємною швидкістю " - -#: src/slic3r/GUI/PresetHints.cpp:226 -#, c-format -msgid "%3.2f mm³/s" -msgstr "%3.2f мм³/с" +#: src/slic3r/GUI/PresetHints.cpp:227 +msgid "when printing" +msgstr "коли друкуємо" #: src/slic3r/GUI/PresetHints.cpp:228 -#, c-format -msgid " at filament speed %3.2f mm/s." -msgstr " при швидкості філаменту %3.2f мм/с." +msgid "with a volumetric rate" +msgstr "з об'ємною швидкістю" -#: src/slic3r/GUI/PresetHints.cpp:247 +#: src/slic3r/GUI/PresetHints.cpp:232 +#, c-format +msgid "%3.2f mm³/s at filament speed %3.2f mm/s." +msgstr "%3.2f мм³/с при швидкості філаменту %3.2f мм/с." + +#: src/slic3r/GUI/PresetHints.cpp:250 msgid "" "Recommended object thin wall thickness: Not available due to invalid layer " "height." msgstr "" -"Рекомендований об'єкт товщиною тонкої стінки: Недоступний через невірне " -"значення висоти шару." +"Рекомендована товщина стінки об'єкту: Недоступний через невірне значення " +"висоти шару." -#: src/slic3r/GUI/PresetHints.cpp:264 +#: src/slic3r/GUI/PresetHints.cpp:266 #, c-format -msgid "Recommended object thin wall thickness for layer height %.2f and " -msgstr "Рекомендована товщина стінки для висоти шару %.2f та " +msgid "Recommended object thin wall thickness for layer height %.2f and" +msgstr "Рекомендована товщина стінки об'єкту для висоти шару %.2f та" -#: src/slic3r/GUI/PresetHints.cpp:271 +#: src/slic3r/GUI/PresetHints.cpp:273 #, c-format -msgid "%d lines: %.2lf mm" -msgstr "%d рядків: %.2lf мм" +msgid "%d lines: %.2f mm" +msgstr "%d рядків: %.2f мм" -#: src/slic3r/GUI/PrintHostDialogs.cpp:32 +#: src/slic3r/GUI/PresetHints.cpp:277 +msgid "" +"Recommended object thin wall thickness: Not available due to excessively " +"small extrusion width." +msgstr "" +"Рекомендована товщина стінки об'єкту: Недоступний через надмірно малу ширину " +"екструзії." + +#: src/slic3r/GUI/PresetHints.cpp:306 +msgid "" +"Top / bottom shell thickness hint: Not available due to invalid layer height." +msgstr "" +"Підказка щодо товщини верхньої/нижньої оболонки: Недоступна через " +"неправильну висоту шару." + +#: src/slic3r/GUI/PresetHints.cpp:319 +msgid "Top shell is %1% mm thick for layer height %2% mm." +msgstr "Верхня оболонка має товщину %1% мм для висоти шару %2% мм." + +#: src/slic3r/GUI/PresetHints.cpp:322 +msgid "Minimum top shell thickness is %1% mm." +msgstr "Мінімальна товщина верхньої оболонки становить %1% мм." + +#: src/slic3r/GUI/PresetHints.cpp:325 +msgid "Top is open." +msgstr "Верх відкритий." + +#: src/slic3r/GUI/PresetHints.cpp:338 +msgid "Bottom shell is %1% mm thick for layer height %2% mm." +msgstr "Нижня оболонка має товщину %1% мм для висоти шару %2% мм." + +#: src/slic3r/GUI/PresetHints.cpp:341 +msgid "Minimum bottom shell thickness is %1% mm." +msgstr "Мінімальна товщина нижньої оболонки становить %1% мм." + +#: src/slic3r/GUI/PresetHints.cpp:344 +msgid "Bottom is open." +msgstr "Внизу відкрито." + +#: src/slic3r/GUI/PrintHostDialogs.cpp:35 msgid "Send G-Code to printer host" -msgstr "" +msgstr "Надіслання G-коду на хост друку" -#: src/slic3r/GUI/PrintHostDialogs.cpp:32 +#: src/slic3r/GUI/PrintHostDialogs.cpp:35 msgid "Upload to Printer Host with the following filename:" -msgstr "" +msgstr "Завантажити на хост принтера з таким ім’ям файлу:" -#: src/slic3r/GUI/PrintHostDialogs.cpp:34 +#: src/slic3r/GUI/PrintHostDialogs.cpp:37 msgid "Start printing after upload" -msgstr "" +msgstr "Почати друк після заведення" -#: src/slic3r/GUI/PrintHostDialogs.cpp:41 +#: src/slic3r/GUI/PrintHostDialogs.cpp:45 msgid "Use forward slashes ( / ) as a directory separator if needed." -msgstr "" +msgstr "За потреби використовуйте скісні риски (/) як роздільник каталогів." -#: src/slic3r/GUI/PrintHostDialogs.cpp:157 +#: src/slic3r/GUI/PrintHostDialogs.cpp:58 +msgid "Group" +msgstr "Group" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:176 +msgid "ID" +msgstr "ID" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:177 +msgid "Progress" +msgstr "Прогрес" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:178 +msgid "Status" +msgstr "Статус" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:179 +msgid "Host" +msgstr "Хост" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:180 +msgid "Filename" +msgstr "Ім'я файлу" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:181 +msgid "Error Message" +msgstr "Повідомлення про помилку" + +#: src/slic3r/GUI/PrintHostDialogs.cpp:184 msgid "Cancel selected" -msgstr "" +msgstr "Скасувати вибране" -#: src/slic3r/GUI/PrintHostDialogs.cpp:159 +#: src/slic3r/GUI/PrintHostDialogs.cpp:186 msgid "Show error message" -msgstr "" +msgstr "Показати повідомлення про помилку" -#: src/slic3r/GUI/PrintHostDialogs.cpp:198 -#: src/slic3r/GUI/PrintHostDialogs.cpp:217 +#: src/slic3r/GUI/PrintHostDialogs.cpp:228 +#: src/slic3r/GUI/PrintHostDialogs.cpp:261 msgid "Enqueued" -msgstr "" +msgstr "У черзі" -#: src/slic3r/GUI/PrintHostDialogs.cpp:218 +#: src/slic3r/GUI/PrintHostDialogs.cpp:262 msgid "Uploading" -msgstr "" +msgstr "Завантаження" -#: src/slic3r/GUI/PrintHostDialogs.cpp:222 +#: src/slic3r/GUI/PrintHostDialogs.cpp:266 msgid "Completed" -msgstr "" +msgstr "Завершено" -#: src/slic3r/GUI/PrintHostDialogs.cpp:260 +#: src/slic3r/GUI/PrintHostDialogs.cpp:304 msgid "Error uploading to print host:" -msgstr "" +msgstr "Помилка завантаження на хост друку:" #: src/slic3r/GUI/RammingChart.cpp:23 msgid "NO RAMMING AT ALL" -msgstr "" +msgstr "ВЗАГАЛІ БЕЗ раммінгу" -#: src/slic3r/GUI/RammingChart.cpp:76 -msgid "Time" -msgstr "" - -#: src/slic3r/GUI/RammingChart.cpp:76 src/slic3r/GUI/RammingChart.cpp:81 -#: src/slic3r/GUI/WipeTowerDialog.cpp:82 src/libslic3r/PrintConfig.cpp:611 -#: src/libslic3r/PrintConfig.cpp:655 src/libslic3r/PrintConfig.cpp:670 -#: src/libslic3r/PrintConfig.cpp:2241 src/libslic3r/PrintConfig.cpp:2250 -#: src/libslic3r/PrintConfig.cpp:2308 src/libslic3r/PrintConfig.cpp:2315 +#: src/slic3r/GUI/RammingChart.cpp:76 src/slic3r/GUI/WipeTowerDialog.cpp:83 +#: src/libslic3r/PrintConfig.cpp:706 src/libslic3r/PrintConfig.cpp:750 +#: src/libslic3r/PrintConfig.cpp:765 src/libslic3r/PrintConfig.cpp:2636 +#: src/libslic3r/PrintConfig.cpp:2645 src/libslic3r/PrintConfig.cpp:2755 +#: src/libslic3r/PrintConfig.cpp:2763 src/libslic3r/PrintConfig.cpp:2771 +#: src/libslic3r/PrintConfig.cpp:2778 src/libslic3r/PrintConfig.cpp:2786 +#: src/libslic3r/PrintConfig.cpp:2794 msgid "s" -msgstr "" +msgstr "с" #: src/slic3r/GUI/RammingChart.cpp:81 msgid "Volumetric speed" -msgstr "" +msgstr "Об'ємна швидкість" -#: src/slic3r/GUI/SysInfoDialog.cpp:44 -msgid "Slic3r Prusa Edition - System Information" -msgstr "" +#: src/slic3r/GUI/RammingChart.cpp:81 src/libslic3r/PrintConfig.cpp:663 +#: src/libslic3r/PrintConfig.cpp:1458 +msgid "mm³/s" +msgstr "мм³/с" -#: src/slic3r/GUI/Tab.cpp:50 src/libslic3r/PrintConfig.cpp:228 +#: src/slic3r/GUI/SavePresetDialog.cpp:57 +#, c-format +msgid "Save %s as:" +msgstr "Зберегти %s як:" + +#: src/slic3r/GUI/SavePresetDialog.cpp:110 +msgid "the following suffix is not allowed:" +msgstr "такий суфікс не допускається:" + +#: src/slic3r/GUI/SavePresetDialog.cpp:116 +msgid "The supplied name is not available." +msgstr "Надане ім'я недоступне." + +#: src/slic3r/GUI/SavePresetDialog.cpp:122 +msgid "Cannot overwrite a system profile." +msgstr "Неможливо замінити системний профіль." + +#: src/slic3r/GUI/SavePresetDialog.cpp:127 +msgid "Cannot overwrite an external profile." +msgstr "Неможливо замінити сторонній профіль." + +#: src/slic3r/GUI/SavePresetDialog.cpp:134 +msgid "Preset with name \"%1%\" already exists." +msgstr "Пресет з ім'ям \"%1%\" вже існує." + +#: src/slic3r/GUI/SavePresetDialog.cpp:136 +msgid "" +"Preset with name \"%1%\" already exists and is incompatible with selected " +"printer." +msgstr "Пресет з ім'ям \"%1%\" вже існує і несумісний з вибраним принтером." + +#: src/slic3r/GUI/SavePresetDialog.cpp:137 +msgid "Note: This preset will be replaced after saving" +msgstr "Примітка: Цей пресет буде замінено після збереження" + +#: src/slic3r/GUI/SavePresetDialog.cpp:142 +msgid "The name cannot be empty." +msgstr "Ім'я не може бути порожнім." + +#: src/slic3r/GUI/SavePresetDialog.cpp:147 +msgid "The name cannot start with space character." +msgstr "Ім'я не може починатися з пробілу." + +#: src/slic3r/GUI/SavePresetDialog.cpp:152 +msgid "The name cannot end with space character." +msgstr "Ім'я не може закінчуватися пробілом." + +#: src/slic3r/GUI/SavePresetDialog.cpp:186 +#: src/slic3r/GUI/SavePresetDialog.cpp:192 +msgid "Save preset" +msgstr "Зберегти налаштування" + +#: src/slic3r/GUI/SavePresetDialog.cpp:215 +msgctxt "PresetName" +msgid "Copy" +msgstr "Копія" + +#: src/slic3r/GUI/SavePresetDialog.cpp:273 +msgid "" +"You have selected physical printer \"%1%\" \n" +"with related printer preset \"%2%\"" +msgstr "" +"Ви вибрали фізичний принтер \"%1%\"\n" +"із пов'язаним пресетом \"%2%\"" + +#: src/slic3r/GUI/SavePresetDialog.cpp:306 +msgid "What would you like to do with \"%1%\" preset after saving?" +msgstr "Що ви хочете зробити із пресетом \"%1%\" після збереження?" + +#: src/slic3r/GUI/SavePresetDialog.cpp:309 +msgid "Change \"%1%\" to \"%2%\" for this physical printer \"%3%\"" +msgstr "Для цього фізичного принтера \"%3%\" змінити \"%1%\" на \"%2%\"" + +#: src/slic3r/GUI/SavePresetDialog.cpp:310 +msgid "Add \"%1%\" as a next preset for the the physical printer \"%2%\"" +msgstr "Додати \"%1%\" як наступний пресет для фізичного принтера \"%2%\"" + +#: src/slic3r/GUI/SavePresetDialog.cpp:311 +msgid "Just switch to \"%1%\" preset" +msgstr "Просто переключитися до пресету \"%1%\"" + +#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2421 +msgid "Stealth" +msgstr "Тихий" + +#: src/slic3r/GUI/Search.cpp:77 src/slic3r/GUI/Tab.cpp:2415 +msgid "Normal" +msgstr "Нормальний" + +#: src/slic3r/GUI/Selection.cpp:172 +msgid "Selection-Add" +msgstr "Виділення - Додано" + +#: src/slic3r/GUI/Selection.cpp:213 +msgid "Selection-Remove" +msgstr "Виділення - Видалено" + +#: src/slic3r/GUI/Selection.cpp:245 +msgid "Selection-Add Object" +msgstr "Виділення - Додано об'єкт" + +#: src/slic3r/GUI/Selection.cpp:264 +msgid "Selection-Remove Object" +msgstr "Виділення - Видалено об'єкт" + +#: src/slic3r/GUI/Selection.cpp:282 +msgid "Selection-Add Instance" +msgstr "Виділення - Додано екземпляр" + +#: src/slic3r/GUI/Selection.cpp:301 +msgid "Selection-Remove Instance" +msgstr "Виділення - Видалено екземпляр" + +#: src/slic3r/GUI/Selection.cpp:402 +msgid "Selection-Add All" +msgstr "Виділення - Додано все" + +#: src/slic3r/GUI/Selection.cpp:428 +msgid "Selection-Remove All" +msgstr "Виділення - Видалено все" + +#: src/slic3r/GUI/Selection.cpp:960 +msgid "Scale To Fit" +msgstr "Масштабувати під область друку" + +#: src/slic3r/GUI/Selection.cpp:1487 +msgid "Set Printable Instance" +msgstr "Встановити екземпляр \"Для друку\"" + +#: src/slic3r/GUI/Selection.cpp:1487 +msgid "Set Unprintable Instance" +msgstr "Встановити екземпляр \"Не для друку\"" + +#: src/slic3r/GUI/SysInfoDialog.cpp:82 +msgid "System Information" +msgstr "Інформація про систему" + +#: src/slic3r/GUI/SysInfoDialog.cpp:158 +msgid "Copy to Clipboard" +msgstr "Скопіювати в буфер обміну" + +#: src/slic3r/GUI/Tab.cpp:109 src/libslic3r/PrintConfig.cpp:321 msgid "Compatible printers" msgstr "Сумісні принтери" -#: src/slic3r/GUI/Tab.cpp:51 +#: src/slic3r/GUI/Tab.cpp:110 msgid "Select the printers this profile is compatible with." msgstr "Оберіть принтери, сумісні з цим профілем." -#: src/slic3r/GUI/Tab.cpp:56 src/libslic3r/PrintConfig.cpp:243 +#: src/slic3r/GUI/Tab.cpp:115 src/libslic3r/PrintConfig.cpp:336 msgid "Compatible print profiles" -msgstr "" +msgstr "Сумісні пресети друку" -#: src/slic3r/GUI/Tab.cpp:57 +#: src/slic3r/GUI/Tab.cpp:116 msgid "Select the print profiles this profile is compatible with." -msgstr "" +msgstr "Оберіть профілі друку, з якими цей профіль сумісний." -#: src/slic3r/GUI/Tab.cpp:132 -msgid "Save current " -msgstr "Зберегти поточний " +#. TRN "Save current Settings" +#: src/slic3r/GUI/Tab.cpp:211 +#, c-format +msgid "Save current %s" +msgstr "Зберегти поточний %s" -#: src/slic3r/GUI/Tab.cpp:133 +#: src/slic3r/GUI/Tab.cpp:212 msgid "Delete this preset" msgstr "Видалити це налаштування" -#: src/slic3r/GUI/Tab.cpp:145 +#: src/slic3r/GUI/Tab.cpp:216 msgid "" "Hover the cursor over buttons to find more information \n" "or click this button." msgstr "" +"Наведіть курсор на кнопки, щоб знайти додаткову інформацію\n" +"або натисніть цю кнопку." -#: src/slic3r/GUI/Tab.cpp:858 -msgid "It's a default preset." -msgstr "" +#: src/slic3r/GUI/Tab.cpp:220 +msgid "Search in settings [%1%]" +msgstr "Шукайте в налаштуваннях [%1%]" -#: src/slic3r/GUI/Tab.cpp:859 -msgid "It's a system preset." -msgstr "" +#: src/slic3r/GUI/Tab.cpp:1237 +msgid "Detach from system preset" +msgstr "Від'єднати від системного пресету" -#: src/slic3r/GUI/Tab.cpp:860 -msgid "Current preset is inherited from " -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:865 -msgid "It can't be deleted or modified. " -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:866 +#: src/slic3r/GUI/Tab.cpp:1250 msgid "" -"Any modifications should be saved as a new preset inherited from this one. " +"A copy of the current system preset will be created, which will be detached " +"from the system preset." msgstr "" +"Буде створено копію поточного системного пресету, який буде від'єднано від " +"системного пресету." -#: src/slic3r/GUI/Tab.cpp:867 +#: src/slic3r/GUI/Tab.cpp:1251 +msgid "" +"The current custom preset will be detached from the parent system preset." +msgstr "" +"Поточний власний пресет буде від'єднаний від батьківського системного " +"пресету." + +#: src/slic3r/GUI/Tab.cpp:1254 +msgid "Modifications to the current profile will be saved." +msgstr "Зміни до поточного профілю буде збережено." + +#: src/slic3r/GUI/Tab.cpp:1257 +msgid "" +"This action is not revertable.\n" +"Do you want to proceed?" +msgstr "" +"Цю дію не можна повернути.\n" +"Ви хочете продовжити?" + +#: src/slic3r/GUI/Tab.cpp:1259 +msgid "Detach preset" +msgstr "Від'єднати пресет" + +#: src/slic3r/GUI/Tab.cpp:1285 +msgid "This is a default preset." +msgstr "Цей пресет є пресетом за-замовчуванням." + +#: src/slic3r/GUI/Tab.cpp:1287 +msgid "This is a system preset." +msgstr "Цей пресет є системним пресетом." + +#: src/slic3r/GUI/Tab.cpp:1289 +msgid "Current preset is inherited from the default preset." +msgstr "Поточний пресет успадковується від пресету за замовчуванням." + +#: src/slic3r/GUI/Tab.cpp:1293 +msgid "Current preset is inherited from" +msgstr "Поточний пресет успадковується від" + +#: src/slic3r/GUI/Tab.cpp:1297 +msgid "It can't be deleted or modified." +msgstr "Його не можна видалити або змінити." + +#: src/slic3r/GUI/Tab.cpp:1298 +msgid "" +"Any modifications should be saved as a new preset inherited from this one." +msgstr "" +"Будь-які модифікації слід зберігати як новий пресет, успадкований від цього." + +#: src/slic3r/GUI/Tab.cpp:1299 msgid "To do that please specify a new name for the preset." -msgstr "" +msgstr "Для цього вкажіть нову назву пресету." -#: src/slic3r/GUI/Tab.cpp:871 +#: src/slic3r/GUI/Tab.cpp:1303 msgid "Additional information:" -msgstr "" +msgstr "Додаткова інформація:" -#: src/slic3r/GUI/Tab.cpp:877 +#: src/slic3r/GUI/Tab.cpp:1309 msgid "printer model" -msgstr "" +msgstr "модель принтеру" -#: src/slic3r/GUI/Tab.cpp:885 +#: src/slic3r/GUI/Tab.cpp:1317 msgid "default print profile" -msgstr "" +msgstr "профіль друку за замовчанням" -#: src/slic3r/GUI/Tab.cpp:888 +#: src/slic3r/GUI/Tab.cpp:1320 msgid "default filament profile" -msgstr "" +msgstr "профіль філаметну за замовчанням" -#: src/slic3r/GUI/Tab.cpp:902 +#: src/slic3r/GUI/Tab.cpp:1334 msgid "default SLA material profile" -msgstr "" +msgstr "профіль SLA-матеріалу за замовчанням" -#: src/slic3r/GUI/Tab.cpp:906 +#: src/slic3r/GUI/Tab.cpp:1338 msgid "default SLA print profile" -msgstr "" +msgstr "профіль SLA-друку за замовчанням" -#: src/slic3r/GUI/Tab.cpp:948 src/slic3r/GUI/Tab.cpp:3303 +#: src/slic3r/GUI/Tab.cpp:1346 +msgid "full profile name" +msgstr "повне ім'я профілю" + +#: src/slic3r/GUI/Tab.cpp:1347 +msgid "symbolic profile name" +msgstr "символічне ім'я профілю" + +#: src/slic3r/GUI/Tab.cpp:1385 src/slic3r/GUI/Tab.cpp:4042 msgid "Layers and perimeters" msgstr "Шари та периметри" -#: src/slic3r/GUI/Tab.cpp:949 src/libslic3r/PrintConfig.cpp:55 -msgid "Layer height" -msgstr "Висота шару" - -#: src/slic3r/GUI/Tab.cpp:953 +#: src/slic3r/GUI/Tab.cpp:1391 msgid "Vertical shells" msgstr "Вертикальні оболонки" -#: src/slic3r/GUI/Tab.cpp:964 +#: src/slic3r/GUI/Tab.cpp:1403 msgid "Horizontal shells" msgstr "Горизонтальні оболонки" -#: src/slic3r/GUI/Tab.cpp:965 src/libslic3r/PrintConfig.cpp:1709 +#: src/slic3r/GUI/Tab.cpp:1404 src/libslic3r/PrintConfig.cpp:1980 msgid "Solid layers" msgstr "Суцільні шари" -#: src/slic3r/GUI/Tab.cpp:970 +#: src/slic3r/GUI/Tab.cpp:1409 +msgid "Minimum shell thickness" +msgstr "Мінімальна товщина оболонки" + +#: src/slic3r/GUI/Tab.cpp:1420 msgid "Quality (slower slicing)" msgstr "Якість (повільне нарізання)" -#: src/slic3r/GUI/Tab.cpp:988 +#: src/slic3r/GUI/Tab.cpp:1448 msgid "Reducing printing time" msgstr "Зниження часу друку" -#: src/slic3r/GUI/Tab.cpp:1000 +#: src/slic3r/GUI/Tab.cpp:1460 msgid "Skirt and brim" msgstr "Плінтус та край" -#: src/slic3r/GUI/Tab.cpp:1017 +#: src/slic3r/GUI/Tab.cpp:1480 msgid "Raft" msgstr "Пліт" -#: src/slic3r/GUI/Tab.cpp:1021 +#: src/slic3r/GUI/Tab.cpp:1484 msgid "Options for support material and raft" msgstr "Варіанти для опорного матеріалу та плоту" -#: src/slic3r/GUI/Tab.cpp:1036 +#: src/slic3r/GUI/Tab.cpp:1499 msgid "Speed for print moves" msgstr "Швидкість друкарських рухів" -#: src/slic3r/GUI/Tab.cpp:1048 +#: src/slic3r/GUI/Tab.cpp:1512 msgid "Speed for non-print moves" msgstr "Швидкість недрукарських рухів" -#: src/slic3r/GUI/Tab.cpp:1051 +#: src/slic3r/GUI/Tab.cpp:1515 msgid "Modifiers" msgstr "Модифікатори" -#: src/slic3r/GUI/Tab.cpp:1054 +#: src/slic3r/GUI/Tab.cpp:1518 msgid "Acceleration control (advanced)" msgstr "Контроль прискорення (розширений)" -#: src/slic3r/GUI/Tab.cpp:1061 +#: src/slic3r/GUI/Tab.cpp:1525 msgid "Autospeed (advanced)" msgstr "Автоматична швидкість (розширена)" -#: src/slic3r/GUI/Tab.cpp:1069 +#: src/slic3r/GUI/Tab.cpp:1533 msgid "Multiple Extruders" msgstr "Кілька екструдерів" -#: src/slic3r/GUI/Tab.cpp:1077 +#: src/slic3r/GUI/Tab.cpp:1541 msgid "Ooze prevention" -msgstr "Профілактика просочування" +msgstr "Запобігання просочування" -#: src/slic3r/GUI/Tab.cpp:1094 +#: src/slic3r/GUI/Tab.cpp:1559 msgid "Extrusion width" msgstr "Ширина екструзії" -#: src/slic3r/GUI/Tab.cpp:1104 +#: src/slic3r/GUI/Tab.cpp:1569 msgid "Overlap" msgstr "Перекриття" -#: src/slic3r/GUI/Tab.cpp:1107 +#: src/slic3r/GUI/Tab.cpp:1572 msgid "Flow" msgstr "Потік" -#: src/slic3r/GUI/Tab.cpp:1116 +#: src/slic3r/GUI/Tab.cpp:1581 msgid "Other" msgstr "Інше" -#: src/slic3r/GUI/Tab.cpp:1119 src/slic3r/GUI/Tab.cpp:3351 +#: src/slic3r/GUI/Tab.cpp:1584 src/slic3r/GUI/Tab.cpp:4118 msgid "Output options" msgstr "Параметри виводу" -#: src/slic3r/GUI/Tab.cpp:1120 +#: src/slic3r/GUI/Tab.cpp:1585 msgid "Sequential printing" msgstr "Послідовне друкування" -#: src/slic3r/GUI/Tab.cpp:1122 -msgid "Extruder clearance (mm)" -msgstr "Розмір екструдера (мм)" +#: src/slic3r/GUI/Tab.cpp:1587 +msgid "Extruder clearance" +msgstr "Область зіткнення екструдера" -#: src/slic3r/GUI/Tab.cpp:1131 src/slic3r/GUI/Tab.cpp:3352 +#: src/slic3r/GUI/Tab.cpp:1592 src/slic3r/GUI/Tab.cpp:4119 msgid "Output file" msgstr "Вихідний файл" -#: src/slic3r/GUI/Tab.cpp:1138 src/libslic3r/PrintConfig.cpp:1382 +#: src/slic3r/GUI/Tab.cpp:1599 src/libslic3r/PrintConfig.cpp:1662 msgid "Post-processing scripts" msgstr "Скрипти пост-обробки" -#: src/slic3r/GUI/Tab.cpp:1144 src/slic3r/GUI/Tab.cpp:1145 -#: src/slic3r/GUI/Tab.cpp:1527 src/slic3r/GUI/Tab.cpp:1528 -#: src/slic3r/GUI/Tab.cpp:1935 src/slic3r/GUI/Tab.cpp:1936 -#: src/slic3r/GUI/Tab.cpp:2027 src/slic3r/GUI/Tab.cpp:2028 -#: src/slic3r/GUI/Tab.cpp:3240 src/slic3r/GUI/Tab.cpp:3241 +#: src/slic3r/GUI/Tab.cpp:1605 src/slic3r/GUI/Tab.cpp:1606 +#: src/slic3r/GUI/Tab.cpp:1927 src/slic3r/GUI/Tab.cpp:1928 +#: src/slic3r/GUI/Tab.cpp:2266 src/slic3r/GUI/Tab.cpp:2267 +#: src/slic3r/GUI/Tab.cpp:2342 src/slic3r/GUI/Tab.cpp:2343 +#: src/slic3r/GUI/Tab.cpp:3985 src/slic3r/GUI/Tab.cpp:3986 msgid "Notes" msgstr "Примітки" -#: src/slic3r/GUI/Tab.cpp:1151 src/slic3r/GUI/Tab.cpp:1535 -#: src/slic3r/GUI/Tab.cpp:1942 src/slic3r/GUI/Tab.cpp:2034 -#: src/slic3r/GUI/Tab.cpp:3248 src/slic3r/GUI/Tab.cpp:3357 +#: src/slic3r/GUI/Tab.cpp:1612 src/slic3r/GUI/Tab.cpp:1935 +#: src/slic3r/GUI/Tab.cpp:2273 src/slic3r/GUI/Tab.cpp:2349 +#: src/slic3r/GUI/Tab.cpp:3993 src/slic3r/GUI/Tab.cpp:4124 msgid "Dependencies" msgstr "Залежності" -#: src/slic3r/GUI/Tab.cpp:1152 src/slic3r/GUI/Tab.cpp:1536 -#: src/slic3r/GUI/Tab.cpp:1943 src/slic3r/GUI/Tab.cpp:2035 -#: src/slic3r/GUI/Tab.cpp:3249 src/slic3r/GUI/Tab.cpp:3358 +#: src/slic3r/GUI/Tab.cpp:1613 src/slic3r/GUI/Tab.cpp:1936 +#: src/slic3r/GUI/Tab.cpp:2274 src/slic3r/GUI/Tab.cpp:2350 +#: src/slic3r/GUI/Tab.cpp:3994 src/slic3r/GUI/Tab.cpp:4125 msgid "Profile dependencies" msgstr "Залежності профілю" -#: src/slic3r/GUI/Tab.cpp:1198 -#, no-c-format -msgid "" -"The Spiral Vase mode requires:\n" -"- one perimeter\n" -"- no top solid layers\n" -"- 0% fill density\n" -"- no support material\n" -"- no ensure_vertical_shell_thickness\n" -"\n" -"Shall I adjust those settings in order to enable Spiral Vase?" -msgstr "" -"Режим спіральної вази вимагає:\n" -"- один периметр\n" -"- немає верхніх щільних шарів\n" -"- 0% щільність заповнення\n" -"- немає підтримуючого матеріалу\n" -"- не забезпечує товщини вертикальної оболонки\n" -"\n" -"Чи потрібно змінити ці налаштування, щоб увімкнути режим Спіральної вази?" +#: src/slic3r/GUI/Tab.cpp:1693 +msgid "Filament Overrides" +msgstr "Переписування глобальних змінних" -#: src/slic3r/GUI/Tab.cpp:1205 -msgid "Spiral Vase" -msgstr "Спіральна ваза" +#: src/slic3r/GUI/Tab.cpp:1815 +msgid "Temperature" +msgstr "Температура" -#: src/slic3r/GUI/Tab.cpp:1228 -msgid "" -"The Wipe Tower currently supports the non-soluble supports only\n" -"if they are printed with the current extruder without triggering a tool " -"change.\n" -"(both support_material_extruder and support_material_interface_extruder need " -"to be set to 0).\n" -"\n" -"Shall I adjust those settings in order to enable the Wipe Tower?" -msgstr "" -"Вичіщуюча веж в даний час підтримує лише нерозчинну підтримку\n" -"якщо вони друкуються з поточним екструдером, не запускаючи зміну " -"інструменту.\n" -"(обидва значення support_material_extruder і " -"support_material_interface_extruder повинні бути встановлені на 0).\n" -"\n" -"Чи потрібно коригувати ці налаштування, щоб увімкнути вичіщуючу веж?" +#: src/slic3r/GUI/Tab.cpp:1816 +msgid "Nozzle" +msgstr "Сопло" -#: src/slic3r/GUI/Tab.cpp:1232 src/slic3r/GUI/Tab.cpp:1249 -msgid "Wipe Tower" -msgstr "Вичіщуюча веж" - -#: src/slic3r/GUI/Tab.cpp:1246 -msgid "" -"For the Wipe Tower to work with the soluble supports, the support layers\n" -"need to be synchronized with the object layers.\n" -"\n" -"Shall I synchronize support layers in order to enable the Wipe Tower?" -msgstr "" -"Для того, щоб Вичіщуюча веж працювала з розчинними підтримками, шари " -"підтримки\n" -"повинні бути синхронізовані з шаром об'єкта.\n" -"\n" -"Чи потрібно синхронізувати шари підтримки, щоб увімкнути вичіщуючу веж?" - -#: src/slic3r/GUI/Tab.cpp:1264 -msgid "" -"Supports work better, if the following feature is enabled:\n" -"- Detect bridging perimeters\n" -"\n" -"Shall I adjust those settings for supports?" -msgstr "" -"Підтримка працює краще, якщо ввімкнено таку функцію:\n" -"- Виявлення висячих периметрів(перемичок)\n" -"\n" -"Чи потрібно змінити ці налаштування для підтримки?" - -#: src/slic3r/GUI/Tab.cpp:1267 -msgid "Support Generator" -msgstr "Створення підтримки" - -#: src/slic3r/GUI/Tab.cpp:1309 -msgid "The " -msgstr "Шаблон наповнення " - -#: src/slic3r/GUI/Tab.cpp:1309 -#, no-c-format -msgid "" -" infill pattern is not supposed to work at 100%% density.\n" -"\n" -"Shall I switch to rectilinear fill pattern?" -msgstr "" -" не підтримується на 100% щільності.\n" -"\n" -"Чи потрібно змінити його на Rectilinear шаблон заповнення?" - -#: src/slic3r/GUI/Tab.cpp:1429 -msgid "Temperature " -msgstr "Температура " - -#: src/slic3r/GUI/Tab.cpp:1435 +#: src/slic3r/GUI/Tab.cpp:1821 msgid "Bed" -msgstr "Полотно" +msgstr "Стіл" -#: src/slic3r/GUI/Tab.cpp:1440 +#: src/slic3r/GUI/Tab.cpp:1826 msgid "Cooling" msgstr "Охолодження" -#: src/slic3r/GUI/Tab.cpp:1441 src/libslic3r/PrintConfig.cpp:1285 -#: src/libslic3r/PrintConfig.cpp:2097 +#: src/slic3r/GUI/Tab.cpp:1828 src/libslic3r/PrintConfig.cpp:1565 +#: src/libslic3r/PrintConfig.cpp:2428 msgid "Enable" msgstr "Увімкнути" -#: src/slic3r/GUI/Tab.cpp:1452 +#: src/slic3r/GUI/Tab.cpp:1839 msgid "Fan settings" msgstr "Налаштування вентилятора" -#: src/slic3r/GUI/Tab.cpp:1453 -msgid "Fan speed" -msgstr "Швидкість вентилятора" - -#: src/slic3r/GUI/Tab.cpp:1461 +#: src/slic3r/GUI/Tab.cpp:1850 msgid "Cooling thresholds" msgstr "Пороги охолодження" -#: src/slic3r/GUI/Tab.cpp:1467 +#: src/slic3r/GUI/Tab.cpp:1856 msgid "Filament properties" msgstr "Властивості філаменту" -#: src/slic3r/GUI/Tab.cpp:1471 +#: src/slic3r/GUI/Tab.cpp:1863 msgid "Print speed override" msgstr "Перевизначення швидкості друку" -#: src/slic3r/GUI/Tab.cpp:1481 +#: src/slic3r/GUI/Tab.cpp:1873 +msgid "Wipe tower parameters" +msgstr "Параметри вежі витирання" + +#: src/slic3r/GUI/Tab.cpp:1876 msgid "Toolchange parameters with single extruder MM printers" -msgstr "" +msgstr "Параметри зміни інструменту в одно-екструдерному ММ-принтері" -#: src/slic3r/GUI/Tab.cpp:1496 +#: src/slic3r/GUI/Tab.cpp:1889 msgid "Ramming settings" -msgstr "" +msgstr "Налаштування раммінгу" -#: src/slic3r/GUI/Tab.cpp:1514 src/slic3r/GUI/Tab.cpp:1898 +#: src/slic3r/GUI/Tab.cpp:1912 src/slic3r/GUI/Tab.cpp:2205 +#: src/libslic3r/PrintConfig.cpp:2063 msgid "Custom G-code" msgstr "Користувацький G-код" -#: src/slic3r/GUI/Tab.cpp:1515 src/slic3r/GUI/Tab.cpp:1899 -#: src/libslic3r/PrintConfig.cpp:1735 src/libslic3r/PrintConfig.cpp:1750 +#: src/slic3r/GUI/Tab.cpp:1913 src/slic3r/GUI/Tab.cpp:2206 +#: src/libslic3r/PrintConfig.cpp:2013 src/libslic3r/PrintConfig.cpp:2028 msgid "Start G-code" msgstr "Початок G-коду" -#: src/slic3r/GUI/Tab.cpp:1521 src/slic3r/GUI/Tab.cpp:1905 -#: src/libslic3r/PrintConfig.cpp:358 src/libslic3r/PrintConfig.cpp:368 +#: src/slic3r/GUI/Tab.cpp:1920 src/slic3r/GUI/Tab.cpp:2213 +#: src/libslic3r/PrintConfig.cpp:441 src/libslic3r/PrintConfig.cpp:451 msgid "End G-code" msgstr "Закінчення G-коду" -#: src/slic3r/GUI/Tab.cpp:1632 src/slic3r/GUI/Tab.cpp:1689 -msgid " Browse " -msgstr " Переглянути " +#: src/slic3r/GUI/Tab.cpp:1970 +msgid "Volumetric flow hints not available" +msgstr "Підказки об'ємного потоку відсутні" -#: src/slic3r/GUI/Tab.cpp:1651 src/slic3r/GUI/Tab.cpp:1838 -msgid "Test" -msgstr "Перевірити" - -#: src/slic3r/GUI/Tab.cpp:1662 -msgid "Could not get a valid Printer Host reference" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:1668 src/slic3r/GUI/Tab.cpp:1851 -msgid "Success!" -msgstr "Успіх!" - -#: src/slic3r/GUI/Tab.cpp:1683 +#: src/slic3r/GUI/Tab.cpp:2066 msgid "" -"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-" -"signed certificate." +"Note: All parameters from this group are moved to the Physical Printer " +"settings (see changelog).\n" +"\n" +"A new Physical Printer profile is created by clicking on the \"cog\" icon " +"right of the Printer profiles combo box, by selecting the \"Add physical " +"printer\" item in the Printer combo box. The Physical Printer profile editor " +"opens also when clicking on the \"cog\" icon in the Printer settings tab. " +"The Physical Printer profiles are being stored into PrusaSlicer/" +"physical_printer directory." msgstr "" +"Примітка: Усі параметри з цієї групи переміщено до налаштувань фізичного " +"принтера (див. Журнал змін).\n" +"\n" +"Новий профіль фізичного принтера створюється натисканням на піктограму " +"\"гвинтик\" праворуч від списку \"Профілі принтера\", вибором пункту " +"\"Додати фізичний принтер\" у списку принтера. Редактор профілю фізичного " +"принтера відкривається також при натисканні на піктограму \"гвинтик\" на " +"вкладці \"Параметри принтеру\". Профілі фізичного принтера зберігаються в " +"каталозі \"PrusaSlicer/physical_printer\"." -#: src/slic3r/GUI/Tab.cpp:1696 -msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:1697 -msgid "Open CA certificate file" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:1725 -msgid "" -"HTTPS CA File:\n" -"\tOn this system, Slic3r uses HTTPS certificates from the system Certificate " -"Store or Keychain.\n" -"\tTo use a custom CA file, please import your CA file into Certificate " -"Store / Keychain." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:1763 src/slic3r/GUI/Tab.cpp:1964 +#: src/slic3r/GUI/Tab.cpp:2099 src/slic3r/GUI/Tab.cpp:2286 msgid "Size and coordinates" msgstr "Розмір і координати" -#: src/slic3r/GUI/Tab.cpp:1767 src/slic3r/GUI/Tab.cpp:1968 -#: src/slic3r/GUI/Tab.cpp:2911 -msgid " Set " -msgstr " Встановити " - -#: src/slic3r/GUI/Tab.cpp:1790 +#: src/slic3r/GUI/Tab.cpp:2108 src/slic3r/GUI/UnsavedChangesDialog.cpp:1080 msgid "Capabilities" msgstr "Можливості" -#: src/slic3r/GUI/Tab.cpp:1795 +#: src/slic3r/GUI/Tab.cpp:2113 msgid "Number of extruders of the printer." msgstr "Кількість екструдерів у принтері." -#: src/slic3r/GUI/Tab.cpp:1823 -msgid "USB/Serial connection" -msgstr "USB/послідовне з'єднання" - -#: src/slic3r/GUI/Tab.cpp:1824 src/libslic3r/PrintConfig.cpp:1590 -msgid "Serial port" -msgstr "Послідовний порт" - -#: src/slic3r/GUI/Tab.cpp:1829 -msgid "Rescan serial ports" -msgstr "Сканувати ще раз послідовні порти" - -#: src/slic3r/GUI/Tab.cpp:1851 -msgid "Connection to printer works correctly." -msgstr "Підключення до принтера працює коректно." - -#: src/slic3r/GUI/Tab.cpp:1854 -msgid "Connection failed." -msgstr "Підключення не вдалося." - -#: src/slic3r/GUI/Tab.cpp:1867 src/slic3r/GUI/Tab.cpp:2022 -msgid "Print Host upload" +#: src/slic3r/GUI/Tab.cpp:2141 +msgid "" +"Single Extruder Multi Material is selected, \n" +"and all extruders must have the same diameter.\n" +"Do you want to change the diameter for all extruders to first extruder " +"nozzle diameter value?" msgstr "" +"Вибрано мульти-матеріальний (ММ) друк з одним екструдером,\n" +"і всі екструдери повинні мати однаковий діаметр.\n" +"Хочете змінити діаметр для всіх екструдерів на значення діаметра сопла " +"першого екструдера?" -#: src/slic3r/GUI/Tab.cpp:1911 src/libslic3r/PrintConfig.cpp:128 +#: src/slic3r/GUI/Tab.cpp:2144 src/slic3r/GUI/Tab.cpp:2552 +#: src/libslic3r/PrintConfig.cpp:1534 +msgid "Nozzle diameter" +msgstr "Діаметр сопла" + +#: src/slic3r/GUI/Tab.cpp:2220 src/libslic3r/PrintConfig.cpp:209 msgid "Before layer change G-code" msgstr "G-код перед зміною шару" -#: src/slic3r/GUI/Tab.cpp:1917 src/libslic3r/PrintConfig.cpp:1030 +#: src/slic3r/GUI/Tab.cpp:2227 src/libslic3r/PrintConfig.cpp:1273 msgid "After layer change G-code" msgstr "G-код після зміни шару" -#: src/slic3r/GUI/Tab.cpp:1923 src/libslic3r/PrintConfig.cpp:2005 +#: src/slic3r/GUI/Tab.cpp:2234 src/libslic3r/PrintConfig.cpp:2321 msgid "Tool change G-code" msgstr "G-код зміни інструменту" -#: src/slic3r/GUI/Tab.cpp:1929 +#: src/slic3r/GUI/Tab.cpp:2241 msgid "Between objects G-code (for sequential printing)" msgstr "G-код між об'єктами (для послідовного друку)" -#: src/slic3r/GUI/Tab.cpp:1990 +#: src/slic3r/GUI/Tab.cpp:2248 +msgid "Color Change G-code" +msgstr "G-код зміни кольору" + +#: src/slic3r/GUI/Tab.cpp:2254 src/libslic3r/PrintConfig.cpp:2054 +msgid "Pause Print G-code" +msgstr "G-код для паузи друку" + +#: src/slic3r/GUI/Tab.cpp:2260 +msgid "Template Custom G-code" +msgstr "Шаблон власного G-коду" + +#: src/slic3r/GUI/Tab.cpp:2293 msgid "Display" -msgstr "" +msgstr "Дисплей" -#: src/slic3r/GUI/Tab.cpp:2001 +#: src/slic3r/GUI/Tab.cpp:2308 msgid "Tilt" -msgstr "" +msgstr "Нахил" -#: src/slic3r/GUI/Tab.cpp:2002 +#: src/slic3r/GUI/Tab.cpp:2309 msgid "Tilt time" -msgstr "" +msgstr "Час нахилу" -#: src/slic3r/GUI/Tab.cpp:2008 src/slic3r/GUI/Tab.cpp:3223 +#: src/slic3r/GUI/Tab.cpp:2315 src/slic3r/GUI/Tab.cpp:3969 msgid "Corrections" -msgstr "" +msgstr "Поправки" -#: src/slic3r/GUI/Tab.cpp:2074 src/slic3r/GUI/Tab.cpp:2136 -#: src/libslic3r/PrintConfig.cpp:1076 src/libslic3r/PrintConfig.cpp:1086 -#: src/libslic3r/PrintConfig.cpp:1096 src/libslic3r/PrintConfig.cpp:1109 -#: src/libslic3r/PrintConfig.cpp:1120 src/libslic3r/PrintConfig.cpp:1131 -#: src/libslic3r/PrintConfig.cpp:1142 +#: src/slic3r/GUI/Tab.cpp:2332 src/slic3r/GUI/Tab.cpp:3965 +msgid "Exposure" +msgstr "Експозиція" + +#: src/slic3r/GUI/Tab.cpp:2391 src/slic3r/GUI/Tab.cpp:2485 +#: src/libslic3r/PrintConfig.cpp:1302 src/libslic3r/PrintConfig.cpp:1337 +#: src/libslic3r/PrintConfig.cpp:1354 src/libslic3r/PrintConfig.cpp:1371 +#: src/libslic3r/PrintConfig.cpp:1387 src/libslic3r/PrintConfig.cpp:1397 +#: src/libslic3r/PrintConfig.cpp:1407 src/libslic3r/PrintConfig.cpp:1417 msgid "Machine limits" -msgstr "" +msgstr "Механічних обмеження" -#: src/slic3r/GUI/Tab.cpp:2088 -msgid "Values in this column are for Full Power mode" -msgstr "" +#: src/slic3r/GUI/Tab.cpp:2414 +msgid "Values in this column are for Normal mode" +msgstr "Значення в цьому стовпці для нормального режиму" -#: src/slic3r/GUI/Tab.cpp:2089 -msgid "Full Power" -msgstr "" +#: src/slic3r/GUI/Tab.cpp:2420 +msgid "Values in this column are for Stealth mode" +msgstr "Значення в цьому стовпці для тихого режиму" -#: src/slic3r/GUI/Tab.cpp:2094 -msgid "Values in this column are for Silent mode" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2095 -msgid "Silent" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2103 +#: src/slic3r/GUI/Tab.cpp:2429 msgid "Maximum feedrates" -msgstr "" +msgstr "Максимальна швидкість подачі" -#: src/slic3r/GUI/Tab.cpp:2108 +#: src/slic3r/GUI/Tab.cpp:2434 msgid "Maximum accelerations" -msgstr "" +msgstr "Максимальні прискорення" -#: src/slic3r/GUI/Tab.cpp:2115 +#: src/slic3r/GUI/Tab.cpp:2441 msgid "Jerk limits" -msgstr "" +msgstr "Обмеження ривку" -#: src/slic3r/GUI/Tab.cpp:2120 +#: src/slic3r/GUI/Tab.cpp:2446 msgid "Minimum feedrates" -msgstr "" +msgstr "Мінімальна швидкість подачі" -#: src/slic3r/GUI/Tab.cpp:2158 src/slic3r/GUI/Tab.cpp:2166 +#: src/slic3r/GUI/Tab.cpp:2510 src/slic3r/GUI/Tab.cpp:2518 msgid "Single extruder MM setup" -msgstr "" +msgstr "Налаштування MM екструдера" -#: src/slic3r/GUI/Tab.cpp:2167 +#: src/slic3r/GUI/Tab.cpp:2519 msgid "Single extruder multimaterial parameters" +msgstr "Параметри екструдеру в багато-екструдерному принтері" + +#: src/slic3r/GUI/Tab.cpp:2550 +msgid "" +"This is a single extruder multimaterial printer, diameters of all extruders " +"will be set to the new value. Do you want to proceed?" msgstr "" +"Це одно-екструдерний багато-матеріальний принтер, діаметри всіх екструдерів " +"будуть встановлені на нове значення. Ви хочете продовжити?" -#: src/slic3r/GUI/Tab.cpp:2181 src/libslic3r/GCode/PreviewData.cpp:475 -#, c-format -msgid "Extruder %d" -msgstr "Екструдер %d" - -#: src/slic3r/GUI/Tab.cpp:2188 +#: src/slic3r/GUI/Tab.cpp:2574 msgid "Layer height limits" msgstr "Межі висоти шару" -#: src/slic3r/GUI/Tab.cpp:2193 +#: src/slic3r/GUI/Tab.cpp:2579 msgid "Position (for multi-extruder printers)" msgstr "Позиція (для мульти-екструдерних принтерів)" -#: src/slic3r/GUI/Tab.cpp:2196 -msgid "Retraction" -msgstr "Переривання" - -#: src/slic3r/GUI/Tab.cpp:2199 +#: src/slic3r/GUI/Tab.cpp:2585 msgid "Only lift Z" msgstr "Межі підняття Z" -#: src/slic3r/GUI/Tab.cpp:2212 +#: src/slic3r/GUI/Tab.cpp:2598 msgid "" "Retraction when tool is disabled (advanced settings for multi-extruder " "setups)" @@ -3531,11 +7409,11 @@ msgstr "" "Переривання при відключенні інструмента (додаткові налаштування для " "налагодження мульти-екструдерів)" -#: src/slic3r/GUI/Tab.cpp:2216 -msgid "Preview" -msgstr "Попередній перегляд" +#: src/slic3r/GUI/Tab.cpp:2605 +msgid "Reset to Filament Color" +msgstr "Скинути до кольору філаменту" -#: src/slic3r/GUI/Tab.cpp:2352 +#: src/slic3r/GUI/Tab.cpp:2783 msgid "" "The Wipe option is not available when using the Firmware Retraction mode.\n" "\n" @@ -3546,281 +7424,468 @@ msgstr "" "\n" "Відключити його для увімкнення програмного переривання?" -#: src/slic3r/GUI/Tab.cpp:2354 +#: src/slic3r/GUI/Tab.cpp:2785 msgid "Firmware Retraction" msgstr "Програмне переривання" -#: src/slic3r/GUI/Tab.cpp:2681 -#, c-format -msgid "Default preset (%s)" -msgstr "" +#: src/slic3r/GUI/Tab.cpp:3376 +msgid "Detached" +msgstr "Від'єднаний" -#: src/slic3r/GUI/Tab.cpp:2682 -#, c-format -msgid "Preset (%s)" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2699 -msgid "has the following unsaved changes:" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2702 -msgid "is not compatible with printer" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2703 -msgid "is not compatible with print profile" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2705 -msgid "and it has the following unsaved changes:" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2708 -msgid "Discard changes and continue anyway?" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2709 -msgid "Unsaved Changes" -msgstr "Незбережені зміни" - -#: src/slic3r/GUI/Tab.cpp:2721 -msgid "Please check your object list before preset changing." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2801 -msgid "Copy" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2823 -msgid "The supplied name is empty. It can't be saved." -msgstr "Надане ім'я порожнє. Не вдається зберегти." - -#: src/slic3r/GUI/Tab.cpp:2828 -msgid "Cannot overwrite a system profile." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2832 -msgid "Cannot overwrite an external profile." -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:2858 +#: src/slic3r/GUI/Tab.cpp:3439 msgid "remove" -msgstr "перемістити" +msgstr "видалити" -#: src/slic3r/GUI/Tab.cpp:2858 +#: src/slic3r/GUI/Tab.cpp:3439 msgid "delete" msgstr "видалити" -#: src/slic3r/GUI/Tab.cpp:2859 -msgid "Are you sure you want to " -msgstr "Ви впевнені, що хочете " +#: src/slic3r/GUI/Tab.cpp:3448 +msgid "It's a last preset for this physical printer." +msgstr "Це останній пресет для цього фізичного принтера." -#: src/slic3r/GUI/Tab.cpp:2859 -msgid " the selected preset?" -msgstr " вибране налаштування?" - -#: src/slic3r/GUI/Tab.cpp:2860 -msgid "Remove" -msgstr "Перемістити" - -#: src/slic3r/GUI/Tab.cpp:2861 -msgid " Preset" -msgstr " Налаштування" - -#: src/slic3r/GUI/Tab.cpp:2989 +#: src/slic3r/GUI/Tab.cpp:3453 msgid "" -"LOCKED LOCK;indicates that the settings are the same as the system values " +"Are you sure you want to delete \"%1%\" preset from the physical printer " +"\"%2%\"?" +msgstr "" +"Ви впевнені, що хочете видалити пресет \"%1%\" із фізичного принтера \"%2%\"?" + +#: src/slic3r/GUI/Tab.cpp:3465 +msgid "" +"The physical printer(s) below is based on the preset, you are going to " +"delete." +msgstr "" +"Наведений(і) нижче фізичний(і) принтер(и) базується на пресеті, які ви " +"збираєтеся видалити." + +#: src/slic3r/GUI/Tab.cpp:3469 +msgid "" +"Note, that selected preset will be deleted from this/those printer(s) too." +msgstr "" +"Зверніть увагу, що вибраний пресет буде також видалено з цього/цих " +"принтеру(ів)." + +#: src/slic3r/GUI/Tab.cpp:3473 +msgid "" +"The physical printer(s) below is based only on the preset, you are going to " +"delete." +msgstr "" +"Наведений(і) нижче фізичний(і) принтер(и) базується тільки на пресеті, які " +"ви збираєтеся видалити." + +#: src/slic3r/GUI/Tab.cpp:3477 +msgid "" +"Note, that this/those printer(s) will be deleted after deleting of the " +"selected preset." +msgstr "" +"Зауважте, що цей/ці принтер(и) буде видалено після видалення вибраного " +"пресету." + +#: src/slic3r/GUI/Tab.cpp:3481 +msgid "Are you sure you want to %1% the selected preset?" +msgstr "Ви впевнені, що хочете %1% вибраний пресет?" + +#. TRN Remove/Delete +#: src/slic3r/GUI/Tab.cpp:3486 +msgid "%1% Preset" +msgstr "%1% пресет" + +#: src/slic3r/GUI/Tab.cpp:3567 src/slic3r/GUI/Tab.cpp:3639 +msgid "Set" +msgstr "Встановити" + +#: src/slic3r/GUI/Tab.cpp:3703 +msgid "" +"Machine limits will be emitted to G-code and used to estimate print time." +msgstr "" +"Механічних обмеження публікуватимуться в G-код і використовуватимуться для " +"розрахунку часу друку." + +#: src/slic3r/GUI/Tab.cpp:3706 +msgid "" +"Machine limits will NOT be emitted to G-code, however they will be used to " +"estimate print time, which may therefore not be accurate as the printer may " +"apply a different set of machine limits." +msgstr "" +"Механічних обмеження НЕ публікуватимуться в G-код, однак вони будуть " +"використовуватися для оцінки часу друку, що, отже, може бути неточним, " +"оскільки принтер може застосовувати інший набір механічних обмежень." + +#: src/slic3r/GUI/Tab.cpp:3710 +msgid "" +"Machine limits are not set, therefore the print time estimate may not be " +"accurate." +msgstr "" +"Механічних обмеження не встановлені, тому оцінка часу друку може бути " +"неточною." + +#: src/slic3r/GUI/Tab.cpp:3732 +msgid "LOCKED LOCK" +msgstr "ЗАКРИТИЙ ЗАМОК" + +#. TRN Description for "LOCKED LOCK" +#: src/slic3r/GUI/Tab.cpp:3734 +msgid "" +"indicates that the settings are the same as the system (or default) values " "for the current option group" msgstr "" +"вказує на те, що параметри збігаються із системними (або за замовчуванням) " +"значеннями для поточної групи опцій" -#: src/slic3r/GUI/Tab.cpp:2992 +#: src/slic3r/GUI/Tab.cpp:3736 +msgid "UNLOCKED LOCK" +msgstr "ВІДКРИТИЙ ЗАМОК" + +#. TRN Description for "UNLOCKED LOCK" +#: src/slic3r/GUI/Tab.cpp:3738 msgid "" -"UNLOCKED LOCK;indicates that some settings were changed and are not equal to " -"the system values for the current option group.\n" +"indicates that some settings were changed and are not equal to the system " +"(or default) values for the current option group.\n" "Click the UNLOCKED LOCK icon to reset all settings for current option group " -"to the system values." +"to the system (or default) values." msgstr "" +"вказує на те, що деякі параметри були змінені і не дорівнюють системним (або " +"за замовчуванням) значенням для поточної групи опцій.\n" +"Клацніть, щоб скинути всі налаштування для поточної групи опцій до системних " +"значень (або за замовчуванням)." -#: src/slic3r/GUI/Tab.cpp:2998 +#: src/slic3r/GUI/Tab.cpp:3743 +msgid "WHITE BULLET" +msgstr "БІЛА КУЛЯ" + +#. TRN Description for "WHITE BULLET" +#: src/slic3r/GUI/Tab.cpp:3745 msgid "" -"WHITE BULLET;for the left button: \tindicates a non-system preset,\n" -"for the right button: \tindicates that the settings hasn't been modified." +"for the left button: indicates a non-system (or non-default) preset,\n" +"for the right button: indicates that the settings hasn't been modified." msgstr "" +"для лівої кнопки: вказує на несистемний (або не за замовчуванням) пресет,\n" +"для правої кнопки: вказує на те, що параметри не були змінені." -#: src/slic3r/GUI/Tab.cpp:3002 +#: src/slic3r/GUI/Tab.cpp:3748 +msgid "BACK ARROW" +msgstr "СТРІЛКА НАЗАД" + +#. TRN Description for "BACK ARROW" +#: src/slic3r/GUI/Tab.cpp:3750 msgid "" -"BACK ARROW;indicates that the settings were changed and are not equal to the " -"last saved preset for the current option group.\n" +"indicates that the settings were changed and are not equal to the last saved " +"preset for the current option group.\n" "Click the BACK ARROW icon to reset all settings for the current option group " "to the last saved preset." msgstr "" +"вказує на те, що параметри були змінені і не дорівнюють останньому " +"збереженому пресету для поточної групи параметрів.\n" +"Клацніть, щоб скинути всі параметри для поточної групи параметрів до " +"останнього збереженого пресету." -#: src/slic3r/GUI/Tab.cpp:3028 +#: src/slic3r/GUI/Tab.cpp:3760 msgid "" -"LOCKED LOCK icon indicates that the settings are the same as the system " -"values for the current option group" +"LOCKED LOCK icon indicates that the settings are the same as the system (or " +"default) values for the current option group" msgstr "" +"Значок \"ЗАКРИТИЙ ЗАМОК\" вказує на те, що параметри збігаються із " +"системними (або за замовчуванням) значеннями для поточної групи опцій" -#: src/slic3r/GUI/Tab.cpp:3030 +#: src/slic3r/GUI/Tab.cpp:3762 msgid "" "UNLOCKED LOCK icon indicates that some settings were changed and are not " -"equal to the system values for the current option group.\n" -"Click to reset all settings for current option group to the system values." +"equal to the system (or default) values for the current option group.\n" +"Click to reset all settings for current option group to the system (or " +"default) values." msgstr "" +"Значок \"ВІДКРИТИЙ ЗАМОК\" вказує на те, що деякі параметри були змінені і " +"не дорівнюють системним (або за замовчуванням) значенням для поточної групи " +"опцій.\n" +"Клацніть, щоб скинути всі налаштування для поточної групи опцій до системних " +"значень (або за замовчуванням)." -#: src/slic3r/GUI/Tab.cpp:3033 -msgid "WHITE BULLET icon indicates a non system preset." +#: src/slic3r/GUI/Tab.cpp:3765 +msgid "WHITE BULLET icon indicates a non system (or non default) preset." msgstr "" +"Значок \"БІЛА КУЛЯ\" вказує на несистемний (або не за замовчуванням) пресет." -#: src/slic3r/GUI/Tab.cpp:3036 +#: src/slic3r/GUI/Tab.cpp:3768 msgid "" "WHITE BULLET icon indicates that the settings are the same as in the last " "saved preset for the current option group." msgstr "" +"Значок \"БІЛА КУЛЯ\" вказує на те, що параметри збігаються тими, які є в " +"останньому збереженому пресеті для поточної групи опцій." -#: src/slic3r/GUI/Tab.cpp:3038 +#: src/slic3r/GUI/Tab.cpp:3770 msgid "" "BACK ARROW icon indicates that the settings were changed and are not equal " "to the last saved preset for the current option group.\n" "Click to reset all settings for the current option group to the last saved " "preset." msgstr "" +"Значок \"СТРІЛКА НАЗАД\" вказує на те, що параметри були змінені і не " +"дорівнюють останньому збереженому пресету для поточної групи параметрів.\n" +"Клацніть, щоб скинути всі параметри для поточної групи параметрів до " +"останнього збереженого пресету." -#: src/slic3r/GUI/Tab.cpp:3044 +#: src/slic3r/GUI/Tab.cpp:3776 msgid "" -"LOCKED LOCK icon indicates that the value is the same as the system value." +"LOCKED LOCK icon indicates that the value is the same as the system (or " +"default) value." msgstr "" +"Значок \"ЗАКРИТИЙ ЗАМОК\" вказує на те, що значення збігається із системним " +"(або за замовчуванням)." -#: src/slic3r/GUI/Tab.cpp:3045 +#: src/slic3r/GUI/Tab.cpp:3777 msgid "" "UNLOCKED LOCK icon indicates that the value was changed and is not equal to " -"the system value.\n" -"Click to reset current value to the system value." +"the system (or default) value.\n" +"Click to reset current value to the system (or default) value." msgstr "" +"Значок \"ВІДКРИТИЙ ЗАМОК\" вказує на те, що значення було змінено і не " +"дорівнює системному (або за замовчуванням) значенню.\n" +"Клацніть, щоб скинути поточне значення до системного (або за замовчуванням)." -#: src/slic3r/GUI/Tab.cpp:3051 +#: src/slic3r/GUI/Tab.cpp:3783 msgid "" "WHITE BULLET icon indicates that the value is the same as in the last saved " "preset." msgstr "" +"Значок \"БІЛА КУЛЯ\" вказує на те, що значення збігається з значенням " +"збереженого пресету." -#: src/slic3r/GUI/Tab.cpp:3052 +#: src/slic3r/GUI/Tab.cpp:3784 msgid "" "BACK ARROW icon indicates that the value was changed and is not equal to the " "last saved preset.\n" "Click to reset current value to the last saved preset." msgstr "" +"Значок \"СТРІЛКА НАЗАД\" вказує на те, що значення було змінено і не " +"дорівнює останньому збереженому пресету.\n" +"Клацніть, щоб скинути поточне значення до останнього збереженого пресету." -#: src/slic3r/GUI/Tab.cpp:3152 -msgid " as:" -msgstr " як:" - -#: src/slic3r/GUI/Tab.cpp:3196 -msgid "the following postfix are not allowed:" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:3200 -msgid "The supplied name is not available." -msgstr "Надане ім'я недійсне." - -#: src/slic3r/GUI/Tab.cpp:3213 +#: src/slic3r/GUI/Tab.cpp:3928 src/slic3r/GUI/Tab.cpp:3930 msgid "Material" -msgstr "" +msgstr "Матеріал" -#: src/slic3r/GUI/Tab.cpp:3215 src/slic3r/GUI/Tab.cpp:3305 -msgid "Layers" -msgstr "Шари" - -#: src/slic3r/GUI/Tab.cpp:3219 -msgid "Exposure" -msgstr "" - -#: src/slic3r/GUI/Tab.cpp:3313 +#: src/slic3r/GUI/Tab.cpp:4052 msgid "Support head" -msgstr "" +msgstr "Головка підтримки" -#: src/slic3r/GUI/Tab.cpp:3318 +#: src/slic3r/GUI/Tab.cpp:4057 msgid "Support pillar" -msgstr "" +msgstr "Стовп підтримки" -#: src/slic3r/GUI/Tab.cpp:3328 +#: src/slic3r/GUI/Tab.cpp:4080 msgid "Connection of the support sticks and junctions" -msgstr "" +msgstr "З'єднання опорних стовпів і стиків" -#: src/slic3r/GUI/Tab.cpp:3333 +#: src/slic3r/GUI/Tab.cpp:4085 msgid "Automatic generation" -msgstr "" +msgstr "Автоматичне згенерування" -#: src/slic3r/GUI/Tab.cpp:3395 -msgid "Head penetration should not be greater than the head width." +#: src/slic3r/GUI/Tab.cpp:4159 +msgid "" +"\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n" +"To enable \"%1%\", please switch off \"%2%\"" msgstr "" +"\"%1%\" вимкнено, оскільки в категорії \"%3%\" увімкнено \"%2%\".\n" +"Щоб увімкнути \"%1%\", вимкніть \"%2%\"" -#: src/slic3r/GUI/Tab.cpp:3396 -msgid "Invalid Head penetration" -msgstr "" +#: src/slic3r/GUI/Tab.cpp:4161 src/libslic3r/PrintConfig.cpp:3002 +msgid "Object elevation" +msgstr "Підняття об’єкта" -#: src/slic3r/GUI/Tab.cpp:3408 -msgid "Pinhead diameter should be smaller than the pillar diameter." -msgstr "" +#: src/slic3r/GUI/Tab.cpp:4161 src/libslic3r/PrintConfig.cpp:3104 +msgid "Pad around object" +msgstr "Подушка навколо об’єкта" -#: src/slic3r/GUI/Tab.cpp:3409 -msgid "Invalid pinhead diameter" -msgstr "" - -#: src/slic3r/GUI/Tab.hpp:307 src/slic3r/GUI/Tab.hpp:395 +#: src/slic3r/GUI/Tab.hpp:370 src/slic3r/GUI/Tab.hpp:492 msgid "Print Settings" msgstr "Параметри друку" -#: src/slic3r/GUI/Tab.hpp:325 +#: src/slic3r/GUI/Tab.hpp:401 msgid "Filament Settings" msgstr "Параметри філаменту" -#: src/slic3r/GUI/Tab.hpp:358 +#: src/slic3r/GUI/Tab.hpp:442 msgid "Printer Settings" msgstr "Параметри принтеру" -#: src/slic3r/GUI/Tab.hpp:381 +#: src/slic3r/GUI/Tab.hpp:476 msgid "Material Settings" +msgstr "Параметри матеріалу" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:149 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:158 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:857 +msgid "Undef" +msgstr "Невизначений" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:537 +msgid "PrusaSlicer is closing: Unsaved Changes" +msgstr "PrusaSlicer закривається: Незбережені зміни" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:554 +msgid "Switching Presets: Unsaved Changes" +msgstr "Перемикання пресетів: незбережені зміни" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:620 +msgid "Old Value" +msgstr "Старе значення" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:621 +msgid "New Value" +msgstr "Нове значення" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:652 +msgid "Transfer" +msgstr "Перенести" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:653 +msgid "Discard" +msgstr "Відхилити" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:654 +msgid "Save" +msgstr "Зберегти" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:674 +msgid "PrusaSlicer will remember your action." +msgstr "PrusaSlicer запам'ятає ваші дії." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:676 +msgid "" +"You will not be asked about the unsaved changes the next time you close " +"PrusaSlicer." msgstr "" +"Наступного разу, коли ви закриватимете PrusaSlicer, вас не питатимуть про " +"незбережені зміни." -#: src/slic3r/GUI/Tab.hpp:407 -msgid "Save preset" -msgstr "Зберегти налаштування" +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:677 +msgid "" +"You will not be asked about the unsaved changes the next time you switch a " +"preset." +msgstr "" +"Наступного разу, коли ви переключите пресет, вас не питатимуть про " +"незбережені зміни." -#: src/slic3r/GUI/UpdateDialogs.cpp:29 +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:678 +msgid "" +"Visit \"Preferences\" and check \"%1%\"\n" +"to be asked about unsaved changes again." +msgstr "" +"Відвідайте \"Преференції\" та встановіть прапорець \"%1%\"\n" +"щоб знову запитати про незбережені зміни." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:680 +msgid "PrusaSlicer: Don't ask me again" +msgstr "PrusaSlicer: Не питай мене більше" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:747 +msgid "" +"Some fields are too long to fit. Right mouse click reveals the full text." +msgstr "" +"Деякі поля занадто довгі, щоб вміститися у чарунку. Клацніть правою кнопкою " +"миші, щоб відкрити повний текст." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:749 +msgid "All settings changes will be discarded." +msgstr "Усі зміни параметрів буде відхилено." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:752 +msgid "Save the selected options." +msgstr "Зберегти вибрані параметри." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:752 +msgid "Transfer the selected settings to the newly selected preset." +msgstr "Перенести вибрані параметри до нещодавно вибраного пресету." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:756 +msgid "Save the selected options to preset \"%1%\"." +msgstr "Зберегти вибрані параметри до пресету \"%1%\"." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:757 +msgid "Transfer the selected options to the newly selected preset \"%1%\"." +msgstr "Перенести вибрані параметри до нещодавно вибраного пресету \"%1%\"." + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1019 +msgid "The following presets were modified:" +msgstr "Наступні пресети були змінені :" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1024 +msgid "Preset \"%1%\" has the following unsaved changes:" +msgstr "Пресет \"%1%\" має такі незбережені зміни:" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1028 +msgid "" +"Preset \"%1%\" is not compatible with the new printer profile and it has the " +"following unsaved changes:" +msgstr "" +"Пресет \"%1%\" несумісний з новим профілем принтера, і він має такі " +"незбережені зміни:" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1029 +msgid "" +"Preset \"%1%\" is not compatible with the new print profile and it has the " +"following unsaved changes:" +msgstr "" +"Пресет \"%1%\" несумісний з новим профілем друку, і він має такі незбережені " +"зміни:" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1075 +msgid "Extruders count" +msgstr "Кількість екструдерів" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1197 +msgid "Old value" +msgstr "Нове значення" + +#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1198 +msgid "New value" +msgstr "Нове значення" + +#: src/slic3r/GUI/UpdateDialogs.cpp:38 msgid "Update available" -msgstr "" +msgstr "Доступне оновлення" -#: src/slic3r/GUI/UpdateDialogs.cpp:29 -msgid "New version of Slic3r PE is available" -msgstr "" +#: src/slic3r/GUI/UpdateDialogs.cpp:38 +#, c-format +msgid "New version of %s is available" +msgstr "Доступна нова версія %s" -#: src/slic3r/GUI/UpdateDialogs.cpp:36 -msgid "To download, follow the link below." -msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:44 +#: src/slic3r/GUI/UpdateDialogs.cpp:43 msgid "Current version:" -msgstr "" +msgstr "Поточна версія:" -#: src/slic3r/GUI/UpdateDialogs.cpp:46 +#: src/slic3r/GUI/UpdateDialogs.cpp:45 msgid "New version:" -msgstr "" +msgstr "Нова версія:" -#: src/slic3r/GUI/UpdateDialogs.cpp:54 +#: src/slic3r/GUI/UpdateDialogs.cpp:53 +msgid "Changelog && Download" +msgstr "Журнал змін і завантаження" + +#: src/slic3r/GUI/UpdateDialogs.cpp:60 src/slic3r/GUI/UpdateDialogs.cpp:125 +#: src/slic3r/GUI/UpdateDialogs.cpp:183 +msgid "Open changelog page" +msgstr "Відкрийте сторінку журналу змін" + +#: src/slic3r/GUI/UpdateDialogs.cpp:65 +msgid "Open download page" +msgstr "Відкрити сторінку завантаження" + +#: src/slic3r/GUI/UpdateDialogs.cpp:71 msgid "Don't notify about new releases any more" -msgstr "" +msgstr "Більше не сповіщати про нові випуски" -#: src/slic3r/GUI/UpdateDialogs.cpp:72 src/slic3r/GUI/UpdateDialogs.cpp:164 +#: src/slic3r/GUI/UpdateDialogs.cpp:89 src/slic3r/GUI/UpdateDialogs.cpp:266 msgid "Configuration update" -msgstr "" +msgstr "Оновлення конфігурації" -#: src/slic3r/GUI/UpdateDialogs.cpp:72 +#: src/slic3r/GUI/UpdateDialogs.cpp:89 msgid "Configuration update is available" -msgstr "" +msgstr "Доступне оновлення конфігурації" -#: src/slic3r/GUI/UpdateDialogs.cpp:75 +#: src/slic3r/GUI/UpdateDialogs.cpp:92 msgid "" "Would you like to install it?\n" "\n" @@ -3829,48 +7894,91 @@ msgid "" "\n" "Updated configuration bundles:" msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:111 -msgid "Slic3r incompatibility" -msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:111 -msgid "Slic3r configuration is incompatible" -msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:114 -msgid "" -"This version of Slic3r PE is not compatible with currently installed " -"configuration bundles.\n" -"This probably happened as a result of running an older Slic3r PE after using " -"a newer one.\n" +"Ви хотіли б його встановити?\n" "\n" -"You may either exit Slic3r and try again with a newer version, or you may re-" -"run the initial configuration. Doing so will create a backup snapshot of the " -"existing configuration before installing files compatible with this Slic3r.\n" -msgstr "" +"Зверніть увагу, що спочатку буде створено повний знімок конфігурації. Потім " +"його можна відновити в будь-який час, у випадку проблем з новою версією.\n" +"\n" +"Оновлені пакети конфігурації:" -#: src/slic3r/GUI/UpdateDialogs.cpp:123 +#: src/slic3r/GUI/UpdateDialogs.cpp:113 src/slic3r/GUI/UpdateDialogs.cpp:173 +msgid "Comment:" +msgstr "Коментар:" + +#: src/slic3r/GUI/UpdateDialogs.cpp:148 src/slic3r/GUI/UpdateDialogs.cpp:210 #, c-format -msgid "This Slic3r PE version: %s" -msgstr "" +msgid "%s incompatibility" +msgstr "Несумісність з %s" -#: src/slic3r/GUI/UpdateDialogs.cpp:128 -msgid "Incompatible bundles:" -msgstr "" +#: src/slic3r/GUI/UpdateDialogs.cpp:148 +msgid "You must install a configuration update." +msgstr "Потрібно встановити оновлення конфігурації." -#: src/slic3r/GUI/UpdateDialogs.cpp:144 -msgid "Exit Slic3r" -msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:147 -msgid "Re-configure" -msgstr "" - -#: src/slic3r/GUI/UpdateDialogs.cpp:168 +#: src/slic3r/GUI/UpdateDialogs.cpp:151 #, c-format msgid "" -"Slic3r PE now uses an updated configuration structure.\n" +"%s will now start updates. Otherwise it won't be able to start.\n" +"\n" +"Note that a full configuration snapshot will be created first. It can then " +"be restored at any time should there be a problem with the new version.\n" +"\n" +"Updated configuration bundles:" +msgstr "" +"Зараз %s розпочне оновлення. Інакше він не зможе запуститися.\n" +"\n" +"Зверніть увагу, що спочатку буде створено повний знімок конфігурації. Потім " +"його можна буде відновити в будь-який час, якщо виникне проблема з новою " +"версією.\n" +"\n" +"Оновлені пакети конфігурації:" + +#: src/slic3r/GUI/UpdateDialogs.cpp:191 src/slic3r/GUI/UpdateDialogs.cpp:246 +#, c-format +msgid "Exit %s" +msgstr "Вихід %s" + +#: src/slic3r/GUI/UpdateDialogs.cpp:211 +#, c-format +msgid "%s configuration is incompatible" +msgstr "конфігурація %s є несумісна" + +#: src/slic3r/GUI/UpdateDialogs.cpp:216 +#, c-format +msgid "" +"This version of %s is not compatible with currently installed configuration " +"bundles.\n" +"This probably happened as a result of running an older %s after using a " +"newer one.\n" +"\n" +"You may either exit %s and try again with a newer version, or you may re-run " +"the initial configuration. Doing so will create a backup snapshot of the " +"existing configuration before installing files compatible with this %s." +msgstr "" +"Ця версія %s не сумісна з встановленими на сьогодні пакетами конфігурації.\n" +"Можливо, це сталося в результаті запуску старішого %s після використання " +"нового.\n" +"\n" +"Ви можете вийти зі %s і спробувати ще раз із новою версією, або повторно " +"запустити початкову конфігурацію. Це створить резервний знімок існуючої " +"конфігурації перед встановленням файлів, сумісних із цим %s." + +#: src/slic3r/GUI/UpdateDialogs.cpp:225 +#, c-format +msgid "This %s version: %s" +msgstr "%s версії %s" + +#: src/slic3r/GUI/UpdateDialogs.cpp:230 +msgid "Incompatible bundles:" +msgstr "Несумісні комплекти:" + +#: src/slic3r/GUI/UpdateDialogs.cpp:249 +msgid "Re-configure" +msgstr "Пере-налаштувати" + +#: src/slic3r/GUI/UpdateDialogs.cpp:270 +#, c-format +msgid "" +"%s now uses an updated configuration structure.\n" "\n" "So called 'System presets' have been introduced, which hold the built-in " "default settings for various printers. These System presets cannot be " @@ -3882,16 +7990,40 @@ msgid "" "Please proceed with the %s that follows to set up the new presets and to " "choose whether to enable automatic preset updates." msgstr "" +"%s тепер використовує оновлену структуру конфігурації.\n" +"\n" +"Були введені так звані \"системні пресети\", які містять вбудовані " +"налаштування за замовчуванням для різних принтерів. Ці системні пресети не " +"можуть бути змінені, натомість користувачі тепер можуть створювати власні " +"пресети, успадковуючи налаштування з одного із системних пресетів.\n" +"Спадковий пресет може успадкувати певне значення від свого батька або " +"замінити його своїм власним значенням.\n" +"\n" +"Будь ласка, перейдіть до %s, щоб налаштувати нові пресети та вибрати, чи " +"вмикати їх автоматичне оновлення." -#: src/slic3r/GUI/UpdateDialogs.cpp:184 +#: src/slic3r/GUI/UpdateDialogs.cpp:287 msgid "For more information please visit our wiki page:" -msgstr "" +msgstr "Для отримання додаткової інформації відвідайте нашу wiki-сторінку:" -#: src/slic3r/GUI/WipeTowerDialog.cpp:14 +#: src/slic3r/GUI/UpdateDialogs.cpp:304 +msgid "Configuration updates" +msgstr "Оновлення конфігурацій" + +#: src/slic3r/GUI/UpdateDialogs.cpp:304 +msgid "No updates available" +msgstr "Немає оновлень" + +#: src/slic3r/GUI/UpdateDialogs.cpp:309 +#, c-format +msgid "%s has no configuration updates available." +msgstr "%s не має оновлень конфігурації." + +#: src/slic3r/GUI/WipeTowerDialog.cpp:15 msgid "Ramming customization" -msgstr "" +msgstr "Налаштування раммінгу" -#: src/slic3r/GUI/WipeTowerDialog.cpp:40 +#: src/slic3r/GUI/WipeTowerDialog.cpp:41 msgid "" "Ramming denotes the rapid extrusion just before a tool change in a single-" "extruder MM printer. Its purpose is to properly shape the end of the " @@ -3903,576 +8035,835 @@ msgid "" "This is an expert-level setting, incorrect adjustment will likely lead to " "jams, extruder wheel grinding into filament etc." msgstr "" +"Раммінг означає швидке екструдування безпосередньо перед заміною інструменту " +"в одно-екструдерному принтері ММ. Його мета полягає у правильній формі кінця " +"виведеного філаменту, щоб вона не заважала вставці нового філаменту і може " +"бути знову встановлений пізніше. Ця фаза є важливою, і різні матеріали " +"можуть вимагати різної швидкості екструзії для отримання гарної форми. З " +"цієї причини швидкість екструдування під час раммінгу регулюється.\n" +"\n" +"Це налаштування на рівні експерта, неправильне регулювання, ймовірно, " +"призведе до заклинювання, подрібнення екструдерного колеса до філаменту тощо." -#: src/slic3r/GUI/WipeTowerDialog.cpp:82 +#: src/slic3r/GUI/WipeTowerDialog.cpp:83 msgid "Total ramming time" -msgstr "" +msgstr "Загальний час швидкої екструзії" -#: src/slic3r/GUI/WipeTowerDialog.cpp:84 +#: src/slic3r/GUI/WipeTowerDialog.cpp:85 msgid "Total rammed volume" -msgstr "" +msgstr "Загальний обсяг швидкої екструзії" -#: src/slic3r/GUI/WipeTowerDialog.cpp:88 +#: src/slic3r/GUI/WipeTowerDialog.cpp:89 msgid "Ramming line width" -msgstr "" +msgstr "Ширина ліній раммінгу" -#: src/slic3r/GUI/WipeTowerDialog.cpp:90 +#: src/slic3r/GUI/WipeTowerDialog.cpp:91 msgid "Ramming line spacing" -msgstr "" +msgstr "Проміжки між лініями раммінгу" -#: src/slic3r/GUI/WipeTowerDialog.cpp:141 +#: src/slic3r/GUI/WipeTowerDialog.cpp:142 msgid "Wipe tower - Purging volume adjustment" -msgstr "" +msgstr "Вежа витирання - Регулювання об'єму продувки" -#: src/slic3r/GUI/WipeTowerDialog.cpp:225 +#: src/slic3r/GUI/WipeTowerDialog.cpp:254 msgid "" "Here you can adjust required purging volume (mm³) for any given pair of " "tools." msgstr "" +"Тут ви можете відрегулювати необхідний об'єм витирання (мм³) для будь-якої " +"пари інструментів." -#: src/slic3r/GUI/WipeTowerDialog.cpp:226 +#: src/slic3r/GUI/WipeTowerDialog.cpp:255 msgid "Extruder changed to" -msgstr "" +msgstr "Екструдер змінено на" -#: src/slic3r/GUI/WipeTowerDialog.cpp:234 +#: src/slic3r/GUI/WipeTowerDialog.cpp:263 msgid "unloaded" -msgstr "" +msgstr "виведено" -#: src/slic3r/GUI/WipeTowerDialog.cpp:235 +#: src/slic3r/GUI/WipeTowerDialog.cpp:264 msgid "loaded" -msgstr "" +msgstr "заведено" -#: src/slic3r/GUI/WipeTowerDialog.cpp:240 +#: src/slic3r/GUI/WipeTowerDialog.cpp:276 msgid "Tool #" -msgstr "" +msgstr "Інструмент №" -#: src/slic3r/GUI/WipeTowerDialog.cpp:247 +#: src/slic3r/GUI/WipeTowerDialog.cpp:285 msgid "" "Total purging volume is calculated by summing two values below, depending on " "which tools are loaded/unloaded." msgstr "" +"Загальний об'єм витирання обчислюється шляхом підсумовування двох значень " +"нижче, залежно від того, який інструмент заведено/виведено." -#: src/slic3r/GUI/WipeTowerDialog.cpp:248 +#: src/slic3r/GUI/WipeTowerDialog.cpp:286 msgid "Volume to purge (mm³) when the filament is being" -msgstr "" +msgstr "Об'єм для витирання (мм³) при наявності філаменту" -#: src/slic3r/GUI/WipeTowerDialog.cpp:262 +#: src/slic3r/GUI/WipeTowerDialog.cpp:300 msgid "From" -msgstr "" +msgstr "Від" -#: src/slic3r/GUI/WipeTowerDialog.cpp:327 +#: src/slic3r/GUI/WipeTowerDialog.cpp:365 msgid "" "Switching to simple settings will discard changes done in the advanced " "mode!\n" "\n" "Do you want to proceed?" msgstr "" +"Перехід в простий режим налаштувань призведе до скасування змін, здійснених " +"у розширеному режимі!\n" +"\n" +"Хочете продовжити?" -#: src/slic3r/GUI/WipeTowerDialog.cpp:339 +#: src/slic3r/GUI/WipeTowerDialog.cpp:377 msgid "Show simplified settings" -msgstr "" +msgstr "Показати спрощені налаштування" -#: src/slic3r/GUI/WipeTowerDialog.cpp:339 +#: src/slic3r/GUI/WipeTowerDialog.cpp:377 msgid "Show advanced settings" -msgstr "" +msgstr "Показати розширені налаштування" -#: src/slic3r/GUI/wxExtensions.cpp:2398 +#: src/slic3r/GUI/wxExtensions.cpp:627 #, c-format msgid "Switch to the %s mode" msgstr "Перейти до режиму %s" -#: src/slic3r/GUI/wxExtensions.cpp:2399 +#: src/slic3r/GUI/wxExtensions.cpp:628 #, c-format msgid "Current mode is %s" msgstr "Поточний режим - %s" -#: src/slic3r/Utils/Duet.cpp:51 -msgid "Connection to Duet works correctly." -msgstr "" - -#: src/slic3r/Utils/Duet.cpp:56 -msgid "Could not connect to Duet" -msgstr "" - -#: src/slic3r/Utils/Duet.cpp:84 src/slic3r/Utils/Duet.cpp:154 -msgid "Unknown error occured" -msgstr "" - -#: src/slic3r/Utils/Duet.cpp:148 -msgid "Wrong password" -msgstr "" - -#: src/slic3r/Utils/Duet.cpp:151 -msgid "Could not get resources to create a new connection" -msgstr "" - -#: src/slic3r/Utils/OctoPrint.cpp:69 +#: src/slic3r/Utils/AstroBox.cpp:69 src/slic3r/Utils/OctoPrint.cpp:68 #, c-format msgid "Mismatched type of print host: %s" -msgstr "" +msgstr "Несумісний тип хосту друку: %s" -#: src/slic3r/Utils/OctoPrint.cpp:84 -msgid "Connection to OctoPrint works correctly." +#: src/slic3r/Utils/AstroBox.cpp:84 +msgid "Connection to AstroBox works correctly." msgstr "Підключення до OctoPrint працює правильно." -#: src/slic3r/Utils/OctoPrint.cpp:90 -msgid "Could not connect to OctoPrint" -msgstr "" +#: src/slic3r/Utils/AstroBox.cpp:90 +msgid "Could not connect to AstroBox" +msgstr "Не можливо підключитися до AstroBox" -#: src/slic3r/Utils/OctoPrint.cpp:90 -msgid "Note: OctoPrint version at least 1.1.0 is required." -msgstr "" +#: src/slic3r/Utils/AstroBox.cpp:92 +msgid "Note: AstroBox version at least 1.1.0 is required." +msgstr "Примітка: Потрібна версія AstroBox принаймні 1.1.0." -#: src/slic3r/Utils/OctoPrint.cpp:195 -msgid "Connection to Prusa SLA works correctly." -msgstr "" +#: src/slic3r/Utils/Duet.cpp:47 +msgid "Connection to Duet works correctly." +msgstr "Підключення до Duet працює правильно." -#: src/slic3r/Utils/OctoPrint.cpp:200 -msgid "Could not connect to Prusa SLA" -msgstr "" +#: src/slic3r/Utils/Duet.cpp:53 +msgid "Could not connect to Duet" +msgstr "Не можливо підключитися до Duet" -#: src/slic3r/Utils/PresetUpdater.cpp:583 -#, c-format -msgid "requires min. %s and max. %s" -msgstr "" +#: src/slic3r/Utils/Duet.cpp:88 src/slic3r/Utils/Duet.cpp:151 +#: src/slic3r/Utils/FlashAir.cpp:122 src/slic3r/Utils/FlashAir.cpp:143 +#: src/slic3r/Utils/FlashAir.cpp:159 +msgid "Unknown error occured" +msgstr "Сталася невідома помилка" -#: src/slic3r/Utils/PresetUpdater.cpp:588 -#, c-format -msgid "requires min. %s" -msgstr "" +#: src/slic3r/Utils/Duet.cpp:145 +msgid "Wrong password" +msgstr "Неправильний пароль" -#: src/slic3r/Utils/PresetUpdater.cpp:590 -#, c-format -msgid "requires max. %s" -msgstr "" +#: src/slic3r/Utils/Duet.cpp:148 +msgid "Could not get resources to create a new connection" +msgstr "Не вдалося отримати ресурси для створення нового з’єднання" #: src/slic3r/Utils/FixModelByWin10.cpp:219 #: src/slic3r/Utils/FixModelByWin10.cpp:359 msgid "Exporting source model" -msgstr "" +msgstr "Експортування вихідної моделі" #: src/slic3r/Utils/FixModelByWin10.cpp:235 msgid "Failed loading the input model." -msgstr "" +msgstr "Помилка завантаження вхідної моделі." #: src/slic3r/Utils/FixModelByWin10.cpp:242 msgid "Repairing model by the Netfabb service" -msgstr "" +msgstr "Відновлення моделі службою Netfabb" #: src/slic3r/Utils/FixModelByWin10.cpp:248 msgid "Mesh repair failed." -msgstr "" +msgstr "Не вдалося відновити сітку." #: src/slic3r/Utils/FixModelByWin10.cpp:251 #: src/slic3r/Utils/FixModelByWin10.cpp:378 msgid "Loading repaired model" -msgstr "" +msgstr "Завантаження відремонтованої моделі" #: src/slic3r/Utils/FixModelByWin10.cpp:263 #: src/slic3r/Utils/FixModelByWin10.cpp:270 #: src/slic3r/Utils/FixModelByWin10.cpp:302 msgid "Saving mesh into the 3MF container failed." -msgstr "" +msgstr "Не вдалося зберегти сітку в контейнері 3MF." #: src/slic3r/Utils/FixModelByWin10.cpp:340 msgid "Model fixing" -msgstr "" +msgstr "Ремонт моделі" #: src/slic3r/Utils/FixModelByWin10.cpp:341 -msgid "Exporting model..." -msgstr "" +msgid "Exporting model" +msgstr "Експортування моделі" #: src/slic3r/Utils/FixModelByWin10.cpp:368 msgid "Export of a temporary 3mf file failed" -msgstr "" +msgstr "Не вдалося експортувати тимчасовий 3MF-файл" #: src/slic3r/Utils/FixModelByWin10.cpp:383 msgid "Import of the repaired 3mf file failed" -msgstr "" +msgstr "Не вдалося імпортувати відновлений 3MF-файл" #: src/slic3r/Utils/FixModelByWin10.cpp:385 msgid "Repaired 3MF file does not contain any object" -msgstr "" +msgstr "Відновлений 3MF-файл не містить жодного об'єкта" #: src/slic3r/Utils/FixModelByWin10.cpp:387 msgid "Repaired 3MF file contains more than one object" -msgstr "" +msgstr "Відновлений 3MF-файл містить більше одного об'єкта" #: src/slic3r/Utils/FixModelByWin10.cpp:389 msgid "Repaired 3MF file does not contain any volume" -msgstr "" +msgstr "Відновлений 3MF-файл не містить жодної часті" #: src/slic3r/Utils/FixModelByWin10.cpp:391 msgid "Repaired 3MF file contains more than one volume" -msgstr "" +msgstr "Відновлений 3MF-файл містить більше однієї часті" #: src/slic3r/Utils/FixModelByWin10.cpp:400 msgid "Model repair finished" -msgstr "" +msgstr "Ремонт моделі завершено" #: src/slic3r/Utils/FixModelByWin10.cpp:406 msgid "Model repair canceled" -msgstr "" +msgstr "Ремонт моделі скасовано" #: src/slic3r/Utils/FixModelByWin10.cpp:423 msgid "Model repaired successfully" -msgstr "" +msgstr "Модель успішно відремонтована" #: src/slic3r/Utils/FixModelByWin10.cpp:423 #: src/slic3r/Utils/FixModelByWin10.cpp:426 msgid "Model Repair by the Netfabb service" -msgstr "" +msgstr "Ремонт моделі сервісом Netfabb" #: src/slic3r/Utils/FixModelByWin10.cpp:426 -msgid "Model repair failed: \n" -msgstr "" +msgid "Model repair failed:" +msgstr "Не вдалося відремонтувати модель:" -#: src/libslic3r/Zipper.cpp:35 +#: src/slic3r/Utils/FlashAir.cpp:58 +msgid "Upload not enabled on FlashAir card." +msgstr "Завантаження не ввімкнено на картці FlashAir." + +#: src/slic3r/Utils/FlashAir.cpp:68 +msgid "Connection to FlashAir works correctly and upload is enabled." +msgstr "Підключення до FlashAir працює правильно, і завантаження ввімкнено." + +#: src/slic3r/Utils/FlashAir.cpp:74 +msgid "Could not connect to FlashAir" +msgstr "Не можливо підключитися до FlashAir" + +#: src/slic3r/Utils/FlashAir.cpp:76 +msgid "" +"Note: FlashAir with firmware 2.00.02 or newer and activated upload function " +"is required." +msgstr "" +"Примітка: Потрібна FlashAir із прошивкою 2.00.02 або новішою та активованою " +"функцією завантаження." + +#: src/slic3r/Utils/OctoPrint.cpp:83 +msgid "Connection to OctoPrint works correctly." +msgstr "Підключення до OctoPrint працює правильно." + +#: src/slic3r/Utils/OctoPrint.cpp:89 +msgid "Could not connect to OctoPrint" +msgstr "Не можливо підключитися до OctoPrint" + +#: src/slic3r/Utils/OctoPrint.cpp:91 +msgid "Note: OctoPrint version at least 1.1.0 is required." +msgstr "Зауважте: Необхідна версія OctoPrint - принаймні 1.1.0." + +#: src/slic3r/Utils/OctoPrint.cpp:185 +msgid "Connection to Prusa SL1 works correctly." +msgstr "Підключення до Prusa SL1 працює правильно." + +#: src/slic3r/Utils/OctoPrint.cpp:191 +msgid "Could not connect to Prusa SLA" +msgstr "Не можливо підключитися до Prusa SLA" + +#: src/slic3r/Utils/PresetUpdater.cpp:727 +#, c-format +msgid "requires min. %s and max. %s" +msgstr "вимагається мін. %s та макс. %s" + +#: src/slic3r/Utils/PresetUpdater.cpp:731 +#, c-format +msgid "requires min. %s" +msgstr "вимагається мін. %s" + +#: src/slic3r/Utils/PresetUpdater.cpp:734 +#, c-format +msgid "requires max. %s" +msgstr "вимагається макс. %s" + +#: src/slic3r/Utils/Http.cpp:73 +msgid "" +"Could not detect system SSL certificate store. PrusaSlicer will be unable to " +"establish secure network connections." +msgstr "" +"Не вдалося виявити системе сховище SSL сертифікатів. PrusaSlicer не зможе " +"встановити безпечні мережеві з'єднання." + +#: src/slic3r/Utils/Http.cpp:78 +msgid "PrusaSlicer detected system SSL certificate store in: %1%" +msgstr "PrusaSlicer виявив системне сховище сертифікатів SSL у: %1%" + +#: src/slic3r/Utils/Http.cpp:82 +msgid "" +"To specify the system certificate store manually, please set the %1% " +"environment variable to the correct CA bundle and restart the application." +msgstr "" +"Щоб вказати системне сховище сертифікатів вручну, встановіть змінну " +"середовища %1% на правильний пакет CA і перезапустіть програму." + +#: src/slic3r/Utils/Http.cpp:91 +msgid "" +"CURL init has failed. PrusaSlicer will be unable to establish network " +"connections. See logs for additional details." +msgstr "" +"Curl init зазнав невдачі. PrusaSlicer не зможе встановити мережні " +"підключення. Додаткові відомості див." + +#: src/slic3r/Utils/Process.cpp:151 +msgid "Open G-code file:" +msgstr "Відкрити файл G-кода:" + +#: src/libslic3r/GCode.cpp:518 +msgid "There is an object with no extrusions on the first layer." +msgstr "Виявлено об'єкт без екструзії на першому шарі." + +#: src/libslic3r/GCode.cpp:536 +msgid "Empty layers detected, the output would not be printable." +msgstr "Виявлено порожні шари, вихідні дані не можна надрукувати." + +#: src/libslic3r/GCode.cpp:537 +msgid "Print z" +msgstr "Друк на висоті" + +#: src/libslic3r/GCode.cpp:538 +msgid "" +"This is usually caused by negligibly small extrusions or by a faulty model. " +"Try to repair the model or change its orientation on the bed." +msgstr "" +"Зазвичай це спричинено мізерно малою екструзією або несправністю моделі. " +"Спробуйте відремонтувати модель або змінити її орієнтацію на столі." + +#: src/libslic3r/GCode.cpp:1261 +msgid "" +"Your print is very close to the priming regions. Make sure there is no " +"collision." +msgstr "" +"Ваша модель для друку розташована дуже близький до основних областей. " +"Переконайтесь, що немає зіткнення." + +#: src/libslic3r/ExtrusionEntity.cpp:324 src/libslic3r/ExtrusionEntity.cpp:360 +msgid "Mixed" +msgstr "Змішаний" + +#: src/libslic3r/Flow.cpp:61 +msgid "" +"Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible." +msgstr "" +"Не вдається розрахувати ширину екструзії для %1%: Змінна \"%2%\" недоступна." + +#: src/libslic3r/Format/3mf.cpp:1668 +msgid "" +"The selected 3mf file has been saved with a newer version of %1% and is not " +"compatible." +msgstr "Вибраний 3MF-файл було збережено з новою версією %1% і не сумісний." + +#: src/libslic3r/Format/AMF.cpp:958 +msgid "" +"The selected amf file has been saved with a newer version of %1% and is not " +"compatible." +msgstr "Вибраний АMF-файл було збережено з новою версією %1% і не сумісний." + +#: src/libslic3r/miniz_extension.cpp:91 msgid "undefined error" -msgstr "" +msgstr "невизначена помилка" -#: src/libslic3r/Zipper.cpp:37 +#: src/libslic3r/miniz_extension.cpp:93 msgid "too many files" -msgstr "" +msgstr "забагато файлів" -#: src/libslic3r/Zipper.cpp:39 +#: src/libslic3r/miniz_extension.cpp:95 msgid "file too large" -msgstr "" +msgstr "файл занадто великий" -#: src/libslic3r/Zipper.cpp:41 +#: src/libslic3r/miniz_extension.cpp:97 msgid "unsupported method" -msgstr "" +msgstr "непідтримуваний метод" -#: src/libslic3r/Zipper.cpp:43 +#: src/libslic3r/miniz_extension.cpp:99 msgid "unsupported encryption" -msgstr "" +msgstr "непідтримуване шифрування" -#: src/libslic3r/Zipper.cpp:45 +#: src/libslic3r/miniz_extension.cpp:101 msgid "unsupported feature" -msgstr "" +msgstr "непідтримувана функція" -#: src/libslic3r/Zipper.cpp:47 +#: src/libslic3r/miniz_extension.cpp:103 msgid "failed finding central directory" -msgstr "" +msgstr "не вдалося знайти центральний каталог" -#: src/libslic3r/Zipper.cpp:49 +#: src/libslic3r/miniz_extension.cpp:105 msgid "not a ZIP archive" -msgstr "" +msgstr "не ZIP-архів" -#: src/libslic3r/Zipper.cpp:51 +#: src/libslic3r/miniz_extension.cpp:107 msgid "invalid header or archive is corrupted" -msgstr "" +msgstr "недійсний заголовок або архів пошкоджено" -#: src/libslic3r/Zipper.cpp:53 +#: src/libslic3r/miniz_extension.cpp:109 msgid "unsupported multidisk archive" -msgstr "" +msgstr "непідтримуваний багатодисковий архів" -#: src/libslic3r/Zipper.cpp:55 +#: src/libslic3r/miniz_extension.cpp:111 msgid "decompression failed or archive is corrupted" -msgstr "" +msgstr "не вдалося розпакувати або архів пошкоджено" -#: src/libslic3r/Zipper.cpp:57 +#: src/libslic3r/miniz_extension.cpp:113 msgid "compression failed" -msgstr "" +msgstr "помилка компресії" -#: src/libslic3r/Zipper.cpp:59 +#: src/libslic3r/miniz_extension.cpp:115 msgid "unexpected decompressed size" -msgstr "" +msgstr "несподіваний розпакований розмір" -#: src/libslic3r/Zipper.cpp:61 +#: src/libslic3r/miniz_extension.cpp:117 msgid "CRC-32 check failed" -msgstr "" +msgstr "Помилка перевірки CRC-32" -#: src/libslic3r/Zipper.cpp:63 +#: src/libslic3r/miniz_extension.cpp:119 msgid "unsupported central directory size" -msgstr "" +msgstr "непідтримуваний розмір центрального каталогу" -#: src/libslic3r/Zipper.cpp:65 +#: src/libslic3r/miniz_extension.cpp:121 msgid "allocation failed" -msgstr "" +msgstr "розміщення не вдався" -#: src/libslic3r/Zipper.cpp:67 +#: src/libslic3r/miniz_extension.cpp:123 msgid "file open failed" -msgstr "" +msgstr "не вдалося відкрити файл" -#: src/libslic3r/Zipper.cpp:69 +#: src/libslic3r/miniz_extension.cpp:125 msgid "file create failed" -msgstr "" +msgstr "не вдалося створити файл" -#: src/libslic3r/Zipper.cpp:71 +#: src/libslic3r/miniz_extension.cpp:127 msgid "file write failed" -msgstr "" +msgstr "не вдалося записати файл" -#: src/libslic3r/Zipper.cpp:73 +#: src/libslic3r/miniz_extension.cpp:129 msgid "file read failed" -msgstr "" +msgstr "не вдалося прочитати файл" -#: src/libslic3r/Zipper.cpp:75 +#: src/libslic3r/miniz_extension.cpp:131 msgid "file close failed" -msgstr "" +msgstr "не вдалося закрити файл" -#: src/libslic3r/Zipper.cpp:77 +#: src/libslic3r/miniz_extension.cpp:133 msgid "file seek failed" -msgstr "" +msgstr "пошук файлу не вдався" -#: src/libslic3r/Zipper.cpp:79 +#: src/libslic3r/miniz_extension.cpp:135 msgid "file stat failed" -msgstr "" +msgstr "не вдалося відкрити STAT-файл" -#: src/libslic3r/Zipper.cpp:81 +#: src/libslic3r/miniz_extension.cpp:137 msgid "invalid parameter" -msgstr "" +msgstr "некоректний параметр" -#: src/libslic3r/Zipper.cpp:83 +#: src/libslic3r/miniz_extension.cpp:139 msgid "invalid filename" -msgstr "" +msgstr "некоректне ім'я файлу" -#: src/libslic3r/Zipper.cpp:85 +#: src/libslic3r/miniz_extension.cpp:141 msgid "buffer too small" -msgstr "" +msgstr "занадто малий буфер" -#: src/libslic3r/Zipper.cpp:87 +#: src/libslic3r/miniz_extension.cpp:143 msgid "internal error" -msgstr "" +msgstr "внутрішня помилка" -#: src/libslic3r/Zipper.cpp:89 +#: src/libslic3r/miniz_extension.cpp:145 msgid "file not found" -msgstr "" +msgstr "файл не знайдено" -#: src/libslic3r/Zipper.cpp:91 +#: src/libslic3r/miniz_extension.cpp:147 msgid "archive is too large" -msgstr "" +msgstr "архів завеликий" -#: src/libslic3r/Zipper.cpp:93 +#: src/libslic3r/miniz_extension.cpp:149 msgid "validation failed" -msgstr "" +msgstr "не вдалося перевірити" -#: src/libslic3r/Zipper.cpp:95 +#: src/libslic3r/miniz_extension.cpp:151 msgid "write calledback failed" -msgstr "" +msgstr "помилка запису зворотного виклику" -#: src/libslic3r/Zipper.cpp:105 -msgid "Error with zip archive" -msgstr "" +#: src/libslic3r/Preset.cpp:1299 +msgid "filament" +msgstr "філамент" -#: src/libslic3r/SLA/SLASupportTree.cpp:2153 -msgid "Starting" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2154 -msgid "Filtering" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2155 -msgid "Generate pinheads" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2156 -msgid "Classification" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2157 -msgid "Routing to ground" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2158 -msgid "Routing supports to model surface" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2159 -msgid "Cascading pillars" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2160 -msgid "Processing small holes" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2161 -msgid "Done" -msgstr "" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2162 -msgid "Abort" -msgstr "" - -#: src/libslic3r/Print.cpp:1136 +#: src/libslic3r/Print.cpp:1251 msgid "All objects are outside of the print volume." -msgstr "" +msgstr "Усі об'єкти знаходяться поза просторем друку." -#: src/libslic3r/Print.cpp:1165 +#: src/libslic3r/Print.cpp:1254 +msgid "The supplied settings will cause an empty print." +msgstr "Надані параметри спричинять порожній друк." + +#: src/libslic3r/Print.cpp:1258 msgid "Some objects are too close; your extruder will collide with them." msgstr "" +"Деякі предмети розташовано занадто близько; ваш екструдер зіткнеться з ними." -#: src/libslic3r/Print.cpp:1180 +#: src/libslic3r/Print.cpp:1260 msgid "" "Some objects are too tall and cannot be printed without extruder collisions." msgstr "" +"Деякі предмети занадто високі, і їх неможливо надрукувати без зіткнення " +"екструдера." -#: src/libslic3r/Print.cpp:1190 -msgid "The Spiral Vase option can only be used when printing a single object." +#: src/libslic3r/Print.cpp:1269 +msgid "" +"Only a single object may be printed at a time in Spiral Vase mode. Either " +"remove all but the last object, or enable sequential mode by " +"\"complete_objects\"." msgstr "" +"Одночасно в режимі спіральної вази можна друкувати лише один об’єкт. Або " +"видаліть усі, крім останнього об'єкта, або ввімкніть послідовний режим за " +"допомогою \"повних об'єктів\" (\"complete_objects\")." -#: src/libslic3r/Print.cpp:1192 +#: src/libslic3r/Print.cpp:1277 msgid "" "The Spiral Vase option can only be used when printing single material " "objects." msgstr "" +"Варіант спіральної вази можна використовувати лише під час друку одно-" +"матеріальних об’єктів." -#: src/libslic3r/Print.cpp:1198 +#: src/libslic3r/Print.cpp:1290 msgid "" -"All extruders must have the same diameter for single extruder multimaterial " -"printer." +"The wipe tower is only supported if all extruders have the same nozzle " +"diameter and use filaments of the same diameter." msgstr "" +"Вежа витирання підтримується лише в тому випадку, якщо всі екструдери мають " +"однаковий діаметр сопла і використовують філаменти одинакового діаметру." -#: src/libslic3r/Print.cpp:1203 +#: src/libslic3r/Print.cpp:1296 msgid "" -"The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter " -"and Repetier G-code flavors." +"The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, " +"RepRapFirmware and Repetier G-code flavors." msgstr "" +"Наразі вежа витирання підтримується лише для G-кодів, сумісних з Marlin, " +"RepRap/Sprinter, RepRapFirmware та Repetier ." -#: src/libslic3r/Print.cpp:1205 +#: src/libslic3r/Print.cpp:1298 msgid "" "The Wipe Tower is currently only supported with the relative extruder " "addressing (use_relative_e_distances=1)." msgstr "" +"Наразі вежа витирання підтримує лише відносну адресацію екструдерів " +"(use_relative_e_distances = 1)." -#: src/libslic3r/Print.cpp:1226 +#: src/libslic3r/Print.cpp:1300 +msgid "Ooze prevention is currently not supported with the wipe tower enabled." +msgstr "" +"Наразі запобігання просочування не підтримується з увімкненою вежею " +"витирання." + +#: src/libslic3r/Print.cpp:1302 +msgid "" +"The Wipe Tower currently does not support volumetric E (use_volumetric_e=0)." +msgstr "Наразі вежа витирання не підтримує об'ємне E (use_volumetric_e = 0)." + +#: src/libslic3r/Print.cpp:1304 +msgid "" +"The Wipe Tower is currently not supported for multimaterial sequential " +"prints." +msgstr "" +"Наразі вежа витирання не підтримується для багато-матеріального послідовного " +"друку." + +#: src/libslic3r/Print.cpp:1325 msgid "" "The Wipe Tower is only supported for multiple objects if they have equal " -"layer heigths" +"layer heights" msgstr "" +"Вежа витирання для кількох об’єктів підтримується лише у випадку, коли вони " +"мають однакову висоту шару" -#: src/libslic3r/Print.cpp:1228 +#: src/libslic3r/Print.cpp:1327 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "over an equal number of raft layers" msgstr "" +"Вежа витирання для кількох об’єктів підтримується лише у випадку, коли вони " +"надруковані на рівній кількості шарів плоту" -#: src/libslic3r/Print.cpp:1230 +#: src/libslic3r/Print.cpp:1329 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "with the same support_material_contact_distance" msgstr "" +"Вежа витирання для кількох об’єктів підтримується лише у випадку, коли вони " +"надруковані з однаковою відстанню support_material_contact_distance" -#: src/libslic3r/Print.cpp:1232 +#: src/libslic3r/Print.cpp:1331 msgid "" "The Wipe Tower is only supported for multiple objects if they are sliced " "equally." msgstr "" +"Вежа витирання для кількох об’єктів підтримується лише у випадку, коли вони " +"нарізані однаково." -#: src/libslic3r/Print.cpp:1261 +#: src/libslic3r/Print.cpp:1373 msgid "" -"The Wipe tower is only supported if all objects have the same layer height " -"profile" +"The Wipe tower is only supported if all objects have the same variable layer " +"height" msgstr "" +"Вежа витирання підтримується лише в тому випадку, якщо всі об’єкти мають " +"однакову висоту змінного шару" -#: src/libslic3r/Print.cpp:1271 -msgid "The supplied settings will cause an empty print." -msgstr "" - -#: src/libslic3r/Print.cpp:1288 +#: src/libslic3r/Print.cpp:1399 msgid "" "One or more object were assigned an extruder that the printer does not have." msgstr "" +"Одному або декільком об’єктам було призначено екструдер, якого принтер не " +"має." -#: src/libslic3r/Print.cpp:1297 +#: src/libslic3r/Print.cpp:1408 +msgid "%1%=%2% mm is too low to be printable at a layer height %3% mm" +msgstr "%1%=%2% мм є занадто низьким для друку на висоті шару %3% мм" + +#: src/libslic3r/Print.cpp:1411 +msgid "Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm" +msgstr "%1% = %2% мм є надмірно для друку з діаметром сопла %3% мм" + +#: src/libslic3r/Print.cpp:1422 msgid "" "Printing with multiple extruders of differing nozzle diameters. If support " "is to be printed with the current extruder (support_material_extruder == 0 " "or support_material_interface_extruder == 0), all nozzles have to be of the " "same diameter." msgstr "" +"Друк за допомогою декількох екструдерів різного діаметру сопла. Якщо " +"підтримки слід друкувати поточним екструдерем (support_material_extruder == " +"0 або support_material_interface_extruder == 0), усі сопла повинні мати " +"однаковий діаметр." -#: src/libslic3r/Print.cpp:1305 +#: src/libslic3r/Print.cpp:1430 msgid "" "For the Wipe Tower to work with the soluble supports, the support layers " "need to be synchronized with the object layers." msgstr "" +"Для того, щоб вежа витирання працювала з розчинними підтримками, шари " +"підтримки повинні бути синхронізовані з шарами об'єкта." -#: src/libslic3r/Print.cpp:1309 +#: src/libslic3r/Print.cpp:1434 msgid "" "The Wipe Tower currently supports the non-soluble supports only if they are " "printed with the current extruder without triggering a tool change. (both " "support_material_extruder and support_material_interface_extruder need to be " "set to 0)." msgstr "" +"Вежа витирання в даний момент підтримує лише нерозчинні підтримки, якщо вони " +"друкуються з поточним екструдером, не запускаючи зміну інструменту. (Обидва " +"значення support_material_extruder і support_material_interface_extruder " +"повинні бути встановлені на 0)." -#: src/libslic3r/Print.cpp:1316 -msgid "first_layer_height" -msgstr "" - -#: src/libslic3r/Print.cpp:1331 +#: src/libslic3r/Print.cpp:1456 msgid "First layer height can't be greater than nozzle diameter" -msgstr "" +msgstr "Висота першого шару не може перевищувати діаметр сопла" -#: src/libslic3r/Print.cpp:1335 +#: src/libslic3r/Print.cpp:1461 msgid "Layer height can't be greater than nozzle diameter" -msgstr "" +msgstr "Висота шару не може перевищувати діаметр сопла" -#: src/libslic3r/SLAPrint.cpp:55 -msgid "Slicing model" -msgstr "" +#: src/libslic3r/Print.cpp:1620 +msgid "Infilling layers" +msgstr "Шари наповнення" -#: src/libslic3r/SLAPrint.cpp:56 src/libslic3r/SLAPrint.cpp:801 -msgid "Generating support points" -msgstr "" +#: src/libslic3r/Print.cpp:1646 +msgid "Generating skirt" +msgstr "Генерування спідниці" -#: src/libslic3r/SLAPrint.cpp:57 -msgid "Generating support tree" -msgstr "" +#: src/libslic3r/Print.cpp:1655 +msgid "Generating brim" +msgstr "Генерування краю" -#: src/libslic3r/SLAPrint.cpp:58 -msgid "Generating pad" -msgstr "" +#: src/libslic3r/Print.cpp:1678 +msgid "Exporting G-code" +msgstr "Експортування G-коду" -#: src/libslic3r/SLAPrint.cpp:59 -msgid "Slicing supports" -msgstr "" +#: src/libslic3r/Print.cpp:1682 +msgid "Generating G-code" +msgstr "Генерування G-коду" -#: src/libslic3r/SLAPrint.cpp:71 -msgid "Merging slices and calculating statistics" -msgstr "" +#: src/libslic3r/SLA/Pad.cpp:532 +msgid "Pad brim size is too small for the current configuration." +msgstr "Розмір краю подушки замалий для поточної конфігурації." -#: src/libslic3r/SLAPrint.cpp:72 -msgid "Rasterizing layers" -msgstr "" - -#: src/libslic3r/SLAPrint.cpp:605 +#: src/libslic3r/SLAPrint.cpp:630 msgid "" "Cannot proceed without support points! Add support points or disable support " "generation." msgstr "" +"Не можливо продовжувати без точок підтримки! Додайте точки підтримки або " +"вимкніть генерацію підтримки." -#: src/libslic3r/SLAPrint.cpp:617 -msgid "Elevation is too low for object." +#: src/libslic3r/SLAPrint.cpp:642 +msgid "" +"Elevation is too low for object. Use the \"Pad around object\" feature to " +"print the object without elevation." msgstr "" +"Підняття занадто мале для об'єкта. Використовуйте функцію \"Подушка навколо " +"об'єкта\" для друку об'єкта без підняття." -#: src/libslic3r/SLAPrint.cpp:699 -msgid "Slicing had to be stopped due to an internal error." +#: src/libslic3r/SLAPrint.cpp:648 +msgid "" +"The endings of the support pillars will be deployed on the gap between the " +"object and the pad. 'Support base safety distance' has to be greater than " +"the 'Pad object gap' parameter to avoid this." msgstr "" +"Кінці стовпів підтримок будуть розміщені на зазорі між об'єктом і подушкою. " +"\"Безпечна відстань між основами підтримки\" повинна бути більшою за " +"параметр \"Розрив Подушка-Об'єкт\", щоб уникнути цього." -#: src/libslic3r/SLAPrint.cpp:849 src/libslic3r/SLAPrint.cpp:859 -#: src/libslic3r/SLAPrint.cpp:907 -msgid "Visualizing supports" -msgstr "" +#: src/libslic3r/SLAPrint.cpp:663 +msgid "Exposition time is out of printer profile bounds." +msgstr "Час експозиції виходить за межі профілю принтера." -#: src/libslic3r/SLAPrint.cpp:1449 +#: src/libslic3r/SLAPrint.cpp:670 +msgid "Initial exposition time is out of printer profile bounds." +msgstr "Початковий час експозиції виходить за межі профілю принтера." + +#: src/libslic3r/SLAPrint.cpp:786 msgid "Slicing done" -msgstr "" +msgstr "Нарізання завершено" -#: src/libslic3r/PrintBase.cpp:65 +#: src/libslic3r/SLAPrintSteps.cpp:44 +msgid "Hollowing model" +msgstr "Випорожнення моделі" + +#: src/libslic3r/SLAPrintSteps.cpp:45 +msgid "Drilling holes into model." +msgstr "Свердління отворів в моделі." + +#: src/libslic3r/SLAPrintSteps.cpp:46 +msgid "Slicing model" +msgstr "Нарізання моделі" + +#: src/libslic3r/SLAPrintSteps.cpp:47 src/libslic3r/SLAPrintSteps.cpp:359 +msgid "Generating support points" +msgstr "Генерування точок підтримки" + +#: src/libslic3r/SLAPrintSteps.cpp:48 +msgid "Generating support tree" +msgstr "Генерування дерева підтримки" + +#: src/libslic3r/SLAPrintSteps.cpp:49 +msgid "Generating pad" +msgstr "Генерування подушки" + +#: src/libslic3r/SLAPrintSteps.cpp:50 +msgid "Slicing supports" +msgstr "Нарізання підтримок" + +#: src/libslic3r/SLAPrintSteps.cpp:65 +msgid "Merging slices and calculating statistics" +msgstr "Об'єднання шарів друку та обчислення статистики" + +#: src/libslic3r/SLAPrintSteps.cpp:66 +msgid "Rasterizing layers" +msgstr "Растеризуючі шари" + +#: src/libslic3r/SLAPrintSteps.cpp:192 +msgid "Too many overlapping holes." +msgstr "Забагато отворів, що перекриваються." + +#: src/libslic3r/SLAPrintSteps.cpp:201 +msgid "" +"Drilling holes into the mesh failed. This is usually caused by broken model. " +"Try to fix it first." +msgstr "" +"Не вдалося висвердлити отвори. Зазвичай це викликано зламаною моделлю. " +"Спершу спробуйте її виправити." + +#: src/libslic3r/SLAPrintSteps.cpp:247 +msgid "" +"Slicing had to be stopped due to an internal error: Inconsistent slice index." +msgstr "" +"Нарізання довелося зупинити через внутрішню помилку: Невідповідний індекс " +"зрізу." + +#: src/libslic3r/SLAPrintSteps.cpp:411 src/libslic3r/SLAPrintSteps.cpp:420 +#: src/libslic3r/SLAPrintSteps.cpp:459 +msgid "Visualizing supports" +msgstr "Візуалізація підтримки" + +#: src/libslic3r/SLAPrintSteps.cpp:451 +msgid "No pad can be generated for this model with the current configuration" +msgstr "" +"Для цієї моделі з поточною конфігурацією неможливо створити жодну подушку" + +#: src/libslic3r/SLAPrintSteps.cpp:619 +msgid "" +"There are unprintable objects. Try to adjust support settings to make the " +"objects printable." +msgstr "" +"Є об’єкти, що не друкуються. Спробуйте налаштувати параметри підтримки, щоб " +"зробити об’єкти для друку." + +#: src/libslic3r/PrintBase.cpp:72 msgid "Failed processing of the output_filename_format template." -msgstr "" +msgstr "Помилка обробки шаблону output_filename_format." -#: src/libslic3r/PrintConfig.cpp:42 src/libslic3r/PrintConfig.cpp:43 +#: src/libslic3r/PrintConfig.cpp:43 src/libslic3r/PrintConfig.cpp:44 msgid "Printer technology" -msgstr "" +msgstr "Технологія друку" -#: src/libslic3r/PrintConfig.cpp:50 +#: src/libslic3r/PrintConfig.cpp:51 msgid "Bed shape" -msgstr "Форма полотна" +msgstr "Форма столу" -#: src/libslic3r/PrintConfig.cpp:57 +#: src/libslic3r/PrintConfig.cpp:56 +msgid "Bed custom texture" +msgstr "Власна текстура столу" + +#: src/libslic3r/PrintConfig.cpp:61 +msgid "Bed custom model" +msgstr "Власна модель столу" + +#: src/libslic3r/PrintConfig.cpp:66 +msgid "G-code thumbnails" +msgstr "Ескізи G-коду" + +#: src/libslic3r/PrintConfig.cpp:67 +msgid "" +"Picture sizes to be stored into a .gcode and .sl1 files, in the following " +"format: \"XxY, XxY, ...\"" +msgstr "" +"Розміри зображень, які слід зберігати у файлах .gcode та .sl1, у такому " +"форматі: \"XxY, XxY, ...\"" + +#: src/libslic3r/PrintConfig.cpp:75 msgid "" "This setting controls the height (and thus the total number) of the slices/" "layers. Thinner layers give better accuracy but take more time to print." @@ -4480,52 +8871,118 @@ msgstr "" "Цей параметр визначає висоту (і, таким чином, загальну кількість) шарів. " "Тонкі шари забезпечують більшу точність, але для друку потрібно більше часу." -#: src/libslic3r/PrintConfig.cpp:64 +#: src/libslic3r/PrintConfig.cpp:82 msgid "Max print height" -msgstr "" +msgstr "Максимальна висота друку" -#: src/libslic3r/PrintConfig.cpp:65 +#: src/libslic3r/PrintConfig.cpp:83 msgid "" "Set this to the maximum height that can be reached by your extruder while " "printing." msgstr "" +"Встановіть це значення на максимальну висоту, якої може досягти ваш " +"екструдер під час друку." -#: src/libslic3r/PrintConfig.cpp:71 +#: src/libslic3r/PrintConfig.cpp:91 msgid "Slice gap closing radius" -msgstr "" +msgstr "Радіус закриття зазору зрізу" -#: src/libslic3r/PrintConfig.cpp:73 +#: src/libslic3r/PrintConfig.cpp:93 msgid "" "Cracks smaller than 2x gap closing radius are being filled during the " "triangle mesh slicing. The gap closing operation may reduce the final print " "resolution, therefore it is advisable to keep the value reasonably low." msgstr "" +"Тріщини з радіусом, меншим ніж 2 закриття зазору, заповнюються під час " +"нарізування трикутної сітки. Операція заповнення проміжку може зменшити " +"остаточну роздільну здатність друку, тому доцільно підтримувати значення на " +"досить низькому рівні." -#: src/libslic3r/PrintConfig.cpp:81 +#: src/libslic3r/PrintConfig.cpp:101 msgid "Hostname, IP or URL" -msgstr "" +msgstr "Ім'я хоста, IP або URL" -#: src/libslic3r/PrintConfig.cpp:82 +#: src/libslic3r/PrintConfig.cpp:102 msgid "" "Slic3r can upload G-code files to a printer host. This field should contain " -"the hostname, IP address or URL of the printer host instance." +"the hostname, IP address or URL of the printer host instance. Print host " +"behind HAProxy with basic auth enabled can be accessed by putting the user " +"name and password into the URL in the following format: https://username:" +"password@your-octopi-address/" msgstr "" +"Slic3r може завантажувати файли G-коду на хост принтера. Це поле повинно " +"містити ім’я хосту, IP-адресу або URL-адресу екземпляра хосту принтера. Хост " +"друку, що стоїть за HAProxy з увімкненою базовою автентифікацією, можна " +"отримати, ввівши ім’я користувача та пароль у URL-адресу у такому форматі: " +"https://username:password@your-octopi-address/" -#: src/libslic3r/PrintConfig.cpp:88 +#: src/libslic3r/PrintConfig.cpp:110 msgid "API Key / Password" -msgstr "" +msgstr "Ключ API / Пароль" -#: src/libslic3r/PrintConfig.cpp:89 +#: src/libslic3r/PrintConfig.cpp:111 msgid "" "Slic3r can upload G-code files to a printer host. This field should contain " "the API Key or the password required for authentication." msgstr "" +"Slic3r може завантажувати файли G-коду на хост принтера. Це поле повинно " +"містити ключ API або пароль, необхідний для автентифікації." -#: src/libslic3r/PrintConfig.cpp:111 +#: src/libslic3r/PrintConfig.cpp:118 +msgid "Name of the printer" +msgstr "Назва принтера" + +#: src/libslic3r/PrintConfig.cpp:125 +msgid "" +"Custom CA certificate file can be specified for HTTPS OctoPrint connections, " +"in crt/pem format. If left blank, the default OS CA certificate repository " +"is used." +msgstr "" +"Настроюваний файл сертифіката CA можна вказати для з'єднань HTTPS OctoPrint " +"у форматі crt/pem. Якщо залишити це поле порожнім, буде використано типове " +"сховище сертифікатів OS CA." + +#: src/libslic3r/PrintConfig.cpp:131 +msgid "Elephant foot compensation" +msgstr "Зрівноваження Стопи слона" + +#: src/libslic3r/PrintConfig.cpp:133 +msgid "" +"The first layer will be shrunk in the XY plane by the configured value to " +"compensate for the 1st layer squish aka an Elephant Foot effect." +msgstr "" +"Перший шар буде зменшено в площині XY завдяки налаштованому значенню, щоб " +"компенсувати ефект Ноги Слона для 1-го шару." + +#: src/libslic3r/PrintConfig.cpp:149 +msgid "Password" +msgstr "Пароль" + +#: src/libslic3r/PrintConfig.cpp:155 +msgid "Printer preset name" +msgstr "Назва пресету принтера" + +#: src/libslic3r/PrintConfig.cpp:156 +msgid "Related printer preset name" +msgstr "Назва пов’язаного пресету принтера" + +#: src/libslic3r/PrintConfig.cpp:161 +msgid "Authorization Type" +msgstr "Тип авторизації" + +#: src/libslic3r/PrintConfig.cpp:166 +msgid "API key" +msgstr "Ключ API" + +#: src/libslic3r/PrintConfig.cpp:167 +msgid "HTTP digest" +msgstr "Дайджест HTTP" + +#: src/libslic3r/PrintConfig.cpp:180 msgid "Avoid crossing perimeters" msgstr "Уникати перетинання периметрів" -#: src/libslic3r/PrintConfig.cpp:112 +#: src/libslic3r/PrintConfig.cpp:181 msgid "" "Optimize travel moves in order to minimize the crossing of perimeters. This " "is mostly useful with Bowden extruders which suffer from oozing. This " @@ -4535,37 +8992,57 @@ msgstr "" "основному це корисно для екструдерів Bowden, які страждають від протікання. " "Ця функція уповільнює як друк, так і генерацію G-коду." -#: src/libslic3r/PrintConfig.cpp:119 src/libslic3r/PrintConfig.cpp:1976 +#: src/libslic3r/PrintConfig.cpp:188 +msgid "Avoid crossing perimeters - Max detour length" +msgstr "Уникати перетинання периметрів - Макс. довжина обходу" + +#: src/libslic3r/PrintConfig.cpp:190 +msgid "" +"The maximum detour length for avoid crossing perimeters. If the detour is " +"longer than this value, avoid crossing perimeters is not applied for this " +"travel path. Detour length could be specified either as an absolute value or " +"as percentage (for example 50%) of a direct travel path." +msgstr "" +"Максимальна довжина обходу, щоб уникнути перетину периметрів. Якщо обхід " +"довший за це значення, уникнення перетину периметрів для цього шляху не " +"застосовується. Довжина обходу може бути вказана або як абсолютне значення, " +"або як відсоток (наприклад, 50%) від прямого шляху проходу." + +#: src/libslic3r/PrintConfig.cpp:193 +msgid "mm or % (zero to disable)" +msgstr "мм або % (0, щоб вимкнути)" + +#: src/libslic3r/PrintConfig.cpp:199 src/libslic3r/PrintConfig.cpp:2291 msgid "Other layers" msgstr "Інші шари" -#: src/libslic3r/PrintConfig.cpp:120 +#: src/libslic3r/PrintConfig.cpp:200 msgid "" "Bed temperature for layers after the first one. Set this to zero to disable " "bed temperature control commands in the output." msgstr "" -"Температура полотна для останніх шарів після першого. Установіть 0, щоб " -"відключити команди керування температурою полотна на виході." +"Температура столу для останніх шарів після першого. Установіть 0, щоб " +"відключити команди керування температурою столу на виході." -#: src/libslic3r/PrintConfig.cpp:122 +#: src/libslic3r/PrintConfig.cpp:203 msgid "Bed temperature" -msgstr "Температура полотна" +msgstr "Температура столу" -#: src/libslic3r/PrintConfig.cpp:129 +#: src/libslic3r/PrintConfig.cpp:210 msgid "" "This custom code is inserted at every layer change, right before the Z move. " "Note that you can use placeholder variables for all Slic3r settings as well " "as [layer_num] and [layer_z]." msgstr "" "Цей користувацький код вставляється при кожній зміні шару перед початком " -"переміщення Z. Зауважте, що ви можете використовувати змінні-заповнювачі для " +"переміщення Z. Зауважте, що ви можете використовувати шаблонні змінні для " "всіх параметрів Slic3r, а також [layer_num] і [layer_z]." -#: src/libslic3r/PrintConfig.cpp:139 +#: src/libslic3r/PrintConfig.cpp:220 msgid "Between objects G-code" msgstr "G-код між об'єктами" -#: src/libslic3r/PrintConfig.cpp:140 +#: src/libslic3r/PrintConfig.cpp:221 msgid "" "This code is inserted between objects when using sequential printing. By " "default extruder and bed temperature are reset using non-wait command; " @@ -4578,23 +9055,35 @@ msgstr "" "замовчуванням екструдер і температура полотна скидаються за допомогою " "команди non-wait; однак, якщо в цьому користувальному коді виявляються M104, " "M109, M140 або M190, Slic3r не додаватиме команди температури. Зверніть " -"увагу, що ви можете використовувати змінні-заповнювачі для всіх параметрів " +"увагу, що ви можете використовувати шаблонні змінні для всіх параметрів " "Slic3r, то ж ви можете вставити команду \"M109 S [first_layer_temperature]\" " "де завгодно." -#: src/libslic3r/PrintConfig.cpp:150 +#: src/libslic3r/PrintConfig.cpp:232 msgid "Number of solid layers to generate on bottom surfaces." msgstr "Кількість суцільних шарів, генерованих на нижніх поверхнях." -#: src/libslic3r/PrintConfig.cpp:151 +#: src/libslic3r/PrintConfig.cpp:233 msgid "Bottom solid layers" msgstr "Нижні суцільні шари" -#: src/libslic3r/PrintConfig.cpp:156 +#: src/libslic3r/PrintConfig.cpp:241 +msgid "" +"The number of bottom solid layers is increased above bottom_solid_layers if " +"necessary to satisfy minimum thickness of bottom shell." +msgstr "" +"Кількість твердих шарів знизу збільшується над нижчими твердими шарами, якщо " +"це необхідно для задоволення мінімальної товщини донної оболонки." + +#: src/libslic3r/PrintConfig.cpp:243 +msgid "Minimum bottom shell thickness" +msgstr "Мінімальна товщина нижньої оболонки" + +#: src/libslic3r/PrintConfig.cpp:249 msgid "Bridge" msgstr "Міст" -#: src/libslic3r/PrintConfig.cpp:157 +#: src/libslic3r/PrintConfig.cpp:250 msgid "" "This is the acceleration your printer will use for bridges. Set zero to " "disable acceleration control for bridges." @@ -4602,18 +9091,18 @@ msgstr "" "Це прискорення, яке ваш принтер використовуватиме для мостів. Встановити 0, " "щоб відключити управління прискоренням для мостів." -#: src/libslic3r/PrintConfig.cpp:159 src/libslic3r/PrintConfig.cpp:302 -#: src/libslic3r/PrintConfig.cpp:814 src/libslic3r/PrintConfig.cpp:935 -#: src/libslic3r/PrintConfig.cpp:1088 src/libslic3r/PrintConfig.cpp:1133 -#: src/libslic3r/PrintConfig.cpp:1144 src/libslic3r/PrintConfig.cpp:1333 +#: src/libslic3r/PrintConfig.cpp:252 src/libslic3r/PrintConfig.cpp:395 +#: src/libslic3r/PrintConfig.cpp:940 src/libslic3r/PrintConfig.cpp:1079 +#: src/libslic3r/PrintConfig.cpp:1360 src/libslic3r/PrintConfig.cpp:1409 +#: src/libslic3r/PrintConfig.cpp:1419 src/libslic3r/PrintConfig.cpp:1612 msgid "mm/s²" msgstr "мм/с²" -#: src/libslic3r/PrintConfig.cpp:165 +#: src/libslic3r/PrintConfig.cpp:258 msgid "Bridging angle" msgstr "Кут моста" -#: src/libslic3r/PrintConfig.cpp:167 +#: src/libslic3r/PrintConfig.cpp:260 msgid "" "Bridging angle override. If left to zero, the bridging angle will be " "calculated automatically. Otherwise the provided angle will be used for all " @@ -4623,33 +9112,35 @@ msgstr "" "автоматично. Інакше передбачений кут буде використаний для всіх мостів. " "Використовуйте 180° для нульового кута." -#: src/libslic3r/PrintConfig.cpp:170 src/libslic3r/PrintConfig.cpp:732 -#: src/libslic3r/PrintConfig.cpp:1569 src/libslic3r/PrintConfig.cpp:1579 -#: src/libslic3r/PrintConfig.cpp:1807 src/libslic3r/PrintConfig.cpp:1961 -#: src/libslic3r/PrintConfig.cpp:2459 +#: src/libslic3r/PrintConfig.cpp:263 src/libslic3r/PrintConfig.cpp:852 +#: src/libslic3r/PrintConfig.cpp:1853 src/libslic3r/PrintConfig.cpp:1863 +#: src/libslic3r/PrintConfig.cpp:2121 src/libslic3r/PrintConfig.cpp:2276 +#: src/libslic3r/PrintConfig.cpp:2475 src/libslic3r/PrintConfig.cpp:2976 +#: src/libslic3r/PrintConfig.cpp:3097 msgid "°" msgstr "°" -#: src/libslic3r/PrintConfig.cpp:176 +#: src/libslic3r/PrintConfig.cpp:269 msgid "Bridges fan speed" msgstr "Швидкість вентилятора для мостів" -#: src/libslic3r/PrintConfig.cpp:177 +#: src/libslic3r/PrintConfig.cpp:270 msgid "This fan speed is enforced during all bridges and overhangs." msgstr "Ця швидкість вентилятора виконується для всіх мостів і виступів." -#: src/libslic3r/PrintConfig.cpp:178 src/libslic3r/PrintConfig.cpp:744 -#: src/libslic3r/PrintConfig.cpp:1153 src/libslic3r/PrintConfig.cpp:1216 -#: src/libslic3r/PrintConfig.cpp:1461 src/libslic3r/PrintConfig.cpp:2258 -#: src/libslic3r/PrintConfig.cpp:2498 +#: src/libslic3r/PrintConfig.cpp:271 src/libslic3r/PrintConfig.cpp:864 +#: src/libslic3r/PrintConfig.cpp:1248 src/libslic3r/PrintConfig.cpp:1427 +#: src/libslic3r/PrintConfig.cpp:1490 src/libslic3r/PrintConfig.cpp:1745 +#: src/libslic3r/PrintConfig.cpp:2653 src/libslic3r/PrintConfig.cpp:2890 +#: src/libslic3r/PrintConfig.cpp:3016 msgid "%" msgstr "%" -#: src/libslic3r/PrintConfig.cpp:185 +#: src/libslic3r/PrintConfig.cpp:278 msgid "Bridge flow ratio" msgstr "Співвідношення мостового потоку" -#: src/libslic3r/PrintConfig.cpp:187 +#: src/libslic3r/PrintConfig.cpp:280 msgid "" "This factor affects the amount of plastic for bridging. You can decrease it " "slightly to pull the extrudates and prevent sagging, although default " @@ -4661,32 +9152,33 @@ msgstr "" "стандартні налаштування зазвичай добрі, тому ви маете по-експериментувати з " "охолодженням (використовуйте вентилятор), перш ніж їх налаштувати." -#: src/libslic3r/PrintConfig.cpp:197 +#: src/libslic3r/PrintConfig.cpp:290 msgid "Bridges" msgstr "Мости" -#: src/libslic3r/PrintConfig.cpp:199 +#: src/libslic3r/PrintConfig.cpp:292 msgid "Speed for printing bridges." msgstr "Швидкість друку мостів." -#: src/libslic3r/PrintConfig.cpp:200 src/libslic3r/PrintConfig.cpp:576 -#: src/libslic3r/PrintConfig.cpp:584 src/libslic3r/PrintConfig.cpp:593 -#: src/libslic3r/PrintConfig.cpp:601 src/libslic3r/PrintConfig.cpp:628 -#: src/libslic3r/PrintConfig.cpp:647 src/libslic3r/PrintConfig.cpp:873 -#: src/libslic3r/PrintConfig.cpp:1000 src/libslic3r/PrintConfig.cpp:1078 -#: src/libslic3r/PrintConfig.cpp:1098 src/libslic3r/PrintConfig.cpp:1111 -#: src/libslic3r/PrintConfig.cpp:1122 src/libslic3r/PrintConfig.cpp:1175 -#: src/libslic3r/PrintConfig.cpp:1234 src/libslic3r/PrintConfig.cpp:1362 -#: src/libslic3r/PrintConfig.cpp:1536 src/libslic3r/PrintConfig.cpp:1545 -#: src/libslic3r/PrintConfig.cpp:1940 src/libslic3r/PrintConfig.cpp:2051 +#: src/libslic3r/PrintConfig.cpp:293 src/libslic3r/PrintConfig.cpp:671 +#: src/libslic3r/PrintConfig.cpp:679 src/libslic3r/PrintConfig.cpp:688 +#: src/libslic3r/PrintConfig.cpp:696 src/libslic3r/PrintConfig.cpp:723 +#: src/libslic3r/PrintConfig.cpp:742 src/libslic3r/PrintConfig.cpp:1015 +#: src/libslic3r/PrintConfig.cpp:1194 src/libslic3r/PrintConfig.cpp:1267 +#: src/libslic3r/PrintConfig.cpp:1343 src/libslic3r/PrintConfig.cpp:1377 +#: src/libslic3r/PrintConfig.cpp:1389 src/libslic3r/PrintConfig.cpp:1399 +#: src/libslic3r/PrintConfig.cpp:1449 src/libslic3r/PrintConfig.cpp:1508 +#: src/libslic3r/PrintConfig.cpp:1642 src/libslic3r/PrintConfig.cpp:1820 +#: src/libslic3r/PrintConfig.cpp:1829 src/libslic3r/PrintConfig.cpp:2255 +#: src/libslic3r/PrintConfig.cpp:2382 msgid "mm/s" msgstr "мм/с" -#: src/libslic3r/PrintConfig.cpp:207 +#: src/libslic3r/PrintConfig.cpp:300 msgid "Brim width" msgstr "Ширина краю" -#: src/libslic3r/PrintConfig.cpp:208 +#: src/libslic3r/PrintConfig.cpp:301 msgid "" "Horizontal width of the brim that will be printed around each object on the " "first layer." @@ -4694,33 +9186,33 @@ msgstr "" "Горизонтальна ширина краю, яка буде надрукована навколо кожного об'єкта на " "першому шарі." -#: src/libslic3r/PrintConfig.cpp:215 +#: src/libslic3r/PrintConfig.cpp:308 msgid "Clip multi-part objects" msgstr "Обрізати об'єкти, що складаються з кількох частин" -#: src/libslic3r/PrintConfig.cpp:216 +#: src/libslic3r/PrintConfig.cpp:309 msgid "" -"When printing multi-material objects, this settings will make slic3r to clip " +"When printing multi-material objects, this settings will make Slic3r to clip " "the overlapping object parts one by the other (2nd part will be clipped by " "the 1st, 3rd part will be clipped by the 1st and 2nd etc)." msgstr "" -"Під час друку багатоматеріальних об'єктів ці налаштування змушують slic3r " -"обрізати частини, що перекриваються один одною (друга частина буде обрізана " -"першою, третя - першою та другою, тощо)." +"Під час друку багато-матеріальних об'єктів ці налаштування дозволять Slic3r " +"відсікати накладені частини об'єкта одна за одною (друга частина буде " +"відсічена першою, третя частина буде відсічена першою та другою тощо)." -#: src/libslic3r/PrintConfig.cpp:223 +#: src/libslic3r/PrintConfig.cpp:316 msgid "Colorprint height" -msgstr "" +msgstr "Висота кольорового друку" -#: src/libslic3r/PrintConfig.cpp:224 -msgid "Heights at which a filament change is to occur. " -msgstr "" +#: src/libslic3r/PrintConfig.cpp:317 +msgid "Heights at which a filament change is to occur." +msgstr "Висоти, на яких має відбуватися зміна філаменту." -#: src/libslic3r/PrintConfig.cpp:234 +#: src/libslic3r/PrintConfig.cpp:327 msgid "Compatible printers condition" -msgstr "Стан сумісних принтерів" +msgstr "Умови сумісності принтерів" -#: src/libslic3r/PrintConfig.cpp:235 +#: src/libslic3r/PrintConfig.cpp:328 msgid "" "A boolean expression using the configuration values of an active printer " "profile. If this expression evaluates to true, this profile is considered " @@ -4730,22 +9222,25 @@ msgstr "" "принтера. Якщо цей вираз оцінюється як Правда, цей профіль вважається " "сумісним з активним профілем принтера." -#: src/libslic3r/PrintConfig.cpp:249 +#: src/libslic3r/PrintConfig.cpp:342 msgid "Compatible print profiles condition" -msgstr "" +msgstr "Умови сумісності пресетів друку" -#: src/libslic3r/PrintConfig.cpp:250 +#: src/libslic3r/PrintConfig.cpp:343 msgid "" "A boolean expression using the configuration values of an active print " "profile. If this expression evaluates to true, this profile is considered " "compatible with the active print profile." msgstr "" +"Логічний вираз, що використовує значення конфігурації активного профілю " +"друку. Якщо цей вираз оцінюється як Правда, цей профіль вважається сумісним " +"з активним профілем друку." -#: src/libslic3r/PrintConfig.cpp:267 +#: src/libslic3r/PrintConfig.cpp:360 msgid "Complete individual objects" msgstr "Закінчити окремі об'єкти" -#: src/libslic3r/PrintConfig.cpp:268 +#: src/libslic3r/PrintConfig.cpp:361 msgid "" "When printing multiple objects or copies, this feature will complete each " "object before moving onto next one (and starting it from its bottom layer). " @@ -4757,11 +9252,11 @@ msgstr "" "шару). Ця функція корисна для уникнення ризику зіпсованих відбитків. Slic3r " "має попередити та запобігти зіткненню екструдера, але будьте обережні." -#: src/libslic3r/PrintConfig.cpp:276 +#: src/libslic3r/PrintConfig.cpp:369 msgid "Enable auto cooling" msgstr "Увімкнути автоматичне охолодження" -#: src/libslic3r/PrintConfig.cpp:277 +#: src/libslic3r/PrintConfig.cpp:370 msgid "" "This flag enables the automatic cooling logic that adjusts print speed and " "fan speed according to layer printing time." @@ -4769,23 +9264,26 @@ msgstr "" "Цей прапорець дозволяє автоматичну логіку охолодження, яка регулює швидкість " "друку та швидкість вентиляції відповідно до часу друку шару." -#: src/libslic3r/PrintConfig.cpp:282 +#: src/libslic3r/PrintConfig.cpp:375 msgid "Cooling tube position" -msgstr "" +msgstr "Позиція охолоджувальної трубки" -#: src/libslic3r/PrintConfig.cpp:283 -msgid "Distance of the center-point of the cooling tube from the extruder tip " +#: src/libslic3r/PrintConfig.cpp:376 +msgid "Distance of the center-point of the cooling tube from the extruder tip." msgstr "" +"Відстань центральної точки охолоджувальної трубки від наконечника екструдера." -#: src/libslic3r/PrintConfig.cpp:290 +#: src/libslic3r/PrintConfig.cpp:383 msgid "Cooling tube length" -msgstr "" +msgstr "Довжина охолоджувальної трубки" -#: src/libslic3r/PrintConfig.cpp:291 -msgid "Length of the cooling tube to limit space for cooling moves inside it " +#: src/libslic3r/PrintConfig.cpp:384 +msgid "Length of the cooling tube to limit space for cooling moves inside it." msgstr "" +"Довжина охолоджувальної трубки для обмеження простору для охолоджуючих рухів " +"всередині неї." -#: src/libslic3r/PrintConfig.cpp:299 +#: src/libslic3r/PrintConfig.cpp:392 msgid "" "This is the acceleration your printer will be reset to after the role-" "specific acceleration values are used (perimeter/infill). Set zero to " @@ -4795,34 +9293,38 @@ msgstr "" "використані конкретні визначені прискорення (периметру / заповнення). " "Встановити 0, щоб запобігти скиданням прискорення взагалі." -#: src/libslic3r/PrintConfig.cpp:308 +#: src/libslic3r/PrintConfig.cpp:401 msgid "Default filament profile" -msgstr "" +msgstr "Профіль філаметну за замовчанням" -#: src/libslic3r/PrintConfig.cpp:309 +#: src/libslic3r/PrintConfig.cpp:402 msgid "" "Default filament profile associated with the current printer profile. On " "selection of the current printer profile, this filament profile will be " "activated." msgstr "" +"Профіль філаметну за замовчанням, пов'язаний з поточним профілем принтера. " +"При виборі поточного профілю принтера цей профіль філаметну буде активовано." -#: src/libslic3r/PrintConfig.cpp:315 +#: src/libslic3r/PrintConfig.cpp:408 msgid "Default print profile" -msgstr "" +msgstr "Профіль друку за замовчанням" -#: src/libslic3r/PrintConfig.cpp:316 src/libslic3r/PrintConfig.cpp:2337 -#: src/libslic3r/PrintConfig.cpp:2348 +#: src/libslic3r/PrintConfig.cpp:409 src/libslic3r/PrintConfig.cpp:2820 +#: src/libslic3r/PrintConfig.cpp:2831 msgid "" "Default print profile associated with the current printer profile. On " "selection of the current printer profile, this print profile will be " "activated." msgstr "" +"Профіль друку за промовчанням, пов'язаний із поточним профілем принтера. При " +"виборі поточного профілю принтера цей профіль друку буде активовано." -#: src/libslic3r/PrintConfig.cpp:322 +#: src/libslic3r/PrintConfig.cpp:415 msgid "Disable fan for the first" msgstr "Вимкнути вентилятор для першого(их)" -#: src/libslic3r/PrintConfig.cpp:323 +#: src/libslic3r/PrintConfig.cpp:416 msgid "" "You can set this to a positive value to disable fan at all during the first " "layers, so that it does not make adhesion worse." @@ -4831,18 +9333,11 @@ msgstr "" "протягом друку декількох перших шарів, щоб це не призвело до гіршого " "зчеплення." -#: src/libslic3r/PrintConfig.cpp:325 src/libslic3r/PrintConfig.cpp:945 -#: src/libslic3r/PrintConfig.cpp:1434 src/libslic3r/PrintConfig.cpp:1619 -#: src/libslic3r/PrintConfig.cpp:1680 src/libslic3r/PrintConfig.cpp:1843 -#: src/libslic3r/PrintConfig.cpp:1888 -msgid "layers" -msgstr "шару(ів)" - -#: src/libslic3r/PrintConfig.cpp:332 +#: src/libslic3r/PrintConfig.cpp:425 msgid "Don't support bridges" msgstr "Не підтримувати мости" -#: src/libslic3r/PrintConfig.cpp:334 +#: src/libslic3r/PrintConfig.cpp:427 msgid "" "Experimental option for preventing support material from being generated " "under bridged areas." @@ -4850,51 +9345,42 @@ msgstr "" "Експериментальний варіант для запобігання утворенню допоміжного матеріалу в " "областях під мостами." -#: src/libslic3r/PrintConfig.cpp:340 +#: src/libslic3r/PrintConfig.cpp:433 msgid "Distance between copies" msgstr "Відстань між копіями" -#: src/libslic3r/PrintConfig.cpp:341 +#: src/libslic3r/PrintConfig.cpp:434 msgid "Distance used for the auto-arrange feature of the plater." msgstr "Відстань використовується для автоматичного розташування платеру." -#: src/libslic3r/PrintConfig.cpp:348 -msgid "Elephant foot compensation" -msgstr "Зрівноваження Стопи слона" - -#: src/libslic3r/PrintConfig.cpp:350 -msgid "" -"The first layer will be shrunk in the XY plane by the configured value to " -"compensate for the 1st layer squish aka an Elephant Foot effect." -msgstr "" -"Перший шар буде зменшено в площині XY завдяки налаштованому значенню, щоб " -"компенсувати ефект Ноги Слона для 1-го шару." - -#: src/libslic3r/PrintConfig.cpp:359 +#: src/libslic3r/PrintConfig.cpp:442 msgid "" "This end procedure is inserted at the end of the output file. Note that you " -"can use placeholder variables for all Slic3r settings." +"can use placeholder variables for all PrusaSlicer settings." msgstr "" -"Ця кінцева процедура вставляється в кінці вихідного файлу. Зауважте, що ви " -"можете використовувати заповнювачі змінних для всіх параметрів Slic3r." +"Ця процедура завершення вставляється в кінець вихідного файлу. Зверніть " +"увагу, що ви можете використовувати шаблонні змінні для всіх налаштувань " +"PrusaSlicer." -#: src/libslic3r/PrintConfig.cpp:369 +#: src/libslic3r/PrintConfig.cpp:452 msgid "" "This end procedure is inserted at the end of the output file, before the " -"printer end gcode. Note that you can use placeholder variables for all " -"Slic3r settings. If you have multiple extruders, the gcode is processed in " -"extruder order." +"printer end gcode (and before any toolchange from this filament in case of " +"multimaterial printers). Note that you can use placeholder variables for all " +"PrusaSlicer settings. If you have multiple extruders, the gcode is processed " +"in extruder order." msgstr "" -"Ця кінцева процедура вставляється в кінці вихідного файлу перед кінцевим " -"кодом принтера. Зауважте, що ви можете використовувати заповнювачі змінних " -"для всіх параметрів Slic3r. Якщо у вас є кілька екструдерів, G-code " -"обробляється в порядку екструдерів." +"Ця процедура завершення вставляється в кінець вихідного файлу, перед " +"кінцевим кодом принтера (і перед будь-якою заміною інструменту з цього " +"філаменту у разі багатоматеріальних принтерів). Зверніть увагу, що ви можете " +"використовувати шаблонні змінні для всіх налаштувань PrusaSlicer. Якщо у вас " +"кілька екструдерів, G-код обробляється в порядку екструдера." -#: src/libslic3r/PrintConfig.cpp:379 +#: src/libslic3r/PrintConfig.cpp:463 msgid "Ensure vertical shell thickness" -msgstr "Перевірте товщину вертикальної оболонки" +msgstr "Забезпечення товщини вертикальної оболонки" -#: src/libslic3r/PrintConfig.cpp:381 +#: src/libslic3r/PrintConfig.cpp:465 msgid "" "Add solid infill near sloping surfaces to guarantee the vertical shell " "thickness (top+bottom solid layers)." @@ -4902,52 +9388,64 @@ msgstr "" "Додайте суцільні наповнювачі біля нахилених поверхонь, щоб гарантувати " "товщину вертикальної оболонки (верхній і нижній суцільні шари)." -#: src/libslic3r/PrintConfig.cpp:387 +#: src/libslic3r/PrintConfig.cpp:471 msgid "Top fill pattern" -msgstr "" +msgstr "Верхній шаблон наповнення" -#: src/libslic3r/PrintConfig.cpp:389 +#: src/libslic3r/PrintConfig.cpp:473 msgid "" "Fill pattern for top infill. This only affects the top visible layer, and " "not its adjacent solid shells." msgstr "" +"Шаблон для верхнього наповнення. Це впливає лише на зовнішній видимий шар, а " +"не на сусідні суцільні оболонки." -#: src/libslic3r/PrintConfig.cpp:397 src/libslic3r/PrintConfig.cpp:795 -#: src/libslic3r/PrintConfig.cpp:1921 +#: src/libslic3r/PrintConfig.cpp:483 src/libslic3r/PrintConfig.cpp:918 +#: src/libslic3r/PrintConfig.cpp:2236 msgid "Rectilinear" -msgstr "" +msgstr "Прямолінійний" -#: src/libslic3r/PrintConfig.cpp:398 src/libslic3r/PrintConfig.cpp:801 +#: src/libslic3r/PrintConfig.cpp:484 +msgid "Monotonic" +msgstr "Монотонне" + +#: src/libslic3r/PrintConfig.cpp:485 src/libslic3r/PrintConfig.cpp:919 +msgid "Aligned Rectilinear" +msgstr "Вирівняний прямолінійний" + +#: src/libslic3r/PrintConfig.cpp:486 src/libslic3r/PrintConfig.cpp:925 msgid "Concentric" -msgstr "" +msgstr "Концентричний" -#: src/libslic3r/PrintConfig.cpp:399 src/libslic3r/PrintConfig.cpp:805 +#: src/libslic3r/PrintConfig.cpp:487 src/libslic3r/PrintConfig.cpp:929 msgid "Hilbert Curve" -msgstr "" +msgstr "Крива Гільберта" -#: src/libslic3r/PrintConfig.cpp:400 src/libslic3r/PrintConfig.cpp:806 +#: src/libslic3r/PrintConfig.cpp:488 src/libslic3r/PrintConfig.cpp:930 msgid "Archimedean Chords" -msgstr "" +msgstr "Архімедові акорди" -#: src/libslic3r/PrintConfig.cpp:401 src/libslic3r/PrintConfig.cpp:807 +#: src/libslic3r/PrintConfig.cpp:489 src/libslic3r/PrintConfig.cpp:931 msgid "Octagram Spiral" -msgstr "" +msgstr "Спіраль октаграм" -#: src/libslic3r/PrintConfig.cpp:408 +#: src/libslic3r/PrintConfig.cpp:495 msgid "Bottom fill pattern" -msgstr "" +msgstr "Нижній шаблон наповнення" -#: src/libslic3r/PrintConfig.cpp:409 +#: src/libslic3r/PrintConfig.cpp:497 msgid "" "Fill pattern for bottom infill. This only affects the bottom external " "visible layer, and not its adjacent solid shells." msgstr "" +"Шаблон для нижнього наповнення. Це впливає лише на зовнішній видимий шар, а " +"не на сусідні суцільні оболонки." -#: src/libslic3r/PrintConfig.cpp:414 src/libslic3r/PrintConfig.cpp:424 +#: src/libslic3r/PrintConfig.cpp:506 src/libslic3r/PrintConfig.cpp:517 msgid "External perimeters" msgstr "Зовнішні периметри" -#: src/libslic3r/PrintConfig.cpp:416 +#: src/libslic3r/PrintConfig.cpp:508 msgid "" "Set this to a non-zero value to set a manual extrusion width for external " "perimeters. If left zero, default extrusion width will be used if set, " @@ -4960,14 +9458,16 @@ msgstr "" "сопла. Якщо він виражений у відсотках (наприклад, 200%), він буде " "обчислюватися за висотою шару." -#: src/libslic3r/PrintConfig.cpp:419 src/libslic3r/PrintConfig.cpp:834 -#: src/libslic3r/PrintConfig.cpp:966 src/libslic3r/PrintConfig.cpp:1353 -#: src/libslic3r/PrintConfig.cpp:1691 src/libslic3r/PrintConfig.cpp:1864 -#: src/libslic3r/PrintConfig.cpp:2022 -msgid "mm or % (leave 0 for default)" -msgstr "мм або % (залиште 0 за замовчанням)" +#: src/libslic3r/PrintConfig.cpp:511 src/libslic3r/PrintConfig.cpp:621 +#: src/libslic3r/PrintConfig.cpp:962 src/libslic3r/PrintConfig.cpp:975 +#: src/libslic3r/PrintConfig.cpp:1104 src/libslic3r/PrintConfig.cpp:1159 +#: src/libslic3r/PrintConfig.cpp:1185 src/libslic3r/PrintConfig.cpp:1632 +#: src/libslic3r/PrintConfig.cpp:1961 src/libslic3r/PrintConfig.cpp:2110 +#: src/libslic3r/PrintConfig.cpp:2178 src/libslic3r/PrintConfig.cpp:2339 +msgid "mm or %" +msgstr "мм або %" -#: src/libslic3r/PrintConfig.cpp:426 +#: src/libslic3r/PrintConfig.cpp:519 msgid "" "This separate setting will affect the speed of external perimeters (the " "visible ones). If expressed as percentage (for example: 80%) it will be " @@ -4978,17 +9478,17 @@ msgstr "" "налаштування швидкості периметра вище. Встановити 0 для автоматичного " "використання." -#: src/libslic3r/PrintConfig.cpp:429 src/libslic3r/PrintConfig.cpp:855 -#: src/libslic3r/PrintConfig.cpp:1650 src/libslic3r/PrintConfig.cpp:1701 -#: src/libslic3r/PrintConfig.cpp:1907 src/libslic3r/PrintConfig.cpp:2034 +#: src/libslic3r/PrintConfig.cpp:522 src/libslic3r/PrintConfig.cpp:984 +#: src/libslic3r/PrintConfig.cpp:1920 src/libslic3r/PrintConfig.cpp:1972 +#: src/libslic3r/PrintConfig.cpp:2222 src/libslic3r/PrintConfig.cpp:2352 msgid "mm/s or %" msgstr "мм/с або %" -#: src/libslic3r/PrintConfig.cpp:436 +#: src/libslic3r/PrintConfig.cpp:529 msgid "External perimeters first" msgstr "Спочатку зовнішні периметри" -#: src/libslic3r/PrintConfig.cpp:438 +#: src/libslic3r/PrintConfig.cpp:531 msgid "" "Print contour perimeters from the outermost one to the innermost one instead " "of the default inverse order." @@ -4996,12 +9496,11 @@ msgstr "" "Друкувати контури периметра від найзовнішнього до найвнутрішнього, замість " "інверсного порядку за замовчанням." -#: src/libslic3r/PrintConfig.cpp:444 +#: src/libslic3r/PrintConfig.cpp:537 msgid "Extra perimeters if needed" msgstr "Додаткові периметри, якщо необхідно" -#: src/libslic3r/PrintConfig.cpp:446 -#, no-c-format +#: src/libslic3r/PrintConfig.cpp:539 msgid "" "Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r " "keeps adding perimeters, until more than 70% of the loop immediately above " @@ -5011,7 +9510,7 @@ msgstr "" "Slic3r продовжує додавати периметри, поки підтримується більше 70% петель " "безпосередньо вище." -#: src/libslic3r/PrintConfig.cpp:456 +#: src/libslic3r/PrintConfig.cpp:549 msgid "" "The extruder to use (unless more specific extruder settings are specified). " "This value overrides perimeter and infill extruders, but not the support " @@ -5021,7 +9520,7 @@ msgstr "" "екструдера). Це значення перевизначає екструдери периметра та наповнювача, " "але не екструдери підтримки." -#: src/libslic3r/PrintConfig.cpp:468 +#: src/libslic3r/PrintConfig.cpp:561 msgid "" "Set this to the vertical distance between your nozzle tip and (usually) the " "X carriage rods. In other words, this is the height of the clearance " @@ -5033,11 +9532,7 @@ msgstr "" "навколо вашого екструдера, і це являє собою максимальну глибину, яку " "екструдер може розглядати до зіткнення з іншими друкованими предметами." -#: src/libslic3r/PrintConfig.cpp:478 -msgid "Radius" -msgstr "Радіус" - -#: src/libslic3r/PrintConfig.cpp:479 +#: src/libslic3r/PrintConfig.cpp:572 msgid "" "Set this to the clearance radius around your extruder. If the extruder is " "not centered, choose the largest value for safety. This setting is used to " @@ -5048,20 +9543,20 @@ msgstr "" "параметр використовується для перевірки зіткнень та відображення графічного " "попереднього перегляду в панелі." -#: src/libslic3r/PrintConfig.cpp:489 +#: src/libslic3r/PrintConfig.cpp:582 msgid "Extruder Color" msgstr "Колір екструдера" -#: src/libslic3r/PrintConfig.cpp:490 src/libslic3r/PrintConfig.cpp:550 +#: src/libslic3r/PrintConfig.cpp:583 src/libslic3r/PrintConfig.cpp:645 msgid "This is only used in the Slic3r interface as a visual help." msgstr "" "Ця опція використовується лише у інтерфейсі Slic3r як візуальна допомога." -#: src/libslic3r/PrintConfig.cpp:496 +#: src/libslic3r/PrintConfig.cpp:589 msgid "Extruder offset" msgstr "Зміщення екструдеру" -#: src/libslic3r/PrintConfig.cpp:497 +#: src/libslic3r/PrintConfig.cpp:590 msgid "" "If your firmware doesn't handle the extruder displacement you need the G-" "code to take it into account. This option lets you specify the displacement " @@ -5073,11 +9568,11 @@ msgstr "" "відносно першого. Він очікує позитивних координат (вони будуть віднімані від " "координати XY)." -#: src/libslic3r/PrintConfig.cpp:506 +#: src/libslic3r/PrintConfig.cpp:599 msgid "Extrusion axis" msgstr "Ось екструзії" -#: src/libslic3r/PrintConfig.cpp:507 +#: src/libslic3r/PrintConfig.cpp:600 msgid "" "Use this option to set the axis letter associated to your printer's extruder " "(usually E but some printers use A)." @@ -5085,11 +9580,11 @@ msgstr "" "Використовуйте цю опцію, щоб встановити букву осей, пов'язану з екструдером " "принтера (зазвичай E, але деякі принтери використовують A)." -#: src/libslic3r/PrintConfig.cpp:512 +#: src/libslic3r/PrintConfig.cpp:605 msgid "Extrusion multiplier" msgstr "Коефіцієнт екструзії" -#: src/libslic3r/PrintConfig.cpp:513 +#: src/libslic3r/PrintConfig.cpp:606 msgid "" "This factor changes the amount of flow proportionally. You may need to tweak " "this setting to get nice surface finish and correct single wall widths. " @@ -5099,14 +9594,14 @@ msgstr "" "Цей фактор пропорційно змінює величину потоку. Вам може знадобитися " "налаштувати цей параметр, щоб отримати хорошу обробку поверхні та правильно " "визначити ширину однієї стіни. Звичайні значення - від 0,9 до 1,1. Якщо ви " -"вважаєте, що його потрібно більше змінити, перевірте діаметр нитки та E " +"вважаєте, що його потрібно більше змінити, перевірте діаметр філаменту та E " "кроки прошивки ." -#: src/libslic3r/PrintConfig.cpp:521 +#: src/libslic3r/PrintConfig.cpp:615 msgid "Default extrusion width" msgstr "Ширина екструзії за замовчанням" -#: src/libslic3r/PrintConfig.cpp:523 +#: src/libslic3r/PrintConfig.cpp:617 msgid "" "Set this to a non-zero value to allow a manual extrusion width. If left to " "zero, Slic3r derives extrusion widths from the nozzle diameter (see the " @@ -5120,15 +9615,11 @@ msgstr "" "наповнювача тощо). Якщо значення виражене у відсотках (наприклад: 230%), " "воно буде обчислюватися за висотою шару." -#: src/libslic3r/PrintConfig.cpp:527 -msgid "mm or % (leave 0 for auto)" -msgstr "мм або % (залиште 0 для автообчислення)" - -#: src/libslic3r/PrintConfig.cpp:532 +#: src/libslic3r/PrintConfig.cpp:628 msgid "Keep fan always on" msgstr "Тримайте вентилятор завжди" -#: src/libslic3r/PrintConfig.cpp:533 +#: src/libslic3r/PrintConfig.cpp:629 msgid "" "If this is enabled, fan will never be disabled and will be kept running at " "least at its minimum speed. Useful for PLA, harmful for ABS." @@ -5137,11 +9628,11 @@ msgstr "" "триматися, як мінімум, на мінімальній швидкості. Корисно для PLA, шкідливо " "для ABS." -#: src/libslic3r/PrintConfig.cpp:538 +#: src/libslic3r/PrintConfig.cpp:634 msgid "Enable fan if layer print time is below" msgstr "Увімкнути вентилятор, якщо час друку шару нижче" -#: src/libslic3r/PrintConfig.cpp:539 +#: src/libslic3r/PrintConfig.cpp:635 msgid "" "If layer print time is estimated below this number of seconds, fan will be " "enabled and its speed will be calculated by interpolating the minimum and " @@ -5151,27 +9642,27 @@ msgstr "" "активований, а його швидкість буде розрахована шляхом інтерполяції " "мінімальної та максимальної швидкості." -#: src/libslic3r/PrintConfig.cpp:541 src/libslic3r/PrintConfig.cpp:1637 +#: src/libslic3r/PrintConfig.cpp:637 src/libslic3r/PrintConfig.cpp:1908 msgid "approximate seconds" msgstr "приблизні секунди" -#: src/libslic3r/PrintConfig.cpp:549 +#: src/libslic3r/PrintConfig.cpp:644 msgid "Color" msgstr "Колір" -#: src/libslic3r/PrintConfig.cpp:555 +#: src/libslic3r/PrintConfig.cpp:650 msgid "Filament notes" msgstr "Примітки до філаменту" -#: src/libslic3r/PrintConfig.cpp:556 +#: src/libslic3r/PrintConfig.cpp:651 msgid "You can put your notes regarding the filament here." msgstr "Тут ви можете помістити свої нотатки щодо філаменту." -#: src/libslic3r/PrintConfig.cpp:564 src/libslic3r/PrintConfig.cpp:1181 +#: src/libslic3r/PrintConfig.cpp:659 src/libslic3r/PrintConfig.cpp:1455 msgid "Max volumetric speed" msgstr "Максимальна об'ємна швидкість" -#: src/libslic3r/PrintConfig.cpp:565 +#: src/libslic3r/PrintConfig.cpp:660 msgid "" "Maximum volumetric speed allowed for this filament. Limits the maximum " "volumetric speed of a print to the minimum of print and filament volumetric " @@ -5181,79 +9672,86 @@ msgstr "" "максимальну об'ємну швидкість друку до мінімуму об'ємної швидкості друку та " "філаметну. Встановити 0 для відсутності обмежень." -#: src/libslic3r/PrintConfig.cpp:568 src/libslic3r/PrintConfig.cpp:1184 -msgid "mm³/s" -msgstr "мм³/с" - -#: src/libslic3r/PrintConfig.cpp:574 +#: src/libslic3r/PrintConfig.cpp:669 msgid "Loading speed" -msgstr "" +msgstr "Швидкість заведення" -#: src/libslic3r/PrintConfig.cpp:575 -msgid "Speed used for loading the filament on the wipe tower. " +#: src/libslic3r/PrintConfig.cpp:670 +msgid "Speed used for loading the filament on the wipe tower." msgstr "" +"Швидкість, що використовується для заведення філаменту на вежі витирання." -#: src/libslic3r/PrintConfig.cpp:582 +#: src/libslic3r/PrintConfig.cpp:677 msgid "Loading speed at the start" -msgstr "" +msgstr "Швидкість заведення на старті" -#: src/libslic3r/PrintConfig.cpp:583 -msgid "Speed used at the very beginning of loading phase. " -msgstr "" +#: src/libslic3r/PrintConfig.cpp:678 +msgid "Speed used at the very beginning of loading phase." +msgstr "Швидкість, що використовується на самому початку фази заведення." -#: src/libslic3r/PrintConfig.cpp:590 +#: src/libslic3r/PrintConfig.cpp:685 msgid "Unloading speed" -msgstr "" +msgstr "Швидкість виведення" -#: src/libslic3r/PrintConfig.cpp:591 +#: src/libslic3r/PrintConfig.cpp:686 msgid "" "Speed used for unloading the filament on the wipe tower (does not affect " -"initial part of unloading just after ramming). " +"initial part of unloading just after ramming)." msgstr "" +"Швидкість, яка використовується для виведення філаменту на вежі витирання " +"(не впливає на початкову частину виведення безпосередньо після раммінгу)." -#: src/libslic3r/PrintConfig.cpp:599 +#: src/libslic3r/PrintConfig.cpp:694 msgid "Unloading speed at the start" -msgstr "" +msgstr "Швидкість виведення на старті" -#: src/libslic3r/PrintConfig.cpp:600 +#: src/libslic3r/PrintConfig.cpp:695 msgid "" -"Speed used for unloading the tip of the filament immediately after ramming. " +"Speed used for unloading the tip of the filament immediately after ramming." msgstr "" +"Швидкість, яка використовується для виведення кінчику філаменту " +"безпосередньо після раммінгу." -#: src/libslic3r/PrintConfig.cpp:607 +#: src/libslic3r/PrintConfig.cpp:702 msgid "Delay after unloading" -msgstr "" +msgstr "Затримка після виведення" -#: src/libslic3r/PrintConfig.cpp:608 +#: src/libslic3r/PrintConfig.cpp:703 msgid "" "Time to wait after the filament is unloaded. May help to get reliable " "toolchanges with flexible materials that may need more time to shrink to " -"original dimensions. " +"original dimensions." msgstr "" +"Час очікування після виведення філаменту. Може допомогти отримати надійну " +"заміну інструменту для гнучких матеріалів, яким може знадобитися більше " +"часу, щоб зменшитись до початкових розмірів." -#: src/libslic3r/PrintConfig.cpp:617 +#: src/libslic3r/PrintConfig.cpp:712 msgid "Number of cooling moves" -msgstr "" +msgstr "Кількість охолоджуючих рухів" -#: src/libslic3r/PrintConfig.cpp:618 +#: src/libslic3r/PrintConfig.cpp:713 msgid "" "Filament is cooled by being moved back and forth in the cooling tubes. " -"Specify desired number of these moves " +"Specify desired number of these moves." msgstr "" +"Філамент охолоджується шляхом переміщення вперед-назад у охолоджувальних " +"трубках. Вкажіть бажану кількість цих рухів." -#: src/libslic3r/PrintConfig.cpp:626 +#: src/libslic3r/PrintConfig.cpp:721 msgid "Speed of the first cooling move" -msgstr "" +msgstr "Швидкість першого охолоджуючого руху" -#: src/libslic3r/PrintConfig.cpp:627 -msgid "Cooling moves are gradually accelerating beginning at this speed. " +#: src/libslic3r/PrintConfig.cpp:722 +msgid "Cooling moves are gradually accelerating beginning at this speed." msgstr "" +"Охолоджувальні рухи поступово прискорюються, починаючи з цієї швидкості." -#: src/libslic3r/PrintConfig.cpp:634 +#: src/libslic3r/PrintConfig.cpp:729 msgid "Minimal purge on wipe tower" -msgstr "" +msgstr "Мінімальний екструдований об'єм на очисній вежі" -#: src/libslic3r/PrintConfig.cpp:635 +#: src/libslic3r/PrintConfig.cpp:730 msgid "" "After a tool change, the exact position of the newly loaded filament inside " "the nozzle may not be known, and the filament pressure is likely not yet " @@ -5261,66 +9759,80 @@ msgid "" "object, Slic3r will always prime this amount of material into the wipe tower " "to produce successive infill or sacrificial object extrusions reliably." msgstr "" +"Після зміни інструменту точне положення знову заведеного філаменту всередину " +"сопла може бути невідоме, а тиск філаменту, скоріше за все, ще не " +"стабільний. Перш ніж прочищати друкувальну головку до заповнення або " +"очищувальної вежі, Slic3r завжди продавлює цю кількість матеріалу до " +"очищувальної вежі, щоб отримати послідовне заповнення." -#: src/libslic3r/PrintConfig.cpp:639 +#: src/libslic3r/PrintConfig.cpp:734 msgid "mm³" -msgstr "" +msgstr "мм³" -#: src/libslic3r/PrintConfig.cpp:645 +#: src/libslic3r/PrintConfig.cpp:740 msgid "Speed of the last cooling move" -msgstr "" +msgstr "Швидкість останнього охолоджуючого руху" -#: src/libslic3r/PrintConfig.cpp:646 -msgid "Cooling moves are gradually accelerating towards this speed. " -msgstr "" +#: src/libslic3r/PrintConfig.cpp:741 +msgid "Cooling moves are gradually accelerating towards this speed." +msgstr "Охолоджувальні рухи поступово прискорюються до цієї швидкості." -#: src/libslic3r/PrintConfig.cpp:653 +#: src/libslic3r/PrintConfig.cpp:748 msgid "Filament load time" -msgstr "" +msgstr "Час заведення філаменту" -#: src/libslic3r/PrintConfig.cpp:654 +#: src/libslic3r/PrintConfig.cpp:749 msgid "" "Time for the printer firmware (or the Multi Material Unit 2.0) to load a new " "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" +"Час для прошивки принтера (або Multi Material Unit 2.0), щоб завести новий " +"філамент під час заміни інструменту (під час виконання коду Т). Цей час " +"додається до загального часу друку за допомогою оцінювача часу G-коду." -#: src/libslic3r/PrintConfig.cpp:661 +#: src/libslic3r/PrintConfig.cpp:756 msgid "Ramming parameters" -msgstr "" +msgstr "Параметри раммінгу" -#: src/libslic3r/PrintConfig.cpp:662 +#: src/libslic3r/PrintConfig.cpp:757 msgid "" "This string is edited by RammingDialog and contains ramming specific " -"parameters " +"parameters." msgstr "" +"Цей рядок відредаговано у діалогу налаштувань раммінгу та містить певні " +"параметри раммінгу." -#: src/libslic3r/PrintConfig.cpp:668 +#: src/libslic3r/PrintConfig.cpp:763 msgid "Filament unload time" -msgstr "" +msgstr "Час виведення філаменту" -#: src/libslic3r/PrintConfig.cpp:669 +#: src/libslic3r/PrintConfig.cpp:764 msgid "" "Time for the printer firmware (or the Multi Material Unit 2.0) to unload a " "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" +"Час для прошивки принтера (або Multi Material Unit 2.0), щоб вивести " +"філамент під час заміни інструменту (під час виконання коду Т). Цей час " +"додається до загального часу друку за допомогою оцінювача часу G-коду." -#: src/libslic3r/PrintConfig.cpp:677 +#: src/libslic3r/PrintConfig.cpp:772 msgid "" "Enter your filament diameter here. Good precision is required, so use a " "caliper and do multiple measurements along the filament, then compute the " "average." msgstr "" "Введіть тут діаметр свого філаменту. Необхідна висока точність, тому " -"використовуйте суматор і виконайте декілька вимірювань вздовж нитки, потім " -"обчисліть середнє значення." +"використовуйте суматор і виконайте декілька вимірювань вздовж філаменту, " +"потім обчисліть середнє значення." -#: src/libslic3r/PrintConfig.cpp:684 +#: src/libslic3r/PrintConfig.cpp:779 src/libslic3r/PrintConfig.cpp:2731 +#: src/libslic3r/PrintConfig.cpp:2732 msgid "Density" msgstr "Щільність" -#: src/libslic3r/PrintConfig.cpp:685 +#: src/libslic3r/PrintConfig.cpp:780 msgid "" "Enter your filament density here. This is only for statistical information. " "A decent way is to weigh a known length of filament and compute the ratio of " @@ -5328,31 +9840,31 @@ msgid "" "displacement." msgstr "" "Введіть тут щільність свого філаменту. Це тільки для статистичної " -"інформації. Пристойним способом є зважування відомої довжини нитки та " +"інформації. Пристойним способом є зважування відомої довжини філаменту та " "обчислення співвідношення довжини до обсягу. Краще обчислити об'єм " "безпосередньо через зміщення." -#: src/libslic3r/PrintConfig.cpp:688 +#: src/libslic3r/PrintConfig.cpp:783 msgid "g/cm³" msgstr "г/см³" -#: src/libslic3r/PrintConfig.cpp:693 +#: src/libslic3r/PrintConfig.cpp:788 msgid "Filament type" msgstr "Тип філаменту" -#: src/libslic3r/PrintConfig.cpp:694 +#: src/libslic3r/PrintConfig.cpp:789 msgid "The filament material type for use in custom G-codes." -msgstr "" +msgstr "Тип матеріалу філаменту для використання в користувацьких G-кодах." -#: src/libslic3r/PrintConfig.cpp:710 +#: src/libslic3r/PrintConfig.cpp:816 msgid "Soluble material" msgstr "Розчинний матеріал" -#: src/libslic3r/PrintConfig.cpp:711 +#: src/libslic3r/PrintConfig.cpp:817 msgid "Soluble material is most likely used for a soluble support." msgstr "Розчинний матеріал переважно використовується для розчинної підтримки." -#: src/libslic3r/PrintConfig.cpp:717 +#: src/libslic3r/PrintConfig.cpp:823 msgid "" "Enter your filament cost per kg here. This is only for statistical " "information." @@ -5360,15 +9872,39 @@ msgstr "" "Введіть тут свою вартість філаменту на кг. Це тільки для статистичної " "інформації." -#: src/libslic3r/PrintConfig.cpp:718 +#: src/libslic3r/PrintConfig.cpp:824 msgid "money/kg" msgstr "грошових одиниць/кг" -#: src/libslic3r/PrintConfig.cpp:727 +#: src/libslic3r/PrintConfig.cpp:829 +msgid "Spool weight" +msgstr "Вага котушки" + +#: src/libslic3r/PrintConfig.cpp:830 +msgid "" +"Enter weight of the empty filament spool. One may weigh a partially consumed " +"filament spool before printing and one may compare the measured weight with " +"the calculated weight of the filament with the spool to find out whether the " +"amount of filament on the spool is sufficient to finish the print." +msgstr "" +"Введіть вагу порожньої котушки філаменту. Перед друком можна зважити " +"частково витрачену котушку філаменту, а можна порівняти виміряну вагу з " +"розрахунковою вагою філаменту з котушкою, щоб з’ясувати, чи достатньо " +"кількості філаменту на котушці для закінчення друку." + +#: src/libslic3r/PrintConfig.cpp:834 +msgid "g" +msgstr "г" + +#: src/libslic3r/PrintConfig.cpp:843 src/libslic3r/PrintConfig.cpp:2815 +msgid "(Unknown)" +msgstr "(Невідомий)" + +#: src/libslic3r/PrintConfig.cpp:847 msgid "Fill angle" msgstr "Кут наповнення" -#: src/libslic3r/PrintConfig.cpp:729 +#: src/libslic3r/PrintConfig.cpp:849 msgid "" "Default base angle for infill orientation. Cross-hatching will be applied to " "this. Bridges will be infilled using the best direction Slic3r can detect, " @@ -5378,60 +9914,68 @@ msgstr "" "застосовуватися крос-штрих. Мости будуть заповнені, використовуючи найкращий " "напрям, який може виявити Slic3r, тому цей параметр на них не впливає." -#: src/libslic3r/PrintConfig.cpp:741 +#: src/libslic3r/PrintConfig.cpp:861 msgid "Fill density" msgstr "Щільність заповнення" -#: src/libslic3r/PrintConfig.cpp:743 +#: src/libslic3r/PrintConfig.cpp:863 msgid "Density of internal infill, expressed in the range 0% - 100%." msgstr "Щільність внутрішнього заповнення, виражена в діапазоні 0% - 100%." -#: src/libslic3r/PrintConfig.cpp:778 +#: src/libslic3r/PrintConfig.cpp:898 msgid "Fill pattern" msgstr "Шаблон заповнення" -#: src/libslic3r/PrintConfig.cpp:780 +#: src/libslic3r/PrintConfig.cpp:900 msgid "Fill pattern for general low-density infill." msgstr "Шаблон заповнення для загального низько-швидкісного наповнення." -#: src/libslic3r/PrintConfig.cpp:796 +#: src/libslic3r/PrintConfig.cpp:920 msgid "Grid" -msgstr "" +msgstr "Сітка" -#: src/libslic3r/PrintConfig.cpp:797 +#: src/libslic3r/PrintConfig.cpp:921 msgid "Triangles" -msgstr "" +msgstr "Трикутники" -#: src/libslic3r/PrintConfig.cpp:798 +#: src/libslic3r/PrintConfig.cpp:922 msgid "Stars" -msgstr "" +msgstr "Зірки" -#: src/libslic3r/PrintConfig.cpp:799 +#: src/libslic3r/PrintConfig.cpp:923 msgid "Cubic" -msgstr "" +msgstr "Кубічний" -#: src/libslic3r/PrintConfig.cpp:800 +#: src/libslic3r/PrintConfig.cpp:924 msgid "Line" -msgstr "" +msgstr "Лінії" -#: src/libslic3r/PrintConfig.cpp:802 src/libslic3r/PrintConfig.cpp:1923 +#: src/libslic3r/PrintConfig.cpp:926 src/libslic3r/PrintConfig.cpp:2238 msgid "Honeycomb" -msgstr "" +msgstr "Стільниковий" -#: src/libslic3r/PrintConfig.cpp:803 +#: src/libslic3r/PrintConfig.cpp:927 msgid "3D Honeycomb" -msgstr "" +msgstr "3D стільник" -#: src/libslic3r/PrintConfig.cpp:804 +#: src/libslic3r/PrintConfig.cpp:928 msgid "Gyroid" -msgstr "" +msgstr "Гіроїд" -#: src/libslic3r/PrintConfig.cpp:811 src/libslic3r/PrintConfig.cpp:820 -#: src/libslic3r/PrintConfig.cpp:828 src/libslic3r/PrintConfig.cpp:861 +#: src/libslic3r/PrintConfig.cpp:932 +msgid "Adaptive Cubic" +msgstr "Адаптивний кубічний" + +#: src/libslic3r/PrintConfig.cpp:933 +msgid "Support Cubic" +msgstr "Кубічна підтримка" + +#: src/libslic3r/PrintConfig.cpp:937 src/libslic3r/PrintConfig.cpp:946 +#: src/libslic3r/PrintConfig.cpp:956 src/libslic3r/PrintConfig.cpp:990 msgid "First layer" msgstr "Перший шар" -#: src/libslic3r/PrintConfig.cpp:812 +#: src/libslic3r/PrintConfig.cpp:938 msgid "" "This is the acceleration your printer will use for first layer. Set zero to " "disable acceleration control for first layer." @@ -5439,7 +9983,11 @@ msgstr "" "Це прискорення, яке ваш принтер використовуватиме для першого шару. " "Встановити 0, щоб вимкнути керування прискоренням для першого шару." -#: src/libslic3r/PrintConfig.cpp:821 +#: src/libslic3r/PrintConfig.cpp:947 +msgid "First layer bed temperature" +msgstr "Температура столу на першому шарі" + +#: src/libslic3r/PrintConfig.cpp:948 msgid "" "Heated build plate temperature for the first layer. Set this to zero to " "disable bed temperature control commands in the output." @@ -5447,7 +9995,7 @@ msgstr "" "Температура підігрітої збірної пластини для першого шару. Установіть 0, щоб " "відключити команди керування температурою полотна на виході." -#: src/libslic3r/PrintConfig.cpp:830 +#: src/libslic3r/PrintConfig.cpp:958 msgid "" "Set this to a non-zero value to set a manual extrusion width for first " "layer. You can use this to force fatter extrudates for better adhesion. If " @@ -5460,11 +10008,7 @@ msgstr "" "(наприклад, 120%), вона буде обчислена за висотою першого шару. Якщо " "встановлено на 0 - використовуватиме стандартну ширину екструзії." -#: src/libslic3r/PrintConfig.cpp:840 -msgid "First layer height" -msgstr "Висота першого шару" - -#: src/libslic3r/PrintConfig.cpp:842 +#: src/libslic3r/PrintConfig.cpp:971 msgid "" "When printing with very low layer heights, you might still want to print a " "thicker bottom layer to improve adhesion and tolerance for non perfect build " @@ -5476,16 +10020,11 @@ msgstr "" "до невідповідних збірних пластин. Можна виразити як абсолютне значення або " "як відсоток (наприклад: 150%) по висоті шару за замовчуванням." -#: src/libslic3r/PrintConfig.cpp:846 src/libslic3r/PrintConfig.cpp:991 -#: src/libslic3r/PrintConfig.cpp:1796 -msgid "mm or %" -msgstr "мм або %" - -#: src/libslic3r/PrintConfig.cpp:851 +#: src/libslic3r/PrintConfig.cpp:980 msgid "First layer speed" msgstr "Швидкість першого шару" -#: src/libslic3r/PrintConfig.cpp:852 +#: src/libslic3r/PrintConfig.cpp:981 msgid "" "If expressed as absolute value in mm/s, this speed will be applied to all " "the print moves of the first layer, regardless of their type. If expressed " @@ -5496,17 +10035,39 @@ msgstr "" "вона виражена у відсотках (наприклад: 40%), вона буде масштабувати швидкість " "за замовчуванням." -#: src/libslic3r/PrintConfig.cpp:862 -msgid "" -"Extruder temperature for first layer. If you want to control temperature " -"manually during print, set this to zero to disable temperature control " -"commands in the output file." -msgstr "" -"Температура екструдеру для першого шару. Якщо ви хочете контролювати " -"температуру вручну під час друку, встановіть 0, щоб вимкнути команди " -"керування температурою у вихідному файлі." +#: src/libslic3r/PrintConfig.cpp:991 +msgid "First layer nozzle temperature" +msgstr "Температура сопла на першому шарі" -#: src/libslic3r/PrintConfig.cpp:871 +#: src/libslic3r/PrintConfig.cpp:992 +msgid "" +"Nozzle temperature for the first layer. If you want to control temperature " +"manually during print, set this to zero to disable temperature control " +"commands in the output G-code." +msgstr "" +"Температура сопла для першого шару. Якщо ви хочете контролювати температуру " +"вручну під час друку, встановіть її на нуль, щоб вимкнути команди контролю " +"температури у вихідному G-коді." + +#: src/libslic3r/PrintConfig.cpp:1000 +msgid "Full fan speed at layer" +msgstr "Повна швидкість вентилятора на шарі" + +#: src/libslic3r/PrintConfig.cpp:1001 +msgid "" +"Fan speed will be ramped up linearly from zero at layer " +"\"disable_fan_first_layers\" to maximum at layer \"full_fan_speed_layer\". " +"\"full_fan_speed_layer\" will be ignored if lower than " +"\"disable_fan_first_layers\", in which case the fan will be running at " +"maximum allowed speed at layer \"disable_fan_first_layers\" + 1." +msgstr "" +"Швидкість вентилятора буде збільшена лінійно з нуля на шарі " +"\"disable_fan_first_layers\" до максимальної на шарі \"full_fan_speed_layer" +"\". \"full_fan_speed_layer\" буде проігноровано, якщо нижче " +"\"disable_fan_first_layers\", і в цьому випадку вентилятор буде працювати з " +"максимально дозволеною швидкістю на рівні \"disable_fan_first_layers\" + 1." + +#: src/libslic3r/PrintConfig.cpp:1013 msgid "" "Speed for filling small gaps using short zigzag moves. Keep this reasonably " "low to avoid too much shaking and resonance issues. Set zero to disable gaps " @@ -5517,11 +10078,11 @@ msgstr "" "надмірних потрясінь та резонансних проблем. Встановити 0, щоб вимкнути " "заповнення розривів." -#: src/libslic3r/PrintConfig.cpp:879 +#: src/libslic3r/PrintConfig.cpp:1021 msgid "Verbose G-code" msgstr "Докладний G-код" -#: src/libslic3r/PrintConfig.cpp:880 +#: src/libslic3r/PrintConfig.cpp:1022 msgid "" "Enable this to get a commented G-code file, with each line explained by a " "descriptive text. If you print from SD card, the additional weight of the " @@ -5531,38 +10092,57 @@ msgstr "" "пояснюється описовим текстом. Якщо ви друкуєте з SD-карти, додаткова вага " "файлу може призвести до уповільнення прошивки." -#: src/libslic3r/PrintConfig.cpp:887 +#: src/libslic3r/PrintConfig.cpp:1029 msgid "G-code flavor" msgstr "Особливість G-коду" -#: src/libslic3r/PrintConfig.cpp:888 +#: src/libslic3r/PrintConfig.cpp:1030 msgid "" "Some G/M-code commands, including temperature control and others, are not " "universal. Set this option to your printer's firmware to get a compatible " -"output. The \"No extrusion\" flavor prevents Slic3r from exporting any " +"output. The \"No extrusion\" flavor prevents PrusaSlicer from exporting any " "extrusion value at all." msgstr "" -"Деякі команди G/M-коду, включаючи контроль температури тощо, не є " -"універсальними. Установіть цей параметр на прошивку принтера, щоб отримати " -"сумісний вихід. \"Відсутність екструзії\" не дозволяє Slic3r експортувати " -"будь-яке значення екструзії." +"Деякі команди G/M-коду, включаючи контроль температури та інші, не є " +"універсальними. Встановіть для цього параметра мікропрограму принтера, щоб " +"отримати сумісний вихід. Наявність вибору \"Без екструзії\" захищаюсь " +"PrusaSlicer від експорту взагалі будь-яких екструзійних значень." -#: src/libslic3r/PrintConfig.cpp:911 +#: src/libslic3r/PrintConfig.cpp:1055 msgid "No extrusion" -msgstr "" +msgstr "Без екструзії" -#: src/libslic3r/PrintConfig.cpp:924 +#: src/libslic3r/PrintConfig.cpp:1060 +msgid "Label objects" +msgstr "Маркувати об'єкти" + +#: src/libslic3r/PrintConfig.cpp:1061 +msgid "" +"Enable this to add comments into the G-Code labeling print moves with what " +"object they belong to, which is useful for the Octoprint CancelObject " +"plugin. This settings is NOT compatible with Single Extruder Multi Material " +"setup and Wipe into Object / Wipe into Infill." +msgstr "" +"Увімкніть це, щоб додати коментарі до ходів друку міток G-Code із об’єктом, " +"до якого вони належать, що корисно для плагіна Octoprint CancelObject. Ці " +"налаштування НЕ сумісні з параметрами \"Мульти-матеріальний (ММ) друк з " +"одним екструдером\" та \"Витирати в об'єкт\" / \"Витирати в заповнення\"." + +#: src/libslic3r/PrintConfig.cpp:1068 msgid "High extruder current on filament swap" -msgstr "" +msgstr "Звищення струму екструдера на заміні філамента" -#: src/libslic3r/PrintConfig.cpp:925 +#: src/libslic3r/PrintConfig.cpp:1069 msgid "" "It may be beneficial to increase the extruder motor current during the " "filament exchange sequence to allow for rapid ramming feed rates and to " "overcome resistance when loading a filament with an ugly shaped tip." msgstr "" +"Може бути корисно збільшити струм двигуна екструдера під час заміни " +"філаменту, щоб забезпечити швидкий раммінг та подолати опір при заведенні " +"філаменту з кінчиком потворної форми." -#: src/libslic3r/PrintConfig.cpp:933 +#: src/libslic3r/PrintConfig.cpp:1077 msgid "" "This is the acceleration your printer will use for infill. Set zero to " "disable acceleration control for infill." @@ -5570,11 +10150,11 @@ msgstr "" "Це прискорення, яке ваш принтер використовуватиме для наповнення. Встановити " "0, щоб вимкнути регулятор прискорення для заповнення." -#: src/libslic3r/PrintConfig.cpp:941 +#: src/libslic3r/PrintConfig.cpp:1085 msgid "Combine infill every" msgstr "Об'єднати наповнення кожні" -#: src/libslic3r/PrintConfig.cpp:943 +#: src/libslic3r/PrintConfig.cpp:1087 msgid "" "This feature allows to combine infill and speed up your print by extruding " "thicker infill layers while preserving thin perimeters, thus accuracy." @@ -5582,19 +10162,83 @@ msgstr "" "Ця функція дозволяє поєднувати наповнення та прискорити друк, екструдуючи " "більш товсті шари наповнення, зберігаючи тонкі периметри, а отже, і точністю." -#: src/libslic3r/PrintConfig.cpp:946 +#: src/libslic3r/PrintConfig.cpp:1090 msgid "Combine infill every n layers" msgstr "Об'єднати наповнення кожні n шарів" -#: src/libslic3r/PrintConfig.cpp:952 +#: src/libslic3r/PrintConfig.cpp:1096 +msgid "Length of the infill anchor" +msgstr "Довжина якоря заповнення" + +#: src/libslic3r/PrintConfig.cpp:1098 +msgid "" +"Connect an infill line to an internal perimeter with a short segment of an " +"additional perimeter. If expressed as percentage (example: 15%) it is " +"calculated over infill extrusion width. PrusaSlicer tries to connect two " +"close infill lines to a short perimeter segment. If no such perimeter " +"segment shorter than infill_anchor_max is found, the infill line is " +"connected to a perimeter segment at just one side and the length of the " +"perimeter segment taken is limited to this parameter, but no longer than " +"anchor_length_max. Set this parameter to zero to disable anchoring " +"perimeters connected to a single infill line." +msgstr "" +"З'єднати лінію заповнення з внутрішнім периметром за допомогою короткого " +"відрізку додаткового периметра. Якщо це значення виражається у відсотках " +"(приклад: 15%), воно розраховується за шириною екструзії заповнення. " +"PrusaSlicer намагається з'єднати дві тісні лінії заповнення з коротким " +"периметром. Якщо такого відрізка периметра, коротшого за infill_anchor_max, " +"не знайдено, лінія заповнення з'єднується з відрізком периметра лише з " +"одного боку, і довжина прийнятого відрізка периметра обмежена цим " +"параметром, але не довше anchor_length_max. Встановіть для цього параметра " +"нуль, щоб вимкнути периметри закріплення, підключені до однієї лінії " +"заповнення." + +#: src/libslic3r/PrintConfig.cpp:1113 +msgid "0 (no open anchors)" +msgstr "0 (без відкритих якорів)" + +#: src/libslic3r/PrintConfig.cpp:1118 src/libslic3r/PrintConfig.cpp:1140 +msgid "1000 (unlimited)" +msgstr "1000 (необмежено)" + +#: src/libslic3r/PrintConfig.cpp:1123 +msgid "Maximum length of the infill anchor" +msgstr "Максимальна довжина якоря заповнення" + +#: src/libslic3r/PrintConfig.cpp:1125 +msgid "" +"Connect an infill line to an internal perimeter with a short segment of an " +"additional perimeter. If expressed as percentage (example: 15%) it is " +"calculated over infill extrusion width. PrusaSlicer tries to connect two " +"close infill lines to a short perimeter segment. If no such perimeter " +"segment shorter than this parameter is found, the infill line is connected " +"to a perimeter segment at just one side and the length of the perimeter " +"segment taken is limited to infill_anchor, but no longer than this " +"parameter. Set this parameter to zero to disable anchoring." +msgstr "" +"З'єднати лінію заповнення з внутрішнім периметром за допомогою короткого " +"відрізку додаткового периметра. Якщо це значення виражається у відсотках " +"(приклад: 15%), воно розраховується за шириною екструзії заповнення. " +"PrusaSlicer намагається з'єднати дві найближчі лінії заповнення з коротким " +"периметром. Якщо такого відрізка периметра, коротшого за цей параметр, не " +"знайдено, лінія заповнення з'єднується з відрізком периметра лише з одного " +"боку, і довжина прийнятого відрізка периметра обмежена параметром " +"infill_anchor, але не довше за цей параметр. Встановіть для цього параметра " +"нуль, щоб вимкнути закріплення." + +#: src/libslic3r/PrintConfig.cpp:1135 +msgid "0 (not anchored)" +msgstr "0 (не закріплено)" + +#: src/libslic3r/PrintConfig.cpp:1145 msgid "Infill extruder" msgstr "Наповнювач екструдера" -#: src/libslic3r/PrintConfig.cpp:954 +#: src/libslic3r/PrintConfig.cpp:1147 msgid "The extruder to use when printing infill." msgstr "Екструдер, використовуваний під час друку наповнення." -#: src/libslic3r/PrintConfig.cpp:962 +#: src/libslic3r/PrintConfig.cpp:1155 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill. If " "left zero, default extrusion width will be used if set, otherwise 1.125 x " @@ -5609,11 +10253,11 @@ msgstr "" "прискорити наповнення та зміцнити свої деталі. Якщо він виражений у " "відсотках (наприклад, 90%), він буде обчислюватися за висотою шару." -#: src/libslic3r/PrintConfig.cpp:971 +#: src/libslic3r/PrintConfig.cpp:1165 msgid "Infill before perimeters" msgstr "Заповнення перед периметрами" -#: src/libslic3r/PrintConfig.cpp:972 +#: src/libslic3r/PrintConfig.cpp:1166 msgid "" "This option will switch the print order of perimeters and infill, making the " "latter first." @@ -5621,11 +10265,11 @@ msgstr "" "За допомогою цього параметра можна буде змінити порядок друку периметрів та " "наповнювачів, зробивши останнє першим." -#: src/libslic3r/PrintConfig.cpp:977 +#: src/libslic3r/PrintConfig.cpp:1171 msgid "Only infill where needed" msgstr "Заповнити тільки там, де потрібно" -#: src/libslic3r/PrintConfig.cpp:979 +#: src/libslic3r/PrintConfig.cpp:1173 msgid "" "This option will limit infill to the areas actually needed for supporting " "ceilings (it will act as internal support material). If enabled, slows down " @@ -5635,11 +10279,11 @@ msgstr "" "стель (це буде діяти як внутрішній матеріал підтримки). Якщо це ввімкнено, " "сповільнюється генерація G-коду через декілька перевірок." -#: src/libslic3r/PrintConfig.cpp:986 +#: src/libslic3r/PrintConfig.cpp:1180 msgid "Infill/perimeters overlap" msgstr "Перекриття наповнення/периметрів" -#: src/libslic3r/PrintConfig.cpp:988 +#: src/libslic3r/PrintConfig.cpp:1182 msgid "" "This setting applies an additional overlap between infill and perimeters for " "better bonding. Theoretically this shouldn't be needed, but backlash might " @@ -5651,25 +10295,25 @@ msgstr "" "може спричинити розриви. Якщо він виражений у відсотках (приклад: 15%), його " "розраховують за шириною екструзії по периметру." -#: src/libslic3r/PrintConfig.cpp:999 +#: src/libslic3r/PrintConfig.cpp:1193 msgid "Speed for printing the internal fill. Set to zero for auto." msgstr "" "Швидкість друку внутрішнього заповнення. Встановити 0 для автоматичного " "обчислення." -#: src/libslic3r/PrintConfig.cpp:1007 +#: src/libslic3r/PrintConfig.cpp:1201 msgid "Inherits profile" -msgstr "" +msgstr "Успадковує профіль" -#: src/libslic3r/PrintConfig.cpp:1008 +#: src/libslic3r/PrintConfig.cpp:1202 msgid "Name of the profile, from which this profile inherits." -msgstr "" +msgstr "Ім'я профілю, від якого цей профіль успадковується." -#: src/libslic3r/PrintConfig.cpp:1021 +#: src/libslic3r/PrintConfig.cpp:1215 msgid "Interface shells" msgstr "Інтерфейсні оболонки" -#: src/libslic3r/PrintConfig.cpp:1022 +#: src/libslic3r/PrintConfig.cpp:1216 msgid "" "Force the generation of solid shells between adjacent materials/volumes. " "Useful for multi-extruder prints with translucent materials or manual " @@ -5679,7 +10323,50 @@ msgstr "" "Корисно для друку з багатьма екструдерами з напівпрозорими матеріалами або " "ручним розчинним матеріалом для підтримки." -#: src/libslic3r/PrintConfig.cpp:1031 +#: src/libslic3r/PrintConfig.cpp:1224 +msgid "Enable ironing" +msgstr "Увімкнути прасування" + +#: src/libslic3r/PrintConfig.cpp:1225 +msgid "" +"Enable ironing of the top layers with the hot print head for smooth surface" +msgstr "" +"Для гладкої поверхні увімкніть прасування верхніх шарів гарячою друкуючою " +"головкою" + +#: src/libslic3r/PrintConfig.cpp:1231 src/libslic3r/PrintConfig.cpp:1233 +msgid "Ironing Type" +msgstr "Тип прасування" + +#: src/libslic3r/PrintConfig.cpp:1238 +msgid "All top surfaces" +msgstr "Всі верхні поверхні" + +#: src/libslic3r/PrintConfig.cpp:1239 +msgid "Topmost surface only" +msgstr "Тільки верхня поверхня" + +#: src/libslic3r/PrintConfig.cpp:1240 +msgid "All solid surfaces" +msgstr "Всі тверді поверхні" + +#: src/libslic3r/PrintConfig.cpp:1245 +msgid "Flow rate" +msgstr "Швидкість потоку" + +#: src/libslic3r/PrintConfig.cpp:1247 +msgid "Percent of a flow rate relative to object's normal layer height." +msgstr "Відсоток швидкість потоку відносно нормальної висоти шару об'єкта." + +#: src/libslic3r/PrintConfig.cpp:1255 +msgid "Spacing between ironing passes" +msgstr "Відстань між лініями прасування" + +#: src/libslic3r/PrintConfig.cpp:1257 +msgid "Distance between ironing lines" +msgstr "Відстань між прасувальними лініями" + +#: src/libslic3r/PrintConfig.cpp:1274 msgid "" "This custom code is inserted at every layer change, right after the Z move " "and before the extruder moves to the first layer point. Note that you can " @@ -5688,79 +10375,194 @@ msgid "" msgstr "" "Цей користувацький код вставляється при кожній зміні шару відразу після " "переміщення Z і перед тим, як екструдер переміститься до точки першого шару. " -"Зауважте, що ви можете використовувати змінні-заповнювачі для всіх " -"параметрів Slic3r, а також [layer_num] і [layer_z]." +"Зауважте, що ви можете використовувати шаблонні змінні для всіх параметрів " +"Slic3r, а також [layer_num] і [layer_z]." -#: src/libslic3r/PrintConfig.cpp:1042 +#: src/libslic3r/PrintConfig.cpp:1285 msgid "Supports remaining times" -msgstr "" +msgstr "Підтримує час, що залишився" -#: src/libslic3r/PrintConfig.cpp:1043 +#: src/libslic3r/PrintConfig.cpp:1286 msgid "" "Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute " "intervals into the G-code to let the firmware show accurate remaining time. " "As of now only the Prusa i3 MK3 firmware recognizes M73. Also the i3 MK3 " "firmware supports M73 Qxx Sxx for the silent mode." msgstr "" +"Публікувати M73 P[відсоток друку] R[час, що залишився у хвилинах] з " +"інтервалом у 1 хвилину в G-код, щоб прошивка показувала точний час, що " +"залишився. На сьогоднішній день лише прошивка Prusa i3 MK3 розпізнає M73. " +"Також прошивка i3 MK3 підтримує M73 Qxx Sxx для тихого режиму." -#: src/libslic3r/PrintConfig.cpp:1051 -msgid "Supports silent mode" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1294 +msgid "Supports stealth mode" +msgstr "Підтримує тихий режим" -#: src/libslic3r/PrintConfig.cpp:1052 -msgid "Set silent mode for the G-code flavor" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1295 +msgid "The firmware supports stealth mode" +msgstr "Прошивка підтримує тихий режим" -#: src/libslic3r/PrintConfig.cpp:1075 -msgid "Maximum feedrate %1%" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1300 +msgid "How to apply limits" +msgstr "Як застосовувати обмеження" -#: src/libslic3r/PrintConfig.cpp:1077 -msgid "Maximum feedrate of the %1% axis" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1301 +msgid "Purpose of Machine Limits" +msgstr "Призначення механічних обмежень" -#: src/libslic3r/PrintConfig.cpp:1085 -msgid "Maximum acceleration %1%" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1303 +msgid "How to apply the Machine Limits" +msgstr "Призначення механічних обмежень" -#: src/libslic3r/PrintConfig.cpp:1087 -msgid "Maximum acceleration of the %1% axis" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1308 +msgid "Emit to G-code" +msgstr "Публікувати в G-код" -#: src/libslic3r/PrintConfig.cpp:1095 -msgid "Maximum jerk %1%" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1309 +msgid "Use for time estimate" +msgstr "Для оцінки часу" -#: src/libslic3r/PrintConfig.cpp:1097 -msgid "Maximum jerk of the %1% axis" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:1310 +msgid "Ignore" +msgstr "Ігнорувати" -#: src/libslic3r/PrintConfig.cpp:1108 src/libslic3r/PrintConfig.cpp:1110 +#: src/libslic3r/PrintConfig.cpp:1333 +msgid "Maximum feedrate X" +msgstr "Максимальна швидкість подачі за X" + +#: src/libslic3r/PrintConfig.cpp:1334 +msgid "Maximum feedrate Y" +msgstr "Максимальна швидкість подачі за Y" + +#: src/libslic3r/PrintConfig.cpp:1335 +msgid "Maximum feedrate Z" +msgstr "Максимальна швидкість подачі за Y" + +#: src/libslic3r/PrintConfig.cpp:1336 +msgid "Maximum feedrate E" +msgstr "Максимальна швидкість подачі за Е" + +#: src/libslic3r/PrintConfig.cpp:1339 +msgid "Maximum feedrate of the X axis" +msgstr "Максимальна швидкість подачі за віссю X" + +#: src/libslic3r/PrintConfig.cpp:1340 +msgid "Maximum feedrate of the Y axis" +msgstr "Максимальна швидкість подачі за віссю Y" + +#: src/libslic3r/PrintConfig.cpp:1341 +msgid "Maximum feedrate of the Z axis" +msgstr "Максимальна швидкість подачі за віссю Z" + +#: src/libslic3r/PrintConfig.cpp:1342 +msgid "Maximum feedrate of the E axis" +msgstr "Максимальна швидкість подачі за віссю Е" + +#: src/libslic3r/PrintConfig.cpp:1350 +msgid "Maximum acceleration X" +msgstr "Максимальне прискорення X" + +#: src/libslic3r/PrintConfig.cpp:1351 +msgid "Maximum acceleration Y" +msgstr "Максимальне прискорення Y" + +#: src/libslic3r/PrintConfig.cpp:1352 +msgid "Maximum acceleration Z" +msgstr "Максимальне прискорення Z" + +#: src/libslic3r/PrintConfig.cpp:1353 +msgid "Maximum acceleration E" +msgstr "Максимальне прискорення E" + +#: src/libslic3r/PrintConfig.cpp:1356 +msgid "Maximum acceleration of the X axis" +msgstr "Максимальне прискорення за віссю X" + +#: src/libslic3r/PrintConfig.cpp:1357 +msgid "Maximum acceleration of the Y axis" +msgstr "Максимальне прискорення за віссю Y" + +#: src/libslic3r/PrintConfig.cpp:1358 +msgid "Maximum acceleration of the Z axis" +msgstr "Максимальне прискорення за віссю Z" + +#: src/libslic3r/PrintConfig.cpp:1359 +msgid "Maximum acceleration of the E axis" +msgstr "Максимальне прискорення за віссю E" + +#: src/libslic3r/PrintConfig.cpp:1367 +msgid "Maximum jerk X" +msgstr "Максимальний ривок за X" + +#: src/libslic3r/PrintConfig.cpp:1368 +msgid "Maximum jerk Y" +msgstr "Максимальний ривок за Y" + +#: src/libslic3r/PrintConfig.cpp:1369 +msgid "Maximum jerk Z" +msgstr "Максимальний ривок за Z" + +#: src/libslic3r/PrintConfig.cpp:1370 +msgid "Maximum jerk E" +msgstr "Максимальний ривок за E" + +#: src/libslic3r/PrintConfig.cpp:1373 +msgid "Maximum jerk of the X axis" +msgstr "Максимальний ривок за віссю X" + +#: src/libslic3r/PrintConfig.cpp:1374 +msgid "Maximum jerk of the Y axis" +msgstr "Максимальний ривок за віссю Y" + +#: src/libslic3r/PrintConfig.cpp:1375 +msgid "Maximum jerk of the Z axis" +msgstr "Максимальний ривок за віссю Z" + +#: src/libslic3r/PrintConfig.cpp:1376 +msgid "Maximum jerk of the E axis" +msgstr "Максимальний ривок за віссю E" + +#: src/libslic3r/PrintConfig.cpp:1386 msgid "Minimum feedrate when extruding" -msgstr "" +msgstr "Мінімальне прискорення при екструзії" -#: src/libslic3r/PrintConfig.cpp:1119 src/libslic3r/PrintConfig.cpp:1121 +#: src/libslic3r/PrintConfig.cpp:1388 +msgid "Minimum feedrate when extruding (M205 S)" +msgstr "Мінімальне прискорення при екструзії (M205 S)" + +#: src/libslic3r/PrintConfig.cpp:1396 msgid "Minimum travel feedrate" -msgstr "" +msgstr "Мінімальна швидкість подачі" -#: src/libslic3r/PrintConfig.cpp:1130 src/libslic3r/PrintConfig.cpp:1132 +#: src/libslic3r/PrintConfig.cpp:1398 +msgid "Minimum travel feedrate (M205 T)" +msgstr "Мінімальна швидкість подачі (M205 T)" + +#: src/libslic3r/PrintConfig.cpp:1406 msgid "Maximum acceleration when extruding" -msgstr "" +msgstr "Максимальне прискорення при екструзії" -#: src/libslic3r/PrintConfig.cpp:1141 src/libslic3r/PrintConfig.cpp:1143 +#: src/libslic3r/PrintConfig.cpp:1408 +msgid "Maximum acceleration when extruding (M204 S)" +msgstr "Максимальне прискорення при екструзії (M204 S)" + +#: src/libslic3r/PrintConfig.cpp:1416 msgid "Maximum acceleration when retracting" -msgstr "" +msgstr "Максимальне прискорення при втягуванні" -#: src/libslic3r/PrintConfig.cpp:1151 src/libslic3r/PrintConfig.cpp:1160 +#: src/libslic3r/PrintConfig.cpp:1418 +msgid "Maximum acceleration when retracting (M204 T)" +msgstr "Максимальне прискорення при втягуванні (M204 T)" + +#: src/libslic3r/PrintConfig.cpp:1425 src/libslic3r/PrintConfig.cpp:1434 msgid "Max" msgstr "Максимально" -#: src/libslic3r/PrintConfig.cpp:1152 +#: src/libslic3r/PrintConfig.cpp:1426 msgid "This setting represents the maximum speed of your fan." msgstr "Цей параметр відображає максимальну швидкість вашого вентилятора." -#: src/libslic3r/PrintConfig.cpp:1161 -#, no-c-format +#: src/libslic3r/PrintConfig.cpp:1435 msgid "" "This is the highest printable layer height for this extruder, used to cap " "the variable layer height and support layer height. Maximum recommended " @@ -5773,11 +10575,11 @@ msgstr "" "для досягнення розумної міжшарової адгезії. Якщо встановлено 0, висота шару " "обмежена 75% діаметра сопла." -#: src/libslic3r/PrintConfig.cpp:1171 +#: src/libslic3r/PrintConfig.cpp:1445 msgid "Max print speed" msgstr "Максимальна швидкість друку" -#: src/libslic3r/PrintConfig.cpp:1172 +#: src/libslic3r/PrintConfig.cpp:1446 msgid "" "When setting other speed settings to 0 Slic3r will autocalculate the optimal " "speed in order to keep constant extruder pressure. This experimental setting " @@ -5788,7 +10590,7 @@ msgstr "" "екструдера. Цей експериментальний параметр використовується для встановлення " "максимальної швидкості друку, яку ви хочете дозволити." -#: src/libslic3r/PrintConfig.cpp:1182 +#: src/libslic3r/PrintConfig.cpp:1456 msgid "" "This experimental setting is used to set the maximum volumetric speed your " "extruder supports." @@ -5796,11 +10598,11 @@ msgstr "" "Цей експериментальний параметр використовується для встановлення " "максимальної об'ємної швидкості, яку підтримує екструдер." -#: src/libslic3r/PrintConfig.cpp:1191 +#: src/libslic3r/PrintConfig.cpp:1465 msgid "Max volumetric slope positive" msgstr "Максимальний об'ємний нахил позитивний" -#: src/libslic3r/PrintConfig.cpp:1192 src/libslic3r/PrintConfig.cpp:1203 +#: src/libslic3r/PrintConfig.cpp:1466 src/libslic3r/PrintConfig.cpp:1477 msgid "" "This experimental setting is used to limit the speed of change in extrusion " "rate. A value of 1.8 mm³/s² ensures, that a change from the extrusion rate " @@ -5813,25 +10615,25 @@ msgstr "" "швидкість подачі 20 мм/с) до 5,4 мм³/с (подача 60 мм/с) займе принаймні 2 " "секунди." -#: src/libslic3r/PrintConfig.cpp:1196 src/libslic3r/PrintConfig.cpp:1207 +#: src/libslic3r/PrintConfig.cpp:1470 src/libslic3r/PrintConfig.cpp:1481 msgid "mm³/s²" msgstr "мм³/с²" -#: src/libslic3r/PrintConfig.cpp:1202 +#: src/libslic3r/PrintConfig.cpp:1476 msgid "Max volumetric slope negative" msgstr "Максимальний об'ємний схил негативний" -#: src/libslic3r/PrintConfig.cpp:1214 src/libslic3r/PrintConfig.cpp:1223 +#: src/libslic3r/PrintConfig.cpp:1488 src/libslic3r/PrintConfig.cpp:1497 msgid "Min" msgstr "Мінімально" -#: src/libslic3r/PrintConfig.cpp:1215 +#: src/libslic3r/PrintConfig.cpp:1489 msgid "This setting represents the minimum PWM your fan needs to work." msgstr "" "Цей параметр відповідає мінімальній ШІМ, на якій повинен працювати ваш " "вентилятор." -#: src/libslic3r/PrintConfig.cpp:1224 +#: src/libslic3r/PrintConfig.cpp:1498 msgid "" "This is the lowest printable layer height for this extruder and limits the " "resolution for variable layer height. Typical values are between 0.05 mm and " @@ -5841,19 +10643,19 @@ msgstr "" "роздільну здатність для висоти змінного шару. Типові значення - від 0,05 мм " "до 0,1 мм." -#: src/libslic3r/PrintConfig.cpp:1232 +#: src/libslic3r/PrintConfig.cpp:1506 msgid "Min print speed" msgstr "Мінімальна швидкість друку" -#: src/libslic3r/PrintConfig.cpp:1233 +#: src/libslic3r/PrintConfig.cpp:1507 msgid "Slic3r will not scale speed down below this speed." msgstr "Slic3r не буде масштабувати швидкість нижче цієї швидкості." -#: src/libslic3r/PrintConfig.cpp:1240 +#: src/libslic3r/PrintConfig.cpp:1514 msgid "Minimal filament extrusion length" -msgstr "" +msgstr "Мінімальна довжина екструзії філаменту" -#: src/libslic3r/PrintConfig.cpp:1241 +#: src/libslic3r/PrintConfig.cpp:1515 msgid "" "Generate no less than the number of skirt loops required to consume the " "specified amount of filament on the bottom layer. For multi-extruder " @@ -5863,11 +10665,11 @@ msgstr "" "зазначеної кількості філаменту на нижньому шарі. Для машин із декількома " "екструдерами цей мінімум застосовується до кожного екструдера." -#: src/libslic3r/PrintConfig.cpp:1250 +#: src/libslic3r/PrintConfig.cpp:1524 msgid "Configuration notes" msgstr "Примітки до конфігурації" -#: src/libslic3r/PrintConfig.cpp:1251 +#: src/libslic3r/PrintConfig.cpp:1525 msgid "" "You can put here your personal notes. This text will be added to the G-code " "header comments." @@ -5875,30 +10677,28 @@ msgstr "" "Ви можете додати тут свої особисті примітки. Цей текст буде додано до " "коментарів заголовка G-коду." -#: src/libslic3r/PrintConfig.cpp:1260 -msgid "Nozzle diameter" -msgstr "Діаметр сопла" - -#: src/libslic3r/PrintConfig.cpp:1261 +#: src/libslic3r/PrintConfig.cpp:1535 msgid "" "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)" msgstr "Це діаметр сопла вашого екструдера (наприклад: 0.5, 0.35 тощо)" -#: src/libslic3r/PrintConfig.cpp:1266 +#: src/libslic3r/PrintConfig.cpp:1540 msgid "Host Type" -msgstr "" +msgstr "Тип хосту" -#: src/libslic3r/PrintConfig.cpp:1267 +#: src/libslic3r/PrintConfig.cpp:1541 msgid "" "Slic3r can upload G-code files to a printer host. This field must contain " "the kind of the host." msgstr "" +"Slic3r може завантажувати файли G-коду на хост принтера. Це поле повинно " +"містити тип хоста." -#: src/libslic3r/PrintConfig.cpp:1278 +#: src/libslic3r/PrintConfig.cpp:1558 msgid "Only retract when crossing perimeters" msgstr "Перервати тільки у разі перетину периметрів" -#: src/libslic3r/PrintConfig.cpp:1279 +#: src/libslic3r/PrintConfig.cpp:1559 msgid "" "Disables retraction when the travel path does not exceed the upper layer's " "perimeters (and thus any ooze will be probably invisible)." @@ -5906,7 +10706,7 @@ msgstr "" "Вимикає переривання, коли шлях не перевищує периметри верхніх шарів (і, " "таким чином, будь-який розрядник буде, мабуть, невидимим)." -#: src/libslic3r/PrintConfig.cpp:1286 +#: src/libslic3r/PrintConfig.cpp:1566 msgid "" "This option will drop the temperature of the inactive extruders to prevent " "oozing. It will enable a tall skirt automatically and move extruders outside " @@ -5916,11 +10716,11 @@ msgstr "" "протіканню. Це дозволить автоматично ввімкнути високий плінтус та " "перемістить екструдери за межі такого плінтуса у разі зміни температури." -#: src/libslic3r/PrintConfig.cpp:1293 +#: src/libslic3r/PrintConfig.cpp:1573 msgid "Output filename format" msgstr "Формат вихідного файлу" -#: src/libslic3r/PrintConfig.cpp:1294 +#: src/libslic3r/PrintConfig.cpp:1574 msgid "" "You can use all configuration options as variables inside this template. For " "example: [layer_height], [fill_density] etc. You can also use [timestamp], " @@ -5932,11 +10732,11 @@ msgstr "" "можете використовувати [timestamp], [year], [month], [day], [hour], " "[minute], [second], [version], [input_filename] ], [input_filename_base]." -#: src/libslic3r/PrintConfig.cpp:1303 +#: src/libslic3r/PrintConfig.cpp:1583 msgid "Detect bridging perimeters" msgstr "Виявлення висячих периметрів" -#: src/libslic3r/PrintConfig.cpp:1305 +#: src/libslic3r/PrintConfig.cpp:1585 msgid "" "Experimental option to adjust flow for overhangs (bridge flow will be used), " "to apply bridge speed to them and enable fan." @@ -5945,56 +10745,59 @@ msgstr "" "використано мостовий потік), щоб застосувати до них швидкість мосту та " "увімкнути вентилятор." -#: src/libslic3r/PrintConfig.cpp:1311 +#: src/libslic3r/PrintConfig.cpp:1591 msgid "Filament parking position" -msgstr "" +msgstr "Позиція паркування філаменту" -#: src/libslic3r/PrintConfig.cpp:1312 +#: src/libslic3r/PrintConfig.cpp:1592 msgid "" "Distance of the extruder tip from the position where the filament is parked " -"when unloaded. This should match the value in printer firmware. " +"when unloaded. This should match the value in printer firmware." msgstr "" +"Відстань наконечника екструдера від місця паркування філаменту при " +"виведенні. Це має відповідати значенню в мікропрограмі принтера." -#: src/libslic3r/PrintConfig.cpp:1320 +#: src/libslic3r/PrintConfig.cpp:1600 msgid "Extra loading distance" -msgstr "" +msgstr "Додаткова відстань заведення" -#: src/libslic3r/PrintConfig.cpp:1321 +#: src/libslic3r/PrintConfig.cpp:1601 msgid "" "When set to zero, the distance the filament is moved from parking position " "during load is exactly the same as it was moved back during unload. When " "positive, it is loaded further, if negative, the loading move is shorter " -"than unloading. " +"than unloading." msgstr "" +"Якщо встановлено на нуль, відстань, на яку філамент переміщується з " +"положення стоянки під час заведення, є точно такою ж, як і при переміщенні " +"назад під час виведення. Якщо позитивне, воно заводеться далі, якщо " +"негативне, рух заведення коротший, ніж виведення." -#: src/libslic3r/PrintConfig.cpp:1329 src/libslic3r/PrintConfig.cpp:1347 -#: src/libslic3r/PrintConfig.cpp:1359 src/libslic3r/PrintConfig.cpp:1369 +#: src/libslic3r/PrintConfig.cpp:1609 src/libslic3r/PrintConfig.cpp:1626 +#: src/libslic3r/PrintConfig.cpp:1639 src/libslic3r/PrintConfig.cpp:1649 msgid "Perimeters" msgstr "Периметри" -#: src/libslic3r/PrintConfig.cpp:1330 +#: src/libslic3r/PrintConfig.cpp:1610 msgid "" -"This is the acceleration your printer will use for perimeters. A high value " -"like 9000 usually gives good results if your hardware is up to the job. Set " -"zero to disable acceleration control for perimeters." +"This is the acceleration your printer will use for perimeters. Set zero to " +"disable acceleration control for perimeters." msgstr "" -"Це прискорення, яке ваш принтер використовуватиме для периметрів. Висока " -"значення, таке як 9000, зазвичай дає хороші результати, якщо ваше апаратне " -"забезпечення відповідає завданню. Встановити 0, щоб вимкнути регулятор " -"прискорення для периметрів." +"Це прискорення, яке ваш принтер використовуватиме для периметрів. Встановити " +"0, щоб відключити управління прискоренням для периметрів." -#: src/libslic3r/PrintConfig.cpp:1338 +#: src/libslic3r/PrintConfig.cpp:1617 msgid "Perimeter extruder" msgstr "Екструдер периметру" -#: src/libslic3r/PrintConfig.cpp:1340 +#: src/libslic3r/PrintConfig.cpp:1619 msgid "" "The extruder to use when printing perimeters and brim. First extruder is 1." msgstr "" "Екструдер, що використовується при друці периметрів і краю. Перший екструдер " "- 1." -#: src/libslic3r/PrintConfig.cpp:1349 +#: src/libslic3r/PrintConfig.cpp:1628 msgid "" "Set this to a non-zero value to set a manual extrusion width for perimeters. " "You may want to use thinner extrudates to get more accurate surfaces. If " @@ -6009,14 +10812,14 @@ msgstr "" "діаметр сопла. Якщо він виражений у відсотках (наприклад, 200%), він буде " "обчислюватися за висотою шару." -#: src/libslic3r/PrintConfig.cpp:1361 +#: src/libslic3r/PrintConfig.cpp:1641 msgid "" "Speed for perimeters (contours, aka vertical shells). Set to zero for auto." msgstr "" "Швидкість для периметрів (контури, вертикальні оболонки). Встановити 0 для " "автоматичного використання." -#: src/libslic3r/PrintConfig.cpp:1371 +#: src/libslic3r/PrintConfig.cpp:1651 msgid "" "This option sets the number of perimeters to generate for each layer. Note " "that Slic3r may increase this number automatically when it detects sloping " @@ -6028,11 +10831,11 @@ msgstr "" "які отримують вигоду від більшої кількості периметрів, якщо опція «Додаткові " "периметри» увімкнена." -#: src/libslic3r/PrintConfig.cpp:1375 +#: src/libslic3r/PrintConfig.cpp:1655 msgid "(minimum)" msgstr "(мінімум)" -#: src/libslic3r/PrintConfig.cpp:1383 +#: src/libslic3r/PrintConfig.cpp:1663 msgid "" "If you want to process the output G-code through custom scripts, just list " "their absolute paths here. Separate multiple scripts with a semicolon. " @@ -6046,45 +10849,47 @@ msgstr "" "аргумент, і вони можуть отримати доступ до параметрів конфігурації Slic3r, " "прочитавши змінні середовища." -#: src/libslic3r/PrintConfig.cpp:1395 +#: src/libslic3r/PrintConfig.cpp:1675 msgid "Printer type" -msgstr "" +msgstr "Тип принтеру" -#: src/libslic3r/PrintConfig.cpp:1396 +#: src/libslic3r/PrintConfig.cpp:1676 msgid "Type of the printer." -msgstr "" +msgstr "Тип принтеру." -#: src/libslic3r/PrintConfig.cpp:1401 +#: src/libslic3r/PrintConfig.cpp:1681 msgid "Printer notes" msgstr "Примітки принтера" -#: src/libslic3r/PrintConfig.cpp:1402 +#: src/libslic3r/PrintConfig.cpp:1682 msgid "You can put your notes regarding the printer here." msgstr "Тут ви можете помістити свої нотатки щодо принтера." -#: src/libslic3r/PrintConfig.cpp:1410 +#: src/libslic3r/PrintConfig.cpp:1690 msgid "Printer vendor" -msgstr "" +msgstr "Виробник принтера" -#: src/libslic3r/PrintConfig.cpp:1411 +#: src/libslic3r/PrintConfig.cpp:1691 msgid "Name of the printer vendor." -msgstr "" +msgstr "Назва виробника принтера." -#: src/libslic3r/PrintConfig.cpp:1416 +#: src/libslic3r/PrintConfig.cpp:1696 msgid "Printer variant" -msgstr "" +msgstr "Варіант принтера" -#: src/libslic3r/PrintConfig.cpp:1417 +#: src/libslic3r/PrintConfig.cpp:1697 msgid "" "Name of the printer variant. For example, the printer variants may be " "differentiated by a nozzle diameter." msgstr "" +"Назва варіанту принтера. Наприклад, варіанти принтера можуть відрізнятися за " +"діаметром сопла." -#: src/libslic3r/PrintConfig.cpp:1430 +#: src/libslic3r/PrintConfig.cpp:1714 msgid "Raft layers" msgstr "Плоскі шари" -#: src/libslic3r/PrintConfig.cpp:1432 +#: src/libslic3r/PrintConfig.cpp:1716 msgid "" "The object will be raised by this number of layers, and support material " "will be generated under it." @@ -6092,11 +10897,11 @@ msgstr "" "Об'єкт буде піднятий цією кількістю шарів, і під ним буде згенерований " "матеріал підтримки." -#: src/libslic3r/PrintConfig.cpp:1440 +#: src/libslic3r/PrintConfig.cpp:1724 msgid "Resolution" msgstr "Роздільна здатність" -#: src/libslic3r/PrintConfig.cpp:1441 +#: src/libslic3r/PrintConfig.cpp:1725 msgid "" "Minimum detail resolution, used to simplify the input file for speeding up " "the slicing job and reducing memory usage. High-resolution models often " @@ -6110,20 +10915,20 @@ msgstr "" "вимкнути будь-яке спрощення та використовувати повну роздільну здатність від " "введення." -#: src/libslic3r/PrintConfig.cpp:1451 +#: src/libslic3r/PrintConfig.cpp:1735 msgid "Minimum travel after retraction" msgstr "Мінімальне переміщення після переривання" -#: src/libslic3r/PrintConfig.cpp:1452 +#: src/libslic3r/PrintConfig.cpp:1736 msgid "" "Retraction is not triggered when travel moves are shorter than this length." msgstr "Переривання не спрацьовує, коли переміщення коротше за цю довжину." -#: src/libslic3r/PrintConfig.cpp:1458 +#: src/libslic3r/PrintConfig.cpp:1742 msgid "Retract amount before wipe" msgstr "Кількість переривань перед чищенням" -#: src/libslic3r/PrintConfig.cpp:1459 +#: src/libslic3r/PrintConfig.cpp:1743 msgid "" "With bowden extruders, it may be wise to do some amount of quick retract " "before doing the wipe movement." @@ -6131,25 +10936,25 @@ msgstr "" "Завдяки екструдерам з бандами, має зміст зробити певну кількість переривань " "перед рухами очищення." -#: src/libslic3r/PrintConfig.cpp:1466 +#: src/libslic3r/PrintConfig.cpp:1750 msgid "Retract on layer change" msgstr "Переривання на зміну шарів" -#: src/libslic3r/PrintConfig.cpp:1467 +#: src/libslic3r/PrintConfig.cpp:1751 msgid "This flag enforces a retraction whenever a Z move is done." msgstr "" "Цей прапор забезпечує переривання кожного разу, коли виконується переміщення " "Z." -#: src/libslic3r/PrintConfig.cpp:1472 src/libslic3r/PrintConfig.cpp:1480 +#: src/libslic3r/PrintConfig.cpp:1756 src/libslic3r/PrintConfig.cpp:1764 msgid "Length" msgstr "Довжина" -#: src/libslic3r/PrintConfig.cpp:1473 +#: src/libslic3r/PrintConfig.cpp:1757 msgid "Retraction Length" msgstr "Довжина переривання" -#: src/libslic3r/PrintConfig.cpp:1474 +#: src/libslic3r/PrintConfig.cpp:1758 msgid "" "When retraction is triggered, filament is pulled back by the specified " "amount (the length is measured on raw filament, before it enters the " @@ -6159,15 +10964,15 @@ msgstr "" "кількості (довжина вимірюється на сирого філаменту перед тим, як вона " "надходить у екструдер)." -#: src/libslic3r/PrintConfig.cpp:1476 src/libslic3r/PrintConfig.cpp:1485 +#: src/libslic3r/PrintConfig.cpp:1760 src/libslic3r/PrintConfig.cpp:1769 msgid "mm (zero to disable)" msgstr "мм (0, щоб вимкнути)" -#: src/libslic3r/PrintConfig.cpp:1481 +#: src/libslic3r/PrintConfig.cpp:1765 msgid "Retraction Length (Toolchange)" msgstr "Довжина переривання (зміна інструмента)" -#: src/libslic3r/PrintConfig.cpp:1482 +#: src/libslic3r/PrintConfig.cpp:1766 msgid "" "When retraction is triggered before changing tool, filament is pulled back " "by the specified amount (the length is measured on raw filament, before it " @@ -6177,11 +10982,11 @@ msgstr "" "назад до вказаної кількості (довжина вимірюється на сирого філаменту перед " "тим, як вона надходить у екструдер)." -#: src/libslic3r/PrintConfig.cpp:1490 +#: src/libslic3r/PrintConfig.cpp:1774 msgid "Lift Z" msgstr "Підняти Z" -#: src/libslic3r/PrintConfig.cpp:1491 +#: src/libslic3r/PrintConfig.cpp:1775 msgid "" "If you set this to a positive value, Z is quickly raised every time a " "retraction is triggered. When using multiple extruders, only the setting for " @@ -6191,15 +10996,15 @@ msgstr "" "коли спрацьовує переривання. При використанні декількох екструдерів буде " "розглянуто налаштування лише першого екструдера." -#: src/libslic3r/PrintConfig.cpp:1498 +#: src/libslic3r/PrintConfig.cpp:1782 msgid "Above Z" msgstr "Вище Z" -#: src/libslic3r/PrintConfig.cpp:1499 +#: src/libslic3r/PrintConfig.cpp:1783 msgid "Only lift Z above" msgstr "Тільки піднімати Z" -#: src/libslic3r/PrintConfig.cpp:1500 +#: src/libslic3r/PrintConfig.cpp:1784 msgid "" "If you set this to a positive value, Z lift will only take place above the " "specified absolute Z. You can tune this setting for skipping lift on the " @@ -6209,15 +11014,15 @@ msgstr "" "вказаним абсолютним Z. Ви можете налаштувати цей параметр так, що підняття " "буде пропускатися на перших шарах." -#: src/libslic3r/PrintConfig.cpp:1507 +#: src/libslic3r/PrintConfig.cpp:1791 msgid "Below Z" msgstr "Нижче Z" -#: src/libslic3r/PrintConfig.cpp:1508 +#: src/libslic3r/PrintConfig.cpp:1792 msgid "Only lift Z below" msgstr "Тільки опускати Z" -#: src/libslic3r/PrintConfig.cpp:1509 +#: src/libslic3r/PrintConfig.cpp:1793 msgid "" "If you set this to a positive value, Z lift will only take place below the " "specified absolute Z. You can tune this setting for limiting lift to the " @@ -6227,11 +11032,11 @@ msgstr "" "вказаного абсолютного Z. Ви можете налаштувати цей параметр так, що підняття " "буде обмежене на перших шарах." -#: src/libslic3r/PrintConfig.cpp:1517 src/libslic3r/PrintConfig.cpp:1525 +#: src/libslic3r/PrintConfig.cpp:1801 src/libslic3r/PrintConfig.cpp:1809 msgid "Extra length on restart" msgstr "Додаткова довжина при перезапуску" -#: src/libslic3r/PrintConfig.cpp:1518 +#: src/libslic3r/PrintConfig.cpp:1802 msgid "" "When the retraction is compensated after the travel move, the extruder will " "push this additional amount of filament. This setting is rarely needed." @@ -6239,7 +11044,7 @@ msgstr "" "Коли переривання компенсується після руху переміщення, екструдер буде " "проштовхувати цю додаткову кількість філамента. Цей параметр рідко потрібний." -#: src/libslic3r/PrintConfig.cpp:1526 +#: src/libslic3r/PrintConfig.cpp:1810 msgid "" "When the retraction is compensated after changing tool, the extruder will " "push this additional amount of filament." @@ -6247,19 +11052,19 @@ msgstr "" "Коли переривання компенсується після зміни інструмента, екструдер буде " "проштовхувати цю додаткову кількість філамента." -#: src/libslic3r/PrintConfig.cpp:1533 src/libslic3r/PrintConfig.cpp:1534 +#: src/libslic3r/PrintConfig.cpp:1817 src/libslic3r/PrintConfig.cpp:1818 msgid "Retraction Speed" msgstr "Швидкість переривання" -#: src/libslic3r/PrintConfig.cpp:1535 +#: src/libslic3r/PrintConfig.cpp:1819 msgid "The speed for retractions (it only applies to the extruder motor)." msgstr "Швидкість переривання (це стосується лише двигуна екструдера)." -#: src/libslic3r/PrintConfig.cpp:1541 src/libslic3r/PrintConfig.cpp:1542 +#: src/libslic3r/PrintConfig.cpp:1825 src/libslic3r/PrintConfig.cpp:1826 msgid "Deretraction Speed" msgstr "Швидкість після-переривання" -#: src/libslic3r/PrintConfig.cpp:1543 +#: src/libslic3r/PrintConfig.cpp:1827 msgid "" "The speed for loading of a filament into extruder after retraction (it only " "applies to the extruder motor). If left to zero, the retraction speed is " @@ -6269,67 +11074,55 @@ msgstr "" "лише двигуна екструдера ). Якщо залишити 0, використовується швидкість " "переривання ." -#: src/libslic3r/PrintConfig.cpp:1550 +#: src/libslic3r/PrintConfig.cpp:1834 msgid "Seam position" msgstr "Позиція шва" -#: src/libslic3r/PrintConfig.cpp:1552 +#: src/libslic3r/PrintConfig.cpp:1836 msgid "Position of perimeters starting points." msgstr "Позиція стартових точок периметра." -#: src/libslic3r/PrintConfig.cpp:1558 +#: src/libslic3r/PrintConfig.cpp:1842 msgid "Random" -msgstr "" +msgstr "Випадкова" -#: src/libslic3r/PrintConfig.cpp:1559 +#: src/libslic3r/PrintConfig.cpp:1843 msgid "Nearest" -msgstr "" +msgstr "Найближча" -#: src/libslic3r/PrintConfig.cpp:1560 +#: src/libslic3r/PrintConfig.cpp:1844 msgid "Aligned" -msgstr "" +msgstr "Вирівняно" -#: src/libslic3r/PrintConfig.cpp:1568 +#: src/libslic3r/PrintConfig.cpp:1852 msgid "Direction" msgstr "Напрямок" -#: src/libslic3r/PrintConfig.cpp:1570 +#: src/libslic3r/PrintConfig.cpp:1854 msgid "Preferred direction of the seam" msgstr "Бажаний напрямок шва" -#: src/libslic3r/PrintConfig.cpp:1571 +#: src/libslic3r/PrintConfig.cpp:1855 msgid "Seam preferred direction" msgstr "Бажаний напрямок шва" -#: src/libslic3r/PrintConfig.cpp:1578 +#: src/libslic3r/PrintConfig.cpp:1862 msgid "Jitter" msgstr "Джиттер" -#: src/libslic3r/PrintConfig.cpp:1580 +#: src/libslic3r/PrintConfig.cpp:1864 msgid "Seam preferred direction jitter" msgstr "Бажаний напрямок шва джитера" -#: src/libslic3r/PrintConfig.cpp:1581 +#: src/libslic3r/PrintConfig.cpp:1865 msgid "Preferred direction of the seam - jitter" msgstr "Бажаний напрямок шва - джитера" -#: src/libslic3r/PrintConfig.cpp:1591 -msgid "USB/serial port for printer connection." -msgstr "USB / послідовний порт для підключення принтера." - -#: src/libslic3r/PrintConfig.cpp:1598 -msgid "Serial port speed" -msgstr "Швидкість послідовного порту" - -#: src/libslic3r/PrintConfig.cpp:1599 -msgid "Speed (baud) of USB/serial port for printer connection." -msgstr "Швидкість (бод) USB / послідовного порту для підключення принтера." - -#: src/libslic3r/PrintConfig.cpp:1608 +#: src/libslic3r/PrintConfig.cpp:1872 msgid "Distance from object" msgstr "Відстань від об'єкту" -#: src/libslic3r/PrintConfig.cpp:1609 +#: src/libslic3r/PrintConfig.cpp:1873 msgid "" "Distance between skirt and object(s). Set this to zero to attach the skirt " "to the object(s) and get a brim for better adhesion." @@ -6337,11 +11130,11 @@ msgstr "" "Відстань між плінтусом та об'єктом (-ами). Установіть 0, щоб прикріпити " "плінтус до об'єкта (-ів) і отримати край для кращої адгезії." -#: src/libslic3r/PrintConfig.cpp:1616 +#: src/libslic3r/PrintConfig.cpp:1880 msgid "Skirt height" msgstr "Висота плінтусу" -#: src/libslic3r/PrintConfig.cpp:1617 +#: src/libslic3r/PrintConfig.cpp:1881 msgid "" "Height of skirt expressed in layers. Set this to a tall value to use skirt " "as a shield against drafts." @@ -6349,15 +11142,29 @@ msgstr "" "Висота плінтусу виражена в шарах. Встановіть це значення на високе, щоб " "використовувати плінтус як щит проти протягів." -#: src/libslic3r/PrintConfig.cpp:1624 +#: src/libslic3r/PrintConfig.cpp:1888 +msgid "Draft shield" +msgstr "Чорновий щит" + +#: src/libslic3r/PrintConfig.cpp:1889 +msgid "" +"If enabled, the skirt will be as tall as a highest printed object. This is " +"useful to protect an ABS or ASA print from warping and detaching from print " +"bed due to wind draft." +msgstr "" +"Якщо увімкнено, спідниця буде такою ж високою, як найвищий друкований " +"предмет. Це корисно, щоб захистити друк ABS або ASA від деформації та " +"від'єднання від друкарського столу через протяг." + +#: src/libslic3r/PrintConfig.cpp:1895 msgid "Loops (minimum)" msgstr "Петлі (мінімум)" -#: src/libslic3r/PrintConfig.cpp:1625 +#: src/libslic3r/PrintConfig.cpp:1896 msgid "Skirt Loops" msgstr "Петлі плінтусу" -#: src/libslic3r/PrintConfig.cpp:1626 +#: src/libslic3r/PrintConfig.cpp:1897 msgid "" "Number of loops for the skirt. If the Minimum Extrusion Length option is " "set, the number of loops might be greater than the one configured here. Set " @@ -6367,11 +11174,11 @@ msgstr "" "довжина екструзії\", кількість петель може бути більшою, ніж налаштована " "тут. Установіть 0, щоб повністю вимкнути плінтус." -#: src/libslic3r/PrintConfig.cpp:1634 +#: src/libslic3r/PrintConfig.cpp:1905 msgid "Slow down if layer print time is below" msgstr "Уповільнення, якщо час друку шару нижче" -#: src/libslic3r/PrintConfig.cpp:1635 +#: src/libslic3r/PrintConfig.cpp:1906 msgid "" "If layer print time is estimated below this number of seconds, print moves " "speed will be scaled down to extend duration to this value." @@ -6379,11 +11186,11 @@ msgstr "" "Якщо час друку шару оцінюється нижче цієї кількості секунд, швидкість друку " "рухів зменшуватиметься, щоб збільшити тривалість до цього значення." -#: src/libslic3r/PrintConfig.cpp:1645 +#: src/libslic3r/PrintConfig.cpp:1915 msgid "Small perimeters" msgstr "Маленькі периметри" -#: src/libslic3r/PrintConfig.cpp:1647 +#: src/libslic3r/PrintConfig.cpp:1917 msgid "" "This separate setting will affect the speed of perimeters having radius <= " "6.5mm (usually holes). If expressed as percentage (for example: 80%) it will " @@ -6394,11 +11201,11 @@ msgstr "" "вона буде розрахована за наведеним вище параметром швидкості. Встановити 0 " "для автоматичного використання." -#: src/libslic3r/PrintConfig.cpp:1657 +#: src/libslic3r/PrintConfig.cpp:1927 msgid "Solid infill threshold area" msgstr "Порогова площа суцільного наповнення" -#: src/libslic3r/PrintConfig.cpp:1659 +#: src/libslic3r/PrintConfig.cpp:1929 msgid "" "Force solid infill for regions having a smaller area than the specified " "threshold." @@ -6406,23 +11213,23 @@ msgstr "" "Встановити суцільне заповнення для регіонів, що мають площу, меншу " "зазначеного порогу." -#: src/libslic3r/PrintConfig.cpp:1660 +#: src/libslic3r/PrintConfig.cpp:1930 msgid "mm²" msgstr "мм²" -#: src/libslic3r/PrintConfig.cpp:1666 +#: src/libslic3r/PrintConfig.cpp:1936 msgid "Solid infill extruder" msgstr "Екструдер суцільних наповнень" -#: src/libslic3r/PrintConfig.cpp:1668 +#: src/libslic3r/PrintConfig.cpp:1938 msgid "The extruder to use when printing solid infill." msgstr "Екструдер для друку суцільних наповнень." -#: src/libslic3r/PrintConfig.cpp:1674 +#: src/libslic3r/PrintConfig.cpp:1944 msgid "Solid infill every" msgstr "Суцільне наповнення кожні" -#: src/libslic3r/PrintConfig.cpp:1676 +#: src/libslic3r/PrintConfig.cpp:1946 msgid "" "This feature allows to force a solid layer every given number of layers. " "Zero to disable. You can set this to any value (for example 9999); Slic3r " @@ -6434,7 +11241,7 @@ msgstr "" "Slic3r автоматично вибере максимально можливу кількість шарів для " "комбінування відповідно до діаметра сопла та висоти шару." -#: src/libslic3r/PrintConfig.cpp:1688 +#: src/libslic3r/PrintConfig.cpp:1958 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill for " "solid surfaces. If left zero, default extrusion width will be used if set, " @@ -6447,7 +11254,7 @@ msgstr "" "діаметр сопла. Якщо він виражений у відсотках (наприклад, 90%), він буде " "обчислюватися за висотою шару." -#: src/libslic3r/PrintConfig.cpp:1698 +#: src/libslic3r/PrintConfig.cpp:1969 msgid "" "Speed for printing solid regions (top/bottom/internal horizontal shells). " "This can be expressed as a percentage (for example: 80%) over the default " @@ -6458,35 +11265,39 @@ msgstr "" "швидкості заповнення за замовчуванням. Встановити 0 для автоматичного " "використання." -#: src/libslic3r/PrintConfig.cpp:1710 +#: src/libslic3r/PrintConfig.cpp:1981 msgid "Number of solid layers to generate on top and bottom surfaces." msgstr "" "Кількість суцільних шарів для генерування на верхній і нижній поверхні." -#: src/libslic3r/PrintConfig.cpp:1716 +#: src/libslic3r/PrintConfig.cpp:1987 src/libslic3r/PrintConfig.cpp:1988 +msgid "Minimum thickness of a top / bottom shell" +msgstr "Мінімальна товщина верхньої / нижньої оболонки" + +#: src/libslic3r/PrintConfig.cpp:1994 msgid "Spiral vase" msgstr "Спіральна ваза" -#: src/libslic3r/PrintConfig.cpp:1717 +#: src/libslic3r/PrintConfig.cpp:1995 msgid "" "This feature will raise Z gradually while printing a single-walled object in " "order to remove any visible seam. This option requires a single perimeter, " "no infill, no top solid layers and no support material. You can still set " "any number of bottom solid layers as well as skirt/brim loops. It won't work " -"when printing more than an object." +"when printing more than one single object." msgstr "" "Ця функція буде поступово підвищувати Z протягом друку одного-стінного " "об'єкта для уникнення будь-якого видимого шву. Цей параметр вимагає " "одношарового периметру, відсутнє наповнення, відсутність верхніх суцільних " "шарів і відсутність матеріалу підтримки. Ви все ще можете встановити будь-" -"яку кількість нижніх суцільних шарів, а також петель плінтусу/краю. Це не " -"спрацює при друку більше, ніж одного об'єкта." +"яку кількість нижніх твердих шарів, а також спідниці краю. Це не спрацює при " +"друку більше, ніж одного об'єкта." -#: src/libslic3r/PrintConfig.cpp:1725 +#: src/libslic3r/PrintConfig.cpp:2003 msgid "Temperature variation" msgstr "Варіація температури" -#: src/libslic3r/PrintConfig.cpp:1726 +#: src/libslic3r/PrintConfig.cpp:2004 msgid "" "Temperature difference to be applied when an extruder is not active. Enables " "a full-height \"sacrificial\" skirt on which the nozzles are periodically " @@ -6495,88 +11306,127 @@ msgstr "" "Відмітка температури, яка застосовується, коли екструдер не активний. Вмикає " "\"жертовний\" плінтус на повній висоті, на які періодично очищуються сопла." -#: src/libslic3r/PrintConfig.cpp:1736 +#: src/libslic3r/PrintConfig.cpp:2014 msgid "" "This start procedure is inserted at the beginning, after bed has reached the " "target temperature and extruder just started heating, and before extruder " -"has finished heating. If Slic3r detects M104 or M190 in your custom codes, " -"such commands will not be prepended automatically so you're free to " +"has finished heating. If PrusaSlicer detects M104 or M190 in your custom " +"codes, such commands will not be prepended automatically so you're free to " "customize the order of heating commands and other custom actions. Note that " -"you can use placeholder variables for all Slic3r settings, so you can put a " -"\"M109 S[first_layer_temperature]\" command wherever you want." +"you can use placeholder variables for all PrusaSlicer settings, so you can " +"put a \"M109 S[first_layer_temperature]\" command wherever you want." msgstr "" -"Ця початкова процедура вставляється на початку, після того, як полотно " -"досягне цільової температури, а екструдер тільки починає нагріватися, і " -"перед тим, як екструдер закінчить нагрівання. Якщо Slic3r виявляє M104 або " -"M190 у ваших користувацьких кодах, такі команди не будуть додаватися " -"автоматично, щоб ви могли вільно налаштовувати порядок команд нагріву та " -"інших спеціальних дій. Зверніть увагу, що ви можете використовувати змінні-" -"заповнювачі для всіх параметрів Slic3r, щоб ви могли поставити команду " -"\"M109 S [first_layer_temperature]\" де завгодно." +"Ця процедура початку вставляється на початку, після того, як стіл досягне " +"цільової температури, а екструдер тільки починає нагріватися, і перед тим, " +"як екструдер закінчить нагрівання. Якщо Slic3r виявляє M104 або M190 у ваших " +"користувацьких кодах, такі команди не будуть додаватися автоматично, щоб ви " +"могли вільно налаштовувати порядок команд нагріву та інших спеціальних дій. " +"Зверніть увагу, що ви можете використовувати шаблонні змінні для всіх " +"параметрів Slic3r, щоб ви могли поставити команду \"M109 S " +"[first_layer_temperature]\" де завгодно." -#: src/libslic3r/PrintConfig.cpp:1751 +#: src/libslic3r/PrintConfig.cpp:2029 msgid "" "This start procedure is inserted at the beginning, after any printer start " -"gcode. This is used to override settings for a specific filament. If Slic3r " -"detects M104, M109, M140 or M190 in your custom codes, such commands will " -"not be prepended automatically so you're free to customize the order of " -"heating commands and other custom actions. Note that you can use placeholder " -"variables for all Slic3r settings, so you can put a \"M109 " +"gcode (and after any toolchange to this filament in case of multi-material " +"printers). This is used to override settings for a specific filament. If " +"PrusaSlicer detects M104, M109, M140 or M190 in your custom codes, such " +"commands will not be prepended automatically so you're free to customize the " +"order of heating commands and other custom actions. Note that you can use " +"placeholder variables for all PrusaSlicer settings, so you can put a \"M109 " "S[first_layer_temperature]\" command wherever you want. If you have multiple " "extruders, the gcode is processed in extruder order." msgstr "" -"Ця початкова процедура вставляється на початку, після того, як будь-який " -"принтер запускає G-code. Це використовується для перевизначення параметрів " -"для певної нитки. Якщо Slic3r виявляє M104, M109, M140 або M190 у ваших " -"користувацьких кодах, такі команди не будуть автоматично додаватися, тому ви " -"можете налаштувати порядок команд нагріву та інших спеціальних дій. Зверніть " -"увагу, що ви можете використовувати змінні-заповнювачі для всіх параметрів " -"Slic3r, щоб ви могли поставити команду \"M109 S [first_layer_temperature]\" " -"де завгодно. Якщо у вас є кілька екструдерів, G-code обробляється в порядку " -"екструдерів." +"Ця процедура початку вставляється на початку, після будь-якого стартового G-" +"коду принтера (і після будь-якої зміни інструменту на цей філамент, у разі " +"багато-матеріальних принтерів). Вона використовується для заміни налаштувань " +"для певного філаменту. Якщо PrusaSlicer виявить M104, M109, M140 або M190 у " +"ваших користувацьких кодах, такі команди не додаватимуться автоматично, тому " +"ви можете налаштувати порядок команд нагрівання та інші спеціальні дії. " +"Зверніть увагу, що ви можете використовувати шаблонні змінні для всіх " +"налаштувань PrusaSlicer, тому ви можете поставити команду \"M109 S " +"[first_layer_temperature]\" де завгодно. Якщо у вас кілька екструдерів, G-" +"код обробляється в порядку екструдера." -#: src/libslic3r/PrintConfig.cpp:1766 +#: src/libslic3r/PrintConfig.cpp:2045 +msgid "Color change G-code" +msgstr "G-код зміни кольору" + +#: src/libslic3r/PrintConfig.cpp:2046 +msgid "This G-code will be used as a code for the color change" +msgstr "Цей G-код буде використовуватися як код для зміни кольору" + +#: src/libslic3r/PrintConfig.cpp:2055 +msgid "This G-code will be used as a code for the pause print" +msgstr "Цей G-код буде використовуватися як код для паузи друку" + +#: src/libslic3r/PrintConfig.cpp:2064 +msgid "This G-code will be used as a custom code" +msgstr "Цей G-код буде використовуватися як власний код" + +#: src/libslic3r/PrintConfig.cpp:2072 msgid "Single Extruder Multi Material" -msgstr "Одиночний екструдер кількох матеріалів" +msgstr "Мульти-матеріальний (ММ) друк з одним екструдером" -#: src/libslic3r/PrintConfig.cpp:1767 +#: src/libslic3r/PrintConfig.cpp:2073 msgid "The printer multiplexes filaments into a single hot end." -msgstr "Принтер мультиплексує нитки в єдиний гарячий кінець." +msgstr "Принтер змішує філаменту в єдиний гарячий кінець." -#: src/libslic3r/PrintConfig.cpp:1772 +#: src/libslic3r/PrintConfig.cpp:2078 msgid "Prime all printing extruders" -msgstr "" +msgstr "Підготовка всіх друкуючих екструдерів" -#: src/libslic3r/PrintConfig.cpp:1773 +#: src/libslic3r/PrintConfig.cpp:2079 msgid "" "If enabled, all printing extruders will be primed at the front edge of the " "print bed at the start of the print." msgstr "" +"Якщо увімкнено, усі друкуючі екструдери будуть отестовані на передньому краї " +"друкарського столу перед початком друку." -#: src/libslic3r/PrintConfig.cpp:1778 +#: src/libslic3r/PrintConfig.cpp:2084 +msgid "No sparse layers (EXPERIMENTAL)" +msgstr "Немає розріджених шарів (ЕКСПЕРИМЕНТАЛЬНИЙ)" + +#: src/libslic3r/PrintConfig.cpp:2085 +msgid "" +"If enabled, the wipe tower will not be printed on layers with no " +"toolchanges. On layers with a toolchange, extruder will travel downward to " +"print the wipe tower. User is responsible for ensuring there is no collision " +"with the print." +msgstr "" +"Якщо увімкнено, вежа витирання не друкується на шарах без змін інструментів. " +"На шарах із зміною інструменту екструдер рухатиметься вниз, щоб надрукувати " +"вежу витирання. Користувач несе відповідальність за те, щоб не було " +"зіткнення з друком." + +#: src/libslic3r/PrintConfig.cpp:2092 msgid "Generate support material" msgstr "Створити підтримуючий матеріал" -#: src/libslic3r/PrintConfig.cpp:1780 +#: src/libslic3r/PrintConfig.cpp:2094 msgid "Enable support material generation." msgstr "Увімкнути генерацію матеріалів підтримки." -#: src/libslic3r/PrintConfig.cpp:1784 +#: src/libslic3r/PrintConfig.cpp:2098 msgid "Auto generated supports" -msgstr "" +msgstr "Автоматично згенеровані підтримки" -#: src/libslic3r/PrintConfig.cpp:1786 +#: src/libslic3r/PrintConfig.cpp:2100 msgid "" "If checked, supports will be generated automatically based on the overhang " "threshold value. If unchecked, supports will be generated inside the " "\"Support Enforcer\" volumes only." msgstr "" +"Якщо увімкнено, підтримка буде генеруватися автоматично на основі порогового " +"значення звису. Якщо вимкнено, підтримка буде генеруватися лише для " +"\"Примусових підтримок\"." -#: src/libslic3r/PrintConfig.cpp:1792 +#: src/libslic3r/PrintConfig.cpp:2106 msgid "XY separation between an object and its support" msgstr "Розподіл XY між об'єктом та його підтримкою" -#: src/libslic3r/PrintConfig.cpp:1794 +#: src/libslic3r/PrintConfig.cpp:2108 msgid "" "XY separation between an object and its support. If expressed as percentage " "(for example 50%), it will be calculated over external perimeter width." @@ -6584,11 +11434,11 @@ msgstr "" "Розподіл XY між об'єктом та його підтримкою. Якщо вона виражена у відсотках " "(наприклад, 50%), вона буде розрахована за зовнішньою шириною периметру." -#: src/libslic3r/PrintConfig.cpp:1804 +#: src/libslic3r/PrintConfig.cpp:2118 msgid "Pattern angle" msgstr "Кут шаблону" -#: src/libslic3r/PrintConfig.cpp:1806 +#: src/libslic3r/PrintConfig.cpp:2120 msgid "" "Use this setting to rotate the support material pattern on the horizontal " "plane." @@ -6596,7 +11446,7 @@ msgstr "" "Використовуйте цей параметр, щоб повернути шаблон підтримуючого матеріалу на " "горизонтальній площині." -#: src/libslic3r/PrintConfig.cpp:1816 src/libslic3r/PrintConfig.cpp:2421 +#: src/libslic3r/PrintConfig.cpp:2130 src/libslic3r/PrintConfig.cpp:2925 msgid "" "Only create support if it lies on a build plate. Don't create support on a " "print." @@ -6604,11 +11454,11 @@ msgstr "" "Створити підтримку лише, для того, що лежить на збірній пластині. Не " "створювати підтримку на друк." -#: src/libslic3r/PrintConfig.cpp:1822 +#: src/libslic3r/PrintConfig.cpp:2136 msgid "Contact Z distance" msgstr "Контактна відстань по осі Z" -#: src/libslic3r/PrintConfig.cpp:1824 +#: src/libslic3r/PrintConfig.cpp:2138 msgid "" "The vertical distance between object and support material interface. Setting " "this to 0 will also prevent Slic3r from using bridge flow and speed for the " @@ -6618,19 +11468,19 @@ msgstr "" "Встановлення значення 0 також захистить Slic3r від використання потоку " "мостів та швидкості для першого шару об'єктну." -#: src/libslic3r/PrintConfig.cpp:1831 -msgid "soluble" -msgstr "розчинний" +#: src/libslic3r/PrintConfig.cpp:2145 +msgid "0 (soluble)" +msgstr "0 (розчинний)" -#: src/libslic3r/PrintConfig.cpp:1832 -msgid "detachable" -msgstr "відривний" +#: src/libslic3r/PrintConfig.cpp:2146 +msgid "0.2 (detachable)" +msgstr "0,2 (відривний)" -#: src/libslic3r/PrintConfig.cpp:1837 +#: src/libslic3r/PrintConfig.cpp:2151 msgid "Enforce support for the first" msgstr "Забезпечити підтримку першого(их)" -#: src/libslic3r/PrintConfig.cpp:1839 +#: src/libslic3r/PrintConfig.cpp:2153 msgid "" "Generate support material for the specified number of layers counting from " "bottom, regardless of whether normal support material is enabled or not and " @@ -6643,15 +11493,15 @@ msgstr "" "більшої адгезії об'єктів, що мають дуже тонкий або поганий слід на збірній " "пластині." -#: src/libslic3r/PrintConfig.cpp:1844 +#: src/libslic3r/PrintConfig.cpp:2158 msgid "Enforce support for the first n layers" msgstr "Забезпечити підтримку перших n шарів" -#: src/libslic3r/PrintConfig.cpp:1850 +#: src/libslic3r/PrintConfig.cpp:2164 msgid "Support material/raft/skirt extruder" msgstr "Підтримуючий матеріал / пліт / плінтус екструдеру" -#: src/libslic3r/PrintConfig.cpp:1852 +#: src/libslic3r/PrintConfig.cpp:2166 msgid "" "The extruder to use when printing support material, raft and skirt (1+, 0 to " "use the current extruder to minimize tool changes)." @@ -6659,7 +11509,7 @@ msgstr "" "Екструдер для друку підтримуючого матеріалу, плоту та плінтусу (1+, 0 для " "використання поточного екструдера, щоб мінімізувати зміни інструменту)." -#: src/libslic3r/PrintConfig.cpp:1861 +#: src/libslic3r/PrintConfig.cpp:2175 msgid "" "Set this to a non-zero value to set a manual extrusion width for support " "material. If left zero, default extrusion width will be used if set, " @@ -6672,21 +11522,21 @@ msgstr "" "Якщо він виражений у відсотках (наприклад, 90%), він буде обчислюватися за " "висотою шару." -#: src/libslic3r/PrintConfig.cpp:1869 +#: src/libslic3r/PrintConfig.cpp:2184 msgid "Interface loops" msgstr "Інтерфейсні петлі" -#: src/libslic3r/PrintConfig.cpp:1871 +#: src/libslic3r/PrintConfig.cpp:2186 msgid "" "Cover the top contact layer of the supports with loops. Disabled by default." msgstr "" "Закрити петлями верхній контактний шар підтримки. За замовчанням вимкнено." -#: src/libslic3r/PrintConfig.cpp:1876 +#: src/libslic3r/PrintConfig.cpp:2191 msgid "Support material/raft interface extruder" msgstr "Екструдер інтерфейсу підтримуючого матеріалу / плоту" -#: src/libslic3r/PrintConfig.cpp:1878 +#: src/libslic3r/PrintConfig.cpp:2193 msgid "" "The extruder to use when printing support material interface (1+, 0 to use " "the current extruder to minimize tool changes). This affects raft too." @@ -6695,11 +11545,11 @@ msgstr "" "(1+, 0 для використання поточного екструдера, щоб звести до мінімуму зміни " "інструменту). Це також впливає на плот." -#: src/libslic3r/PrintConfig.cpp:1885 +#: src/libslic3r/PrintConfig.cpp:2200 msgid "Interface layers" msgstr "Інтерфейсні шари" -#: src/libslic3r/PrintConfig.cpp:1887 +#: src/libslic3r/PrintConfig.cpp:2202 msgid "" "Number of interface layers to insert between the object(s) and support " "material." @@ -6707,17 +11557,17 @@ msgstr "" "Кількість шарів інтерфейсу для вставки між об'єктом(ами) та підтримуючим " "матеріалом." -#: src/libslic3r/PrintConfig.cpp:1894 +#: src/libslic3r/PrintConfig.cpp:2209 msgid "Interface pattern spacing" msgstr "Відстань між шаблонами інтерфейсу" -#: src/libslic3r/PrintConfig.cpp:1896 +#: src/libslic3r/PrintConfig.cpp:2211 msgid "Spacing between interface lines. Set zero to get a solid interface." msgstr "" "Відстань між інтерфейсними лініями. Встановити 0, щоб отримати надійний " "інтерфейс." -#: src/libslic3r/PrintConfig.cpp:1905 +#: src/libslic3r/PrintConfig.cpp:2220 msgid "" "Speed for printing support material interface layers. If expressed as " "percentage (for example 50%) it will be calculated over support material " @@ -6727,35 +11577,35 @@ msgstr "" "виражена у відсотках (наприклад, 50%), вона буде розрахована за швидкістю " "матеріалу підтримки." -#: src/libslic3r/PrintConfig.cpp:1914 +#: src/libslic3r/PrintConfig.cpp:2229 msgid "Pattern" msgstr "Шаблон" -#: src/libslic3r/PrintConfig.cpp:1916 +#: src/libslic3r/PrintConfig.cpp:2231 msgid "Pattern used to generate support material." msgstr "Шаблон, що використовується для створення матеріалу підтримки." -#: src/libslic3r/PrintConfig.cpp:1922 +#: src/libslic3r/PrintConfig.cpp:2237 msgid "Rectilinear grid" -msgstr "" +msgstr "Прямолінійна сітка" -#: src/libslic3r/PrintConfig.cpp:1928 +#: src/libslic3r/PrintConfig.cpp:2243 msgid "Pattern spacing" msgstr "Відстань між шаблонами" -#: src/libslic3r/PrintConfig.cpp:1930 +#: src/libslic3r/PrintConfig.cpp:2245 msgid "Spacing between support material lines." msgstr "Відстань між лініями підтримуючого матеріалу." -#: src/libslic3r/PrintConfig.cpp:1939 +#: src/libslic3r/PrintConfig.cpp:2254 msgid "Speed for printing support material." msgstr "Швидкість друку підтримуючого матеріалу." -#: src/libslic3r/PrintConfig.cpp:1946 +#: src/libslic3r/PrintConfig.cpp:2261 msgid "Synchronize with object layers" msgstr "Синхронізувати з шарами об'єкту" -#: src/libslic3r/PrintConfig.cpp:1948 +#: src/libslic3r/PrintConfig.cpp:2263 msgid "" "Synchronize support layers with the object print layers. This is useful with " "multi-material printers, where the extruder switch is expensive." @@ -6764,11 +11614,11 @@ msgstr "" "використовувати з багато-матеріальними принтерами, де перемикання " "екструдерів -затратна процедура." -#: src/libslic3r/PrintConfig.cpp:1954 +#: src/libslic3r/PrintConfig.cpp:2269 msgid "Overhang threshold" msgstr "Порог нависання" -#: src/libslic3r/PrintConfig.cpp:1956 +#: src/libslic3r/PrintConfig.cpp:2271 msgid "" "Support material will not be generated for overhangs whose slope angle (90° " "= vertical) is above the given threshold. In other words, this value " @@ -6782,11 +11632,11 @@ msgstr "" "площини), який ви можете надрукувати без підтримуючого матеріалу. Встановити " "0 для автоматичного визначення (рекомендовано)." -#: src/libslic3r/PrintConfig.cpp:1968 +#: src/libslic3r/PrintConfig.cpp:2283 msgid "With sheath around the support" msgstr "З оболонкою навколо підтримки" -#: src/libslic3r/PrintConfig.cpp:1970 +#: src/libslic3r/PrintConfig.cpp:2285 msgid "" "Add a sheath (a single perimeter line) around the base support. This makes " "the support more reliable, but also more difficult to remove." @@ -6794,23 +11644,23 @@ msgstr "" "Додати оболонку (одну лінію периметра) навколо базової підтримки. Це робить " "підтримку більш надійною, але її важче видалити." -#: src/libslic3r/PrintConfig.cpp:1977 +#: src/libslic3r/PrintConfig.cpp:2292 msgid "" -"Extruder temperature for layers after the first one. Set this to zero to " -"disable temperature control commands in the output." +"Nozzle temperature for layers after the first one. Set this to zero to " +"disable temperature control commands in the output G-code." msgstr "" -"Температура екструдеру для шарів після першого. Установіть 0, щоб вимкнути " -"команди керування температурою на виході." +"Температура сопла для шарів після першого. Встановіть значення нуля, щоб " +"вимкнути команди регулювання температури у вихідному G-коді." -#: src/libslic3r/PrintConfig.cpp:1979 -msgid "Temperature" -msgstr "Температура" +#: src/libslic3r/PrintConfig.cpp:2295 +msgid "Nozzle temperature" +msgstr "Температура сопла" -#: src/libslic3r/PrintConfig.cpp:1985 +#: src/libslic3r/PrintConfig.cpp:2301 msgid "Detect thin walls" -msgstr "Виявлення тонких стін" +msgstr "Виявлення тонких стінок" -#: src/libslic3r/PrintConfig.cpp:1987 +#: src/libslic3r/PrintConfig.cpp:2303 msgid "" "Detect single-width walls (parts where two extrusions don't fit and we need " "to collapse them into a single trace)." @@ -6818,11 +11668,11 @@ msgstr "" "Визначення одношарової стінки (частини, де два екструзії не підходять, і нам " "потрібно згорнути їх у єдиний слід)." -#: src/libslic3r/PrintConfig.cpp:1993 +#: src/libslic3r/PrintConfig.cpp:2309 msgid "Threads" msgstr "Нитки" -#: src/libslic3r/PrintConfig.cpp:1994 +#: src/libslic3r/PrintConfig.cpp:2310 msgid "" "Threads are used to parallelize long-running tasks. Optimal threads number " "is slightly above the number of available cores/processors." @@ -6830,17 +11680,23 @@ msgstr "" "Нитки використовуються для паралелізації довготривалих завдань. Оптимальна " "кількість ниток трохи перевищує кількість доступних ядер / процесорів." -#: src/libslic3r/PrintConfig.cpp:2006 +#: src/libslic3r/PrintConfig.cpp:2322 msgid "" -"This custom code is inserted right before every extruder change. Note that " -"you can use placeholder variables for all Slic3r settings as well as " -"[previous_extruder] and [next_extruder]." +"This custom code is inserted before every toolchange. Placeholder variables " +"for all PrusaSlicer settings as well as {previous_extruder} and " +"{next_extruder} can be used. When a tool-changing command which changes to " +"the correct extruder is included (such as T{next_extruder}), PrusaSlicer " +"will emit no other such command. It is therefore possible to script custom " +"behaviour both before and after the toolchange." msgstr "" -"Цей спеціальний код вставляється безпосередньо перед кожною зміненою " -"екструдера. Зверніть увагу, що ви можете використовувати змінні-заповнювачі " -"для всіх параметрів Slic3r, а також [previous_extruder] і [next_extruder]." +"Цей користувацький код вставляється перед кожною заміною інструменту. Можна " +"використовувати шаблонні змінні для всіх налаштувань PrusaSlicer, таких як " +"{previous_extruder} та {next_extruder}. Коли включається команда зміни " +"інструмента, яка змінюється на правильний екструдер (наприклад, " +"T{next_extruder}), PrusaSlicer не видасть жодної такої команди. Отже, можна " +"створювати сценарії до поведінки як до, так і після заміни інструменту." -#: src/libslic3r/PrintConfig.cpp:2018 +#: src/libslic3r/PrintConfig.cpp:2335 msgid "" "Set this to a non-zero value to set a manual extrusion width for infill for " "top surfaces. You may want to use thinner extrudates to fill all narrow " @@ -6856,7 +11712,7 @@ msgstr "" "виражена у відсотках (наприклад, 90%), вона буде обчислюватися за висотою " "шару." -#: src/libslic3r/PrintConfig.cpp:2029 +#: src/libslic3r/PrintConfig.cpp:2347 msgid "" "Speed for printing top solid layers (it only applies to the uppermost " "external layers and not to their internal solid layers). You may want to " @@ -6870,23 +11726,37 @@ msgstr "" "відсотком (наприклад, 80%) звищення швидкості щільного наповнення . " "Встановити 0 для автоматичного обчислення." -#: src/libslic3r/PrintConfig.cpp:2043 +#: src/libslic3r/PrintConfig.cpp:2362 msgid "Number of solid layers to generate on top surfaces." msgstr "Кількість суцільних шарів, генерованих на верхніх поверхнях." -#: src/libslic3r/PrintConfig.cpp:2044 +#: src/libslic3r/PrintConfig.cpp:2363 msgid "Top solid layers" msgstr "Верхні суцільні шари" -#: src/libslic3r/PrintConfig.cpp:2050 +#: src/libslic3r/PrintConfig.cpp:2371 +msgid "" +"The number of top solid layers is increased above top_solid_layers if " +"necessary to satisfy minimum thickness of top shell. This is useful to " +"prevent pillowing effect when printing with variable layer height." +msgstr "" +"Кількість верхніх твердих шарів збільшується над top_solid_layers, якщо це " +"необхідно для задоволення мінімальної товщини верхньої оболонки. Це корисно " +"для запобігання ефекту подушки під час друку зі змінною висотою шару." + +#: src/libslic3r/PrintConfig.cpp:2374 +msgid "Minimum top shell thickness" +msgstr "Мінімальна товщина верхньої оболонки" + +#: src/libslic3r/PrintConfig.cpp:2381 msgid "Speed for travel moves (jumps between distant extrusion points)." msgstr "Швидкість рухів пересування (стрибки між далекими точками екструзії)." -#: src/libslic3r/PrintConfig.cpp:2058 +#: src/libslic3r/PrintConfig.cpp:2389 msgid "Use firmware retraction" msgstr "Використовувати відмову прошивки" -#: src/libslic3r/PrintConfig.cpp:2059 +#: src/libslic3r/PrintConfig.cpp:2390 msgid "" "This experimental setting uses G10 and G11 commands to have the firmware " "handle the retraction. This is only supported in recent Marlin." @@ -6894,11 +11764,11 @@ msgstr "" "Цей експериментальний параметр використовує команди G10 і G11 для обробки " "відмови прошивки. Останнім часом це підтримується лише Marlin-ом." -#: src/libslic3r/PrintConfig.cpp:2065 +#: src/libslic3r/PrintConfig.cpp:2396 msgid "Use relative E distances" msgstr "Використовувати відносні E відстані" -#: src/libslic3r/PrintConfig.cpp:2066 +#: src/libslic3r/PrintConfig.cpp:2397 msgid "" "If your firmware requires relative E values, check this, otherwise leave it " "unchecked. Most firmwares use absolute values." @@ -6906,11 +11776,11 @@ msgstr "" "Якщо ваша прошивка потребує відносне значення E, зазначте це, інакше залиште " "його незазначеним. Більшість прошивок використовують абсолютні значення." -#: src/libslic3r/PrintConfig.cpp:2072 +#: src/libslic3r/PrintConfig.cpp:2403 msgid "Use volumetric E" msgstr "Використовувати об'ємний Е" -#: src/libslic3r/PrintConfig.cpp:2073 +#: src/libslic3r/PrintConfig.cpp:2404 msgid "" "This experimental setting uses outputs the E values in cubic millimeters " "instead of linear millimeters. If your firmware doesn't already know " @@ -6923,14 +11793,14 @@ msgstr "" "міліметрах замість лінійних міліметрів. Якщо ваша прошивку ще не знає " "діаметр ниток, ви можете встановити такі команди, як \"M200 D " "[filament_diameter_0] T0\" у вашому старті G-коду, щоб включити об'ємний " -"режим і використовувати діаметр нитки, пов'язаний з вибраною ниткою в " -"Slic3r. Останнім часом це підтримується лише Marlin-ом." +"режим і використовувати діаметр філаменту, пов'язаний з вибраним філаментем " +"у Slic3r. Останнім часом це підтримується лише Marlin-ом." -#: src/libslic3r/PrintConfig.cpp:2083 +#: src/libslic3r/PrintConfig.cpp:2414 msgid "Enable variable layer height feature" msgstr "Увімкнути функцію шарів змінної висоти" -#: src/libslic3r/PrintConfig.cpp:2084 +#: src/libslic3r/PrintConfig.cpp:2415 msgid "" "Some printers or printer setups may have difficulties printing with a " "variable layer height. Enabled by default." @@ -6938,11 +11808,11 @@ msgstr "" "Деякі принтери або налаштування принтера можуть мати труднощі з друкуванням " "шарів змінної висоти. Увімкнено за умовчанням." -#: src/libslic3r/PrintConfig.cpp:2090 +#: src/libslic3r/PrintConfig.cpp:2421 msgid "Wipe while retracting" -msgstr "Вичіщувати при відмові" +msgstr "Витирання протягом ретракту" -#: src/libslic3r/PrintConfig.cpp:2091 +#: src/libslic3r/PrintConfig.cpp:2422 msgid "" "This flag will move the nozzle while retracting to minimize the possible " "blob on leaky extruders." @@ -6950,7 +11820,7 @@ msgstr "" "Цей прапорець перемістить сопло під час відмови, щоб мінімізувати можливість " "утворення краплі на витікаючих екструдерах." -#: src/libslic3r/PrintConfig.cpp:2098 +#: src/libslic3r/PrintConfig.cpp:2429 msgid "" "Multi material printers may need to prime or purge extruders on tool " "changes. Extrude the excess material into the wipe tower." @@ -6959,94 +11829,101 @@ msgstr "" "екструдерів при зміні інструмента. Екструдуйте надлишок матеріалу до " "вичищуючої вежі." -#: src/libslic3r/PrintConfig.cpp:2104 +#: src/libslic3r/PrintConfig.cpp:2435 msgid "Purging volumes - load/unload volumes" -msgstr "" +msgstr "Обсяги витирання - обсяги заведення/виведення" -#: src/libslic3r/PrintConfig.cpp:2105 +#: src/libslic3r/PrintConfig.cpp:2436 msgid "" "This vector saves required volumes to change from/to each tool used on the " "wipe tower. These values are used to simplify creation of the full purging " -"volumes below. " +"volumes below." msgstr "" +"Цей вектор економить необхідні обсяги для зміни від / до кожного " +"інструменту, що використовується на вежі витирання. Ці значення " +"використовуються для спрощення створення повних обсягів продувки нижче." -#: src/libslic3r/PrintConfig.cpp:2111 +#: src/libslic3r/PrintConfig.cpp:2442 msgid "Purging volumes - matrix" -msgstr "" +msgstr "Таблиця обсягів очищення" -#: src/libslic3r/PrintConfig.cpp:2112 +#: src/libslic3r/PrintConfig.cpp:2443 msgid "" "This matrix describes volumes (in cubic milimetres) required to purge the " -"new filament on the wipe tower for any given pair of tools. " +"new filament on the wipe tower for any given pair of tools." msgstr "" +"Ця матриця описує обсяги (у кубічних міліметрах), необхідні для витирання " +"нового філаменту на вежі витирання для будь-якої пари інструментів." -#: src/libslic3r/PrintConfig.cpp:2121 +#: src/libslic3r/PrintConfig.cpp:2452 msgid "Position X" msgstr "Позиція X" -#: src/libslic3r/PrintConfig.cpp:2122 +#: src/libslic3r/PrintConfig.cpp:2453 msgid "X coordinate of the left front corner of a wipe tower" msgstr "X координата лівого переднього кута вичищуючої вежі" -#: src/libslic3r/PrintConfig.cpp:2128 +#: src/libslic3r/PrintConfig.cpp:2459 msgid "Position Y" msgstr "Позиція Y" -#: src/libslic3r/PrintConfig.cpp:2129 +#: src/libslic3r/PrintConfig.cpp:2460 msgid "Y coordinate of the left front corner of a wipe tower" msgstr "Y координата лівого переднього кута вичищуючої вежі" -#: src/libslic3r/PrintConfig.cpp:2136 +#: src/libslic3r/PrintConfig.cpp:2467 msgid "Width of a wipe tower" msgstr "Ширина вичищуючої вежі" -#: src/libslic3r/PrintConfig.cpp:2142 +#: src/libslic3r/PrintConfig.cpp:2473 msgid "Wipe tower rotation angle" -msgstr "" +msgstr "Кут повороту вежі витирання" -#: src/libslic3r/PrintConfig.cpp:2143 -msgid "Wipe tower rotation angle with respect to x-axis " -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2474 +msgid "Wipe tower rotation angle with respect to x-axis." +msgstr "Кут повороту вежі витирання за віссю Х." -#: src/libslic3r/PrintConfig.cpp:2144 src/libslic3r/PrintConfig.cpp:2565 -msgid "degrees" -msgstr "" - -#: src/libslic3r/PrintConfig.cpp:2150 +#: src/libslic3r/PrintConfig.cpp:2481 msgid "Wipe into this object's infill" -msgstr "" +msgstr "Витирати до наповнення цього об'єкту" -#: src/libslic3r/PrintConfig.cpp:2151 +#: src/libslic3r/PrintConfig.cpp:2482 msgid "" "Purging after toolchange will done inside this object's infills. This lowers " "the amount of waste but may result in longer print time due to additional " "travel moves." msgstr "" +"Очищення після заміни інструменту виконується всередині заповнювачів цього " +"об’єкта. Це зменшує кількість відходів, але може призвести до збільшення " +"часу друку через додаткові переміщення." -#: src/libslic3r/PrintConfig.cpp:2158 +#: src/libslic3r/PrintConfig.cpp:2489 msgid "Wipe into this object" -msgstr "" +msgstr "Витирати до цього об'єкту" -#: src/libslic3r/PrintConfig.cpp:2159 +#: src/libslic3r/PrintConfig.cpp:2490 msgid "" "Object will be used to purge the nozzle after a toolchange to save material " "that would otherwise end up in the wipe tower and decrease print time. " "Colours of the objects will be mixed as a result." msgstr "" +"Об'єкт буде використаний для продувки сопла після заміни інструменту, щоб " +"заощадити матеріал, який інакше потрапив би до вежі витирання, і зменшити " +"час друку. В результаті кольори предметів будуть змішані." -#: src/libslic3r/PrintConfig.cpp:2165 +#: src/libslic3r/PrintConfig.cpp:2496 msgid "Maximal bridging distance" -msgstr "" +msgstr "Максимальна мостова відстань" -#: src/libslic3r/PrintConfig.cpp:2166 -msgid "Maximal distance between supports on sparse infill sections. " -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2497 +msgid "Maximal distance between supports on sparse infill sections." +msgstr "Максимальна відстань між підтримками на рідкісних ділянках заповнення." -#: src/libslic3r/PrintConfig.cpp:2172 +#: src/libslic3r/PrintConfig.cpp:2503 msgid "XY Size Compensation" msgstr "Зрівноваження розміру за XY" -#: src/libslic3r/PrintConfig.cpp:2174 +#: src/libslic3r/PrintConfig.cpp:2505 msgid "" "The object will be grown/shrunk in the XY plane by the configured value " "(negative = inwards, positive = outwards). This might be useful for fine-" @@ -7056,11 +11933,11 @@ msgstr "" "(негативний - внутрішній, позитивний - ззовнішній). Це може бути корисним " "для точного налаштування розмірів отворів." -#: src/libslic3r/PrintConfig.cpp:2182 +#: src/libslic3r/PrintConfig.cpp:2513 msgid "Z offset" msgstr "Зміщення Z" -#: src/libslic3r/PrintConfig.cpp:2183 +#: src/libslic3r/PrintConfig.cpp:2514 msgid "" "This value will be added (or subtracted) from all the Z coordinates in the " "output G-code. It is used to compensate for bad Z endstop position: for " @@ -7072,615 +11949,1382 @@ msgstr "" "наприклад, якщо ваш кінцевий нуль фактично залишає сопло на 0,3 мм від " "полотна друку, встановіть його на значення -0,3 (або виправте ваш endstop)." -#: src/libslic3r/PrintConfig.cpp:2200 +#: src/libslic3r/PrintConfig.cpp:2581 msgid "Display width" -msgstr "" +msgstr "Ширина дисплея" -#: src/libslic3r/PrintConfig.cpp:2201 +#: src/libslic3r/PrintConfig.cpp:2582 msgid "Width of the display" -msgstr "" +msgstr "Ширина дисплея" -#: src/libslic3r/PrintConfig.cpp:2206 +#: src/libslic3r/PrintConfig.cpp:2587 msgid "Display height" -msgstr "" +msgstr "Висота дисплея" -#: src/libslic3r/PrintConfig.cpp:2207 +#: src/libslic3r/PrintConfig.cpp:2588 msgid "Height of the display" -msgstr "" +msgstr "Висота дисплею" -#: src/libslic3r/PrintConfig.cpp:2212 +#: src/libslic3r/PrintConfig.cpp:2593 msgid "Number of pixels in" -msgstr "" +msgstr "Кількість пікселів за віссю" -#: src/libslic3r/PrintConfig.cpp:2214 +#: src/libslic3r/PrintConfig.cpp:2595 msgid "Number of pixels in X" -msgstr "" +msgstr "Кількість пікселів за віссю X" -#: src/libslic3r/PrintConfig.cpp:2220 +#: src/libslic3r/PrintConfig.cpp:2601 msgid "Number of pixels in Y" -msgstr "" +msgstr "Кількість пікселів за віссю Y" -#: src/libslic3r/PrintConfig.cpp:2225 +#: src/libslic3r/PrintConfig.cpp:2606 +msgid "Display horizontal mirroring" +msgstr "Горизонтальне віддзеркалення дисплея" + +#: src/libslic3r/PrintConfig.cpp:2607 +msgid "Mirror horizontally" +msgstr "Віддзеркалити горизонтально" + +#: src/libslic3r/PrintConfig.cpp:2608 +msgid "Enable horizontal mirroring of output images" +msgstr "Увімкнути горизонтальне віддзеркалення вихідних зображень" + +#: src/libslic3r/PrintConfig.cpp:2613 +msgid "Display vertical mirroring" +msgstr "Вертикальне віддзеркалення дисплея" + +#: src/libslic3r/PrintConfig.cpp:2614 +msgid "Mirror vertically" +msgstr "Віддзеркалити вертикально" + +#: src/libslic3r/PrintConfig.cpp:2615 +msgid "Enable vertical mirroring of output images" +msgstr "Увімкнути вертикальне віддзеркалення вихідних зображень" + +#: src/libslic3r/PrintConfig.cpp:2620 msgid "Display orientation" -msgstr "" +msgstr "Орієнтація дисплея" -#: src/libslic3r/PrintConfig.cpp:2226 +#: src/libslic3r/PrintConfig.cpp:2621 msgid "" "Set the actual LCD display orientation inside the SLA printer. Portrait mode " "will flip the meaning of display width and height parameters and the output " "images will be rotated by 90 degrees." msgstr "" +"Встановіть фактичну орієнтацію LCD-дисплея всередині SLA принтера. " +"Портретний режим переверне значення параметрів ширини та висоти дисплея, а " +"вихідні зображення повернуть на 90 градусів." -#: src/libslic3r/PrintConfig.cpp:2232 +#: src/libslic3r/PrintConfig.cpp:2627 msgid "Landscape" -msgstr "" +msgstr "Альбомна" -#: src/libslic3r/PrintConfig.cpp:2233 +#: src/libslic3r/PrintConfig.cpp:2628 msgid "Portrait" -msgstr "" +msgstr "Книжкова" -#: src/libslic3r/PrintConfig.cpp:2238 +#: src/libslic3r/PrintConfig.cpp:2633 msgid "Fast" -msgstr "" +msgstr "Швидкий" -#: src/libslic3r/PrintConfig.cpp:2239 +#: src/libslic3r/PrintConfig.cpp:2634 msgid "Fast tilt" -msgstr "" +msgstr "Швидкий нахил" -#: src/libslic3r/PrintConfig.cpp:2240 +#: src/libslic3r/PrintConfig.cpp:2635 msgid "Time of the fast tilt" -msgstr "" +msgstr "Час швидкого нахилу" -#: src/libslic3r/PrintConfig.cpp:2247 +#: src/libslic3r/PrintConfig.cpp:2642 msgid "Slow" -msgstr "" +msgstr "Повільний" -#: src/libslic3r/PrintConfig.cpp:2248 +#: src/libslic3r/PrintConfig.cpp:2643 msgid "Slow tilt" -msgstr "" +msgstr "Повільний нахил" -#: src/libslic3r/PrintConfig.cpp:2249 +#: src/libslic3r/PrintConfig.cpp:2644 msgid "Time of the slow tilt" -msgstr "" +msgstr "Час повільного нахилу" -#: src/libslic3r/PrintConfig.cpp:2256 +#: src/libslic3r/PrintConfig.cpp:2651 msgid "Area fill" -msgstr "" +msgstr "Заповнена область" -#: src/libslic3r/PrintConfig.cpp:2257 +#: src/libslic3r/PrintConfig.cpp:2652 msgid "" "The percentage of the bed area. \n" "If the print area exceeds the specified value, \n" "then a slow tilt will be used, otherwise - a fast tilt" msgstr "" +"Відсоток площі столу.\n" +"Якщо область друку перевищує вказане значення,\n" +"тоді буде використовуватися повільний нахил, інакше - швидкий нахил" -#: src/libslic3r/PrintConfig.cpp:2264 src/libslic3r/PrintConfig.cpp:2265 -#: src/libslic3r/PrintConfig.cpp:2266 +#: src/libslic3r/PrintConfig.cpp:2659 src/libslic3r/PrintConfig.cpp:2660 +#: src/libslic3r/PrintConfig.cpp:2661 msgid "Printer scaling correction" -msgstr "" +msgstr "Корекція масштабування принтера" -#: src/libslic3r/PrintConfig.cpp:2272 src/libslic3r/PrintConfig.cpp:2273 +#: src/libslic3r/PrintConfig.cpp:2667 src/libslic3r/PrintConfig.cpp:2668 msgid "Printer absolute correction" -msgstr "" +msgstr "Абсолютна корекція принтера" -#: src/libslic3r/PrintConfig.cpp:2274 +#: src/libslic3r/PrintConfig.cpp:2669 msgid "" "Will inflate or deflate the sliced 2D polygons according to the sign of the " "correction." -msgstr "" +msgstr "Надує або спустить нарізані 2D-полігони відповідно до знака корекції." -#: src/libslic3r/PrintConfig.cpp:2280 src/libslic3r/PrintConfig.cpp:2281 +#: src/libslic3r/PrintConfig.cpp:2675 +msgid "Elephant foot minimum width" +msgstr "Мінімальна ширина слонової стопи" + +#: src/libslic3r/PrintConfig.cpp:2677 +msgid "" +"Minimum width of features to maintain when doing elephant foot compensation." +msgstr "" +"Мінімальна ширина частей, яку слід підтримувати, виконуючи компенсацію стопи " +"слона." + +#: src/libslic3r/PrintConfig.cpp:2684 src/libslic3r/PrintConfig.cpp:2685 msgid "Printer gamma correction" -msgstr "" +msgstr "Гамма - корекція принтера" -#: src/libslic3r/PrintConfig.cpp:2282 -msgid "This will apply a gamm correction to the rasterized 2D polygons." +#: src/libslic3r/PrintConfig.cpp:2686 +msgid "" +"This will apply a gamma correction to the rasterized 2D polygons. A gamma " +"value of zero means thresholding with the threshold in the middle. This " +"behaviour eliminates antialiasing without losing holes in polygons." msgstr "" +"Це застосує гамма-корекцію до растеризованих 2D-полігонів. Нульове значення " +"гамми означає порогове значення з порогом посередині. Така поведінка усуває " +"згладжування, не втрачаючи дірок у полігонах." -#: src/libslic3r/PrintConfig.cpp:2291 src/libslic3r/PrintConfig.cpp:2292 +#: src/libslic3r/PrintConfig.cpp:2698 src/libslic3r/PrintConfig.cpp:2699 +msgid "SLA material type" +msgstr "Тип SLA-матеріалу" + +#: src/libslic3r/PrintConfig.cpp:2710 src/libslic3r/PrintConfig.cpp:2711 msgid "Initial layer height" -msgstr "" +msgstr "Висота першого шару" -#: src/libslic3r/PrintConfig.cpp:2298 +#: src/libslic3r/PrintConfig.cpp:2717 src/libslic3r/PrintConfig.cpp:2718 +msgid "Bottle volume" +msgstr "Об’єм пляшки" + +#: src/libslic3r/PrintConfig.cpp:2719 +msgid "ml" +msgstr "мл" + +#: src/libslic3r/PrintConfig.cpp:2724 src/libslic3r/PrintConfig.cpp:2725 +msgid "Bottle weight" +msgstr "Вага пляшки" + +#: src/libslic3r/PrintConfig.cpp:2726 +msgid "kg" +msgstr "кг" + +#: src/libslic3r/PrintConfig.cpp:2733 +msgid "g/ml" +msgstr "г/мл" + +#: src/libslic3r/PrintConfig.cpp:2740 +msgid "money/bottle" +msgstr "грошових одиниць/пляшку" + +#: src/libslic3r/PrintConfig.cpp:2745 msgid "Faded layers" -msgstr "" +msgstr "Шари початкового контакту" -#: src/libslic3r/PrintConfig.cpp:2299 +#: src/libslic3r/PrintConfig.cpp:2746 msgid "" "Number of the layers needed for the exposure time fade from initial exposure " "time to the exposure time" msgstr "" +"Кількість шарів, необхідних для часу експозиції, зменшується від початкового " +"часу експозиції до часу експозиції" -#: src/libslic3r/PrintConfig.cpp:2306 src/libslic3r/PrintConfig.cpp:2307 +#: src/libslic3r/PrintConfig.cpp:2753 src/libslic3r/PrintConfig.cpp:2754 +msgid "Minimum exposure time" +msgstr "Мінімальний час експозиції" + +#: src/libslic3r/PrintConfig.cpp:2761 src/libslic3r/PrintConfig.cpp:2762 +msgid "Maximum exposure time" +msgstr "Максимальний час експозиції" + +#: src/libslic3r/PrintConfig.cpp:2769 src/libslic3r/PrintConfig.cpp:2770 msgid "Exposure time" -msgstr "" +msgstr "Час експозиції" -#: src/libslic3r/PrintConfig.cpp:2313 src/libslic3r/PrintConfig.cpp:2314 +#: src/libslic3r/PrintConfig.cpp:2776 src/libslic3r/PrintConfig.cpp:2777 +msgid "Minimum initial exposure time" +msgstr "Мінімальний час початкової експозиції" + +#: src/libslic3r/PrintConfig.cpp:2784 src/libslic3r/PrintConfig.cpp:2785 +msgid "Maximum initial exposure time" +msgstr "Максимальний час початкової експозиції" + +#: src/libslic3r/PrintConfig.cpp:2792 src/libslic3r/PrintConfig.cpp:2793 msgid "Initial exposure time" -msgstr "" +msgstr "Час початкової експозиції" -#: src/libslic3r/PrintConfig.cpp:2320 src/libslic3r/PrintConfig.cpp:2321 +#: src/libslic3r/PrintConfig.cpp:2799 src/libslic3r/PrintConfig.cpp:2800 msgid "Correction for expansion" -msgstr "" +msgstr "Поправка на розширення" -#: src/libslic3r/PrintConfig.cpp:2327 +#: src/libslic3r/PrintConfig.cpp:2806 msgid "SLA print material notes" -msgstr "" +msgstr "Примітки до друкованих SLA-матеріалів" -#: src/libslic3r/PrintConfig.cpp:2328 +#: src/libslic3r/PrintConfig.cpp:2807 msgid "You can put your notes regarding the SLA print material here." -msgstr "" +msgstr "Тут ви можете помістити свої нотатки щодо SLA-матеріалу." -#: src/libslic3r/PrintConfig.cpp:2336 src/libslic3r/PrintConfig.cpp:2347 +#: src/libslic3r/PrintConfig.cpp:2819 src/libslic3r/PrintConfig.cpp:2830 msgid "Default SLA material profile" -msgstr "" +msgstr "Профіль SLA-матеріалу за замовчанням" -#: src/libslic3r/PrintConfig.cpp:2358 +#: src/libslic3r/PrintConfig.cpp:2841 msgid "Generate supports" -msgstr "" +msgstr "Генерувати підтримки" -#: src/libslic3r/PrintConfig.cpp:2360 +#: src/libslic3r/PrintConfig.cpp:2843 msgid "Generate supports for the models" -msgstr "" +msgstr "Генерувати підтримки для моделей" -#: src/libslic3r/PrintConfig.cpp:2365 -msgid "Support head front diameter" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2848 +msgid "Pinhead front diameter" +msgstr "Діаметр головки стовпа" -#: src/libslic3r/PrintConfig.cpp:2367 +#: src/libslic3r/PrintConfig.cpp:2850 msgid "Diameter of the pointing side of the head" -msgstr "" +msgstr "Діаметр носику головки" -#: src/libslic3r/PrintConfig.cpp:2374 -msgid "Support head penetration" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2857 +msgid "Head penetration" +msgstr "Проникнення головки" -#: src/libslic3r/PrintConfig.cpp:2376 +#: src/libslic3r/PrintConfig.cpp:2859 msgid "How much the pinhead has to penetrate the model surface" -msgstr "" +msgstr "На скільки носики повинні проникати в поверхню моделі" -#: src/libslic3r/PrintConfig.cpp:2383 -msgid "Support head width" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2866 +msgid "Pinhead width" +msgstr "Ширина головки стовпа" -#: src/libslic3r/PrintConfig.cpp:2385 +#: src/libslic3r/PrintConfig.cpp:2868 msgid "Width from the back sphere center to the front sphere center" -msgstr "" +msgstr "Ширина від центру задньої кулі до передньої кулі" -#: src/libslic3r/PrintConfig.cpp:2393 -msgid "Support pillar diameter" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2876 +msgid "Pillar diameter" +msgstr "Діаметр стовпів" -#: src/libslic3r/PrintConfig.cpp:2395 +#: src/libslic3r/PrintConfig.cpp:2878 msgid "Diameter in mm of the support pillars" -msgstr "" +msgstr "Діаметр стовпів підтримки у мм" -#: src/libslic3r/PrintConfig.cpp:2403 -msgid "Support pillar connection mode" -msgstr "" +#: src/libslic3r/PrintConfig.cpp:2886 +msgid "Small pillar diameter percent" +msgstr "Процентний діаметр малих стовпів" -#: src/libslic3r/PrintConfig.cpp:2404 +#: src/libslic3r/PrintConfig.cpp:2888 msgid "" -"Controls the bridge type between two neigboring pillars. Can be zig-zag, " +"The percentage of smaller pillars compared to the normal pillar diameter " +"which are used in problematic areas where a normal pilla cannot fit." +msgstr "" +"Відсоток менших стовпів порівняно з нормальним діаметром стовпа, які " +"використовуються в проблемних зонах, де нормальний стовп не може поміститися." + +#: src/libslic3r/PrintConfig.cpp:2897 +msgid "Max bridges on a pillar" +msgstr "Макс. мостів на стовпі" + +#: src/libslic3r/PrintConfig.cpp:2899 +msgid "" +"Maximum number of bridges that can be placed on a pillar. Bridges hold " +"support point pinheads and connect to pillars as small branches." +msgstr "" +"Максимальна кількість мостів, які можна розмістити на тримаючому стовпі. " +"Мости утримують верхівки опор і з'єднуються зі стовпами як гілочки." + +#: src/libslic3r/PrintConfig.cpp:2907 +msgid "Pillar connection mode" +msgstr "Режим з'єднання стовпів" + +#: src/libslic3r/PrintConfig.cpp:2908 +msgid "" +"Controls the bridge type between two neighboring pillars. Can be zig-zag, " "cross (double zig-zag) or dynamic which will automatically switch between " "the first two depending on the distance of the two pillars." msgstr "" +"Керує типом мосту між двома сусідніми стовпами. Може бути зигзагоподібним, " +"поперечним (подвійний зигзагоподібний) або динамічним, який автоматично " +"перемикається між першими двома залежно від відстані двох стовпів." -#: src/libslic3r/PrintConfig.cpp:2412 +#: src/libslic3r/PrintConfig.cpp:2916 msgid "Zig-Zag" -msgstr "" +msgstr "Зіг-Заг" -#: src/libslic3r/PrintConfig.cpp:2413 +#: src/libslic3r/PrintConfig.cpp:2917 msgid "Cross" -msgstr "" +msgstr "Перехресний" -#: src/libslic3r/PrintConfig.cpp:2414 +#: src/libslic3r/PrintConfig.cpp:2918 msgid "Dynamic" -msgstr "" +msgstr "Динамічний" -#: src/libslic3r/PrintConfig.cpp:2426 +#: src/libslic3r/PrintConfig.cpp:2930 msgid "Pillar widening factor" -msgstr "" +msgstr "Коефіцієнт розширення стовпа" -#: src/libslic3r/PrintConfig.cpp:2428 +#: src/libslic3r/PrintConfig.cpp:2932 msgid "" "Merging bridges or pillars into another pillars can increase the radius. " "Zero means no increase, one means full increase." msgstr "" +"Злиття мостів або стовпів в інші стовпи може збільшити радіус. Нуль означає " +"відсутність збільшення, один означає повне збільшення." -#: src/libslic3r/PrintConfig.cpp:2437 +#: src/libslic3r/PrintConfig.cpp:2941 msgid "Support base diameter" -msgstr "" +msgstr "Діаметр основи підтримки" -#: src/libslic3r/PrintConfig.cpp:2439 +#: src/libslic3r/PrintConfig.cpp:2943 msgid "Diameter in mm of the pillar base" -msgstr "" +msgstr "Діаметр основи стовпа у мм" -#: src/libslic3r/PrintConfig.cpp:2447 +#: src/libslic3r/PrintConfig.cpp:2951 msgid "Support base height" -msgstr "" +msgstr "Висота основи підтримки" -#: src/libslic3r/PrintConfig.cpp:2449 +#: src/libslic3r/PrintConfig.cpp:2953 msgid "The height of the pillar base cone" -msgstr "" +msgstr "Висота конуса основи стовпа" -#: src/libslic3r/PrintConfig.cpp:2456 +#: src/libslic3r/PrintConfig.cpp:2960 +msgid "Support base safety distance" +msgstr "Безпечна відстань між основами підтримки" + +#: src/libslic3r/PrintConfig.cpp:2963 +msgid "" +"The minimum distance of the pillar base from the model in mm. Makes sense in " +"zero elevation mode where a gap according to this parameter is inserted " +"between the model and the pad." +msgstr "" +"Мінімальна відстань основи стовпа від моделі в мм. Має сенс у режимі " +"нульового підняття, коли між моделлю та майданчиком вставляється зазор " +"відповідно до цього параметра." + +#: src/libslic3r/PrintConfig.cpp:2973 msgid "Critical angle" -msgstr "" +msgstr "Критичний кут" -#: src/libslic3r/PrintConfig.cpp:2458 +#: src/libslic3r/PrintConfig.cpp:2975 msgid "The default angle for connecting support sticks and junctions." -msgstr "" +msgstr "Кут за замовчуванням для з'єднання опорних палочок і з'єднань." -#: src/libslic3r/PrintConfig.cpp:2466 +#: src/libslic3r/PrintConfig.cpp:2983 msgid "Max bridge length" -msgstr "" +msgstr "Максимальна довжина мосту" -#: src/libslic3r/PrintConfig.cpp:2468 +#: src/libslic3r/PrintConfig.cpp:2985 msgid "The max length of a bridge" -msgstr "" +msgstr "Максимальна довжина мосту" -#: src/libslic3r/PrintConfig.cpp:2475 +#: src/libslic3r/PrintConfig.cpp:2992 msgid "Max pillar linking distance" -msgstr "" +msgstr "Макс. відстань між стовпами" -#: src/libslic3r/PrintConfig.cpp:2477 +#: src/libslic3r/PrintConfig.cpp:2994 msgid "" "The max distance of two pillars to get linked with each other. A zero value " "will prohibit pillar cascading." msgstr "" +"Максимальна відстань двох стовпів для з'єднання між собою. Нульове значення " +"забороняє каскадування стовпів." -#: src/libslic3r/PrintConfig.cpp:2485 -msgid "Object elevation" +#: src/libslic3r/PrintConfig.cpp:3004 +msgid "" +"How much the supports should lift up the supported object. If \"Pad around " +"object\" is enabled, this value is ignored." msgstr "" +"Скільки опор повинно піднімати підтримуваний об’єкт. Якщо ввімкнено функцію " +"\"Подушка навколо об’єкта\", це значення ігнорується." -#: src/libslic3r/PrintConfig.cpp:2487 -msgid "How much the supports should lift up the supported object." -msgstr "" - -#: src/libslic3r/PrintConfig.cpp:2495 -msgid "Support points density" -msgstr "" - -#: src/libslic3r/PrintConfig.cpp:2497 +#: src/libslic3r/PrintConfig.cpp:3015 msgid "This is a relative measure of support points density." -msgstr "" +msgstr "Відносний показних щільності точок підтримки." -#: src/libslic3r/PrintConfig.cpp:2503 +#: src/libslic3r/PrintConfig.cpp:3021 msgid "Minimal distance of the support points" -msgstr "" +msgstr "Мінімальна відстань опорних точок" -#: src/libslic3r/PrintConfig.cpp:2505 +#: src/libslic3r/PrintConfig.cpp:3023 msgid "No support points will be placed closer than this threshold." -msgstr "" +msgstr "Жодні точки підтримки не будуть розміщені ближче цього порогу." -#: src/libslic3r/PrintConfig.cpp:2511 +#: src/libslic3r/PrintConfig.cpp:3029 msgid "Use pad" -msgstr "" +msgstr "Використовувати полушку" -#: src/libslic3r/PrintConfig.cpp:2513 +#: src/libslic3r/PrintConfig.cpp:3031 msgid "Add a pad underneath the supported model" -msgstr "" +msgstr "Додати подушечку під підтримувану модель" -#: src/libslic3r/PrintConfig.cpp:2518 +#: src/libslic3r/PrintConfig.cpp:3036 msgid "Pad wall thickness" -msgstr "" +msgstr "Товщина стінки подушки" -#: src/libslic3r/PrintConfig.cpp:2520 +#: src/libslic3r/PrintConfig.cpp:3038 msgid "The thickness of the pad and its optional cavity walls." -msgstr "" +msgstr "Товщина подушки та її додаткових стінок порожнини." -#: src/libslic3r/PrintConfig.cpp:2528 +#: src/libslic3r/PrintConfig.cpp:3046 msgid "Pad wall height" -msgstr "" +msgstr "Висота стінки подушки" -#: src/libslic3r/PrintConfig.cpp:2529 -msgid "Defines the cavity depth. Set to zero to disable the cavity." +#: src/libslic3r/PrintConfig.cpp:3047 +msgid "" +"Defines the pad cavity depth. Set to zero to disable the cavity. Be careful " +"when enabling this feature, as some resins may produce an extreme suction " +"effect inside the cavity, which makes peeling the print off the vat foil " +"difficult." msgstr "" +"Визначає глибину порожнини подушечки. Встановіть нуль, щоб вимкнути " +"порожнину. Будьте обережні, включаючи цю функцію, оскільки деякі смоли " +"можуть мати надзвичайний ефект всмоктування всередині порожнини, що " +"ускладнює відшарування відбитка з фольги." -#: src/libslic3r/PrintConfig.cpp:2539 +#: src/libslic3r/PrintConfig.cpp:3060 +msgid "Pad brim size" +msgstr "Розмір краю подушки" + +#: src/libslic3r/PrintConfig.cpp:3061 +msgid "How far should the pad extend around the contained geometry" +msgstr "Як далеко повинна розширюватися подушка навколо вміщуваної геометрії" + +#: src/libslic3r/PrintConfig.cpp:3071 msgid "Max merge distance" -msgstr "" +msgstr "Макс. відстань об'єднання" -#: src/libslic3r/PrintConfig.cpp:2541 +#: src/libslic3r/PrintConfig.cpp:3073 msgid "" "Some objects can get along with a few smaller pads instead of a single big " "one. This parameter defines how far the center of two smaller pads should " "be. If theyare closer, they will get merged into one pad." msgstr "" +"Деякі предмети можуть уживатися з кількома меншими подушками замість однієї " +"великої. Цей параметр визначає, наскільки далеко повинен бути центр двох " +"менших подушок. Якщо вони стануть ближче, вони об’єднаються в одну велику." -#: src/libslic3r/PrintConfig.cpp:2552 -msgid "Pad edge radius" -msgstr "" - -#: src/libslic3r/PrintConfig.cpp:2561 +#: src/libslic3r/PrintConfig.cpp:3093 msgid "Pad wall slope" -msgstr "" +msgstr "Нахил стінки подушки" -#: src/libslic3r/PrintConfig.cpp:2563 +#: src/libslic3r/PrintConfig.cpp:3095 msgid "" "The slope of the pad wall relative to the bed plane. 90 degrees means " "straight walls." msgstr "" +"Нахил стінки подушки відносно площини столу. 90 градусів означає прямі стіни." -#: src/libslic3r/PrintConfig.cpp:2924 -msgid "Export SVG" +#: src/libslic3r/PrintConfig.cpp:3106 +msgid "Create pad around object and ignore the support elevation" +msgstr "Створити подушку навколо об’єкта та ігнорувати підняття підтримки" + +#: src/libslic3r/PrintConfig.cpp:3111 +msgid "Pad around object everywhere" +msgstr "Подушка скрізь навколо об’єкта" + +#: src/libslic3r/PrintConfig.cpp:3113 +msgid "Force pad around object everywhere" +msgstr "Створити подушку навколо об’єкта" + +#: src/libslic3r/PrintConfig.cpp:3118 +msgid "Pad object gap" +msgstr "Розрив Подушка-Об'єкт" + +#: src/libslic3r/PrintConfig.cpp:3120 +msgid "" +"The gap between the object bottom and the generated pad in zero elevation " +"mode." msgstr "" +"Розрив між дном об’єкта та генерованою подушкою в режимі нульового підняття." -#: src/libslic3r/PrintConfig.cpp:2925 +#: src/libslic3r/PrintConfig.cpp:3129 +msgid "Pad object connector stride" +msgstr "Крок з'єднувача Подушка-Об'єкт" + +#: src/libslic3r/PrintConfig.cpp:3131 +msgid "" +"Distance between two connector sticks which connect the object and the " +"generated pad." +msgstr "" +"Відстань між двома з'єднувальними паличками, які з'єднують об'єкт та " +"генеровану подушку." + +#: src/libslic3r/PrintConfig.cpp:3138 +msgid "Pad object connector width" +msgstr "Ширина з'єднувача Подушка-Об'єкт" + +#: src/libslic3r/PrintConfig.cpp:3140 +msgid "" +"Width of the connector sticks which connect the object and the generated pad." +msgstr "" +"Ширина з'єднувальної паличками, що з'єднує об'єкт та генеровану подушку." + +#: src/libslic3r/PrintConfig.cpp:3147 +msgid "Pad object connector penetration" +msgstr "Глибина проникнення з'єднувача Подушка-Об'єкт" + +#: src/libslic3r/PrintConfig.cpp:3150 +msgid "How much should the tiny connectors penetrate into the model body." +msgstr "На скільки крихітні з'єднувачі повинні проникати в тіло моделі." + +#: src/libslic3r/PrintConfig.cpp:3157 +msgid "Enable hollowing" +msgstr "Увімкнути формування порожнин" + +#: src/libslic3r/PrintConfig.cpp:3159 +msgid "Hollow out a model to have an empty interior" +msgstr "Випорожнити модель, щоб мати порожній інтер’єр" + +#: src/libslic3r/PrintConfig.cpp:3164 +msgid "Wall thickness" +msgstr "Товщина стінки" + +#: src/libslic3r/PrintConfig.cpp:3166 +msgid "Minimum wall thickness of a hollowed model." +msgstr "Мінімальна товщина стінки порожнистої моделі." + +#: src/libslic3r/PrintConfig.cpp:3174 +msgid "Accuracy" +msgstr "Точність" + +#: src/libslic3r/PrintConfig.cpp:3176 +msgid "" +"Performance vs accuracy of calculation. Lower values may produce unwanted " +"artifacts." +msgstr "" +"Продуктивність проти точності розрахунку. Менші значення можуть спричинити " +"небажані артефакти." + +#: src/libslic3r/PrintConfig.cpp:3186 +msgid "" +"Hollowing is done in two steps: first, an imaginary interior is calculated " +"deeper (offset plus the closing distance) in the object and then it's " +"inflated back to the specified offset. A greater closing distance makes the " +"interior more rounded. At zero, the interior will resemble the exterior the " +"most." +msgstr "" +"Випорожнення виконується у два етапи: спочатку уявний інтер’єр обчислюється " +"глибше (зміщення плюс відстань закриття) в об’єкті, а потім він завищується " +"назад до заданого зміщення. Більша відстань до закриття робить інтер’єр " +"більш округлим. При нулі інтер’єр найбільше буде нагадувати екстер’єр." + +#: src/libslic3r/PrintConfig.cpp:3602 +msgid "Export OBJ" +msgstr "Експорт OBJ" + +#: src/libslic3r/PrintConfig.cpp:3603 msgid "Export the model(s) as OBJ." -msgstr "" +msgstr "Експорт моделі як OBJ." -#: src/libslic3r/PrintConfig.cpp:2936 +#: src/libslic3r/PrintConfig.cpp:3614 msgid "Export SLA" -msgstr "" +msgstr "Експорт SLA" -#: src/libslic3r/PrintConfig.cpp:2937 +#: src/libslic3r/PrintConfig.cpp:3615 msgid "Slice the model and export SLA printing layers as PNG." -msgstr "" +msgstr "Нарізати модель та експортувати шари SLA-друку до PNG." -#: src/libslic3r/PrintConfig.cpp:2942 +#: src/libslic3r/PrintConfig.cpp:3620 msgid "Export 3MF" -msgstr "" +msgstr "Експортувати 3MF" -#: src/libslic3r/PrintConfig.cpp:2943 +#: src/libslic3r/PrintConfig.cpp:3621 msgid "Export the model(s) as 3MF." -msgstr "" +msgstr "Експорт моделі як 3MF." -#: src/libslic3r/PrintConfig.cpp:2947 +#: src/libslic3r/PrintConfig.cpp:3625 msgid "Export AMF" -msgstr "" +msgstr "Експортувати AMF" -#: src/libslic3r/PrintConfig.cpp:2948 +#: src/libslic3r/PrintConfig.cpp:3626 msgid "Export the model(s) as AMF." -msgstr "" +msgstr "Експорт моделі як АMF." -#: src/libslic3r/PrintConfig.cpp:2952 +#: src/libslic3r/PrintConfig.cpp:3630 msgid "Export STL" -msgstr "" +msgstr "Експорт STL" -#: src/libslic3r/PrintConfig.cpp:2953 +#: src/libslic3r/PrintConfig.cpp:3631 msgid "Export the model(s) as STL." -msgstr "" +msgstr "Експорт моделі як STL." -#: src/libslic3r/PrintConfig.cpp:2958 +#: src/libslic3r/PrintConfig.cpp:3636 msgid "Slice the model and export toolpaths as G-code." -msgstr "" +msgstr "Нарізати та експортувати G-код." -#: src/libslic3r/PrintConfig.cpp:2963 +#: src/libslic3r/PrintConfig.cpp:3641 +msgid "G-code viewer" +msgstr "Переглядач G-коду" + +#: src/libslic3r/PrintConfig.cpp:3642 +msgid "Visualize an already sliced and saved G-code" +msgstr "Візуалізувати вже нарізаний та збережений G-код" + +#: src/libslic3r/PrintConfig.cpp:3647 msgid "Slice" -msgstr "" +msgstr "Нарізати" -#: src/libslic3r/PrintConfig.cpp:2964 +#: src/libslic3r/PrintConfig.cpp:3648 msgid "" "Slice the model as FFF or SLA based on the printer_technology configuration " "value." msgstr "" +"Нарізати модель як FFF або SLA на основі значення printer_technology, " +"зазначеного у конфігурації." -#: src/libslic3r/PrintConfig.cpp:2969 +#: src/libslic3r/PrintConfig.cpp:3653 msgid "Help" msgstr "Допомога" -#: src/libslic3r/PrintConfig.cpp:2970 +#: src/libslic3r/PrintConfig.cpp:3654 msgid "Show this help." -msgstr "" +msgstr "Показати цю підказку." -#: src/libslic3r/PrintConfig.cpp:2975 +#: src/libslic3r/PrintConfig.cpp:3659 msgid "Help (FFF options)" -msgstr "" +msgstr "Допомога (FFF параметри)" -#: src/libslic3r/PrintConfig.cpp:2976 +#: src/libslic3r/PrintConfig.cpp:3660 msgid "Show the full list of print/G-code configuration options." -msgstr "" +msgstr "Показати повний список параметрів конфігурації друку / G-коду." -#: src/libslic3r/PrintConfig.cpp:2980 +#: src/libslic3r/PrintConfig.cpp:3664 msgid "Help (SLA options)" -msgstr "" +msgstr "Допомога (SLA параметри)" -#: src/libslic3r/PrintConfig.cpp:2981 +#: src/libslic3r/PrintConfig.cpp:3665 msgid "Show the full list of SLA print configuration options." -msgstr "" +msgstr "Показати повний перелік параметрів конфігурації SLA-друку." -#: src/libslic3r/PrintConfig.cpp:2985 +#: src/libslic3r/PrintConfig.cpp:3669 msgid "Output Model Info" -msgstr "" +msgstr "Інформація про вихідну модель" -#: src/libslic3r/PrintConfig.cpp:2986 +#: src/libslic3r/PrintConfig.cpp:3670 msgid "Write information about the model to the console." -msgstr "" +msgstr "Писати інформацію про модель на консолі." -#: src/libslic3r/PrintConfig.cpp:2990 +#: src/libslic3r/PrintConfig.cpp:3674 msgid "Save config file" -msgstr "" +msgstr "Зберегти файл конфігурації" -#: src/libslic3r/PrintConfig.cpp:2991 +#: src/libslic3r/PrintConfig.cpp:3675 msgid "Save configuration to the specified file." -msgstr "" +msgstr "Зберегти конфігурацію у вказаному файлі." -#: src/libslic3r/PrintConfig.cpp:3001 +#: src/libslic3r/PrintConfig.cpp:3685 msgid "Align XY" -msgstr "" +msgstr "Вирівняти XY" -#: src/libslic3r/PrintConfig.cpp:3002 +#: src/libslic3r/PrintConfig.cpp:3686 msgid "Align the model to the given point." -msgstr "" +msgstr "Вирівняйте модель за заданою точкою." -#: src/libslic3r/PrintConfig.cpp:3007 +#: src/libslic3r/PrintConfig.cpp:3691 msgid "Cut model at the given Z." msgstr "Розрізати модель за заданим Z." -#: src/libslic3r/PrintConfig.cpp:3028 +#: src/libslic3r/PrintConfig.cpp:3712 msgid "Center" -msgstr "" +msgstr "Центр" -#: src/libslic3r/PrintConfig.cpp:3029 +#: src/libslic3r/PrintConfig.cpp:3713 msgid "Center the print around the given center." -msgstr "" +msgstr "Відцентруйте друк навколо заданого центру." -#: src/libslic3r/PrintConfig.cpp:3033 +#: src/libslic3r/PrintConfig.cpp:3717 msgid "Don't arrange" -msgstr "" +msgstr "Не впорядковувати" -#: src/libslic3r/PrintConfig.cpp:3034 +#: src/libslic3r/PrintConfig.cpp:3718 msgid "" "Do not rearrange the given models before merging and keep their original XY " "coordinates." msgstr "" +"Не переставляйте дані моделі перед об’єднанням та зберігайте їх початкові " +"координати XY." -#: src/libslic3r/PrintConfig.cpp:3037 +#: src/libslic3r/PrintConfig.cpp:3721 msgid "Duplicate" -msgstr "" +msgstr "Дублювати" -#: src/libslic3r/PrintConfig.cpp:3038 +#: src/libslic3r/PrintConfig.cpp:3722 msgid "Multiply copies by this factor." -msgstr "" +msgstr "Збільшить кількість копій на цей коефіцієнт." -#: src/libslic3r/PrintConfig.cpp:3042 +#: src/libslic3r/PrintConfig.cpp:3726 msgid "Duplicate by grid" -msgstr "" +msgstr "Дублювати за сіткою" -#: src/libslic3r/PrintConfig.cpp:3043 +#: src/libslic3r/PrintConfig.cpp:3727 msgid "Multiply copies by creating a grid." -msgstr "" +msgstr "Збільшить кількість копій, створивши сітку." -#: src/libslic3r/PrintConfig.cpp:3046 -msgid "Merge" -msgstr "" - -#: src/libslic3r/PrintConfig.cpp:3047 +#: src/libslic3r/PrintConfig.cpp:3731 msgid "" "Arrange the supplied models in a plate and merge them in a single model in " "order to perform actions once." msgstr "" +"Розташувати поставлені моделі на платформі та об’єднати їх в одну модель, " +"щоб виконати дії один раз." -#: src/libslic3r/PrintConfig.cpp:3052 +#: src/libslic3r/PrintConfig.cpp:3736 msgid "" "Try to repair any non-manifold meshes (this option is implicitly added " "whenever we need to slice the model to perform the requested action)." msgstr "" +"Спробуйте відновити будь-які нерізноманітні сітки (ця опція неявно додається " +"кожного разу, коли нам потрібно нарізати модель для виконання запитуваної " +"дії)." -#: src/libslic3r/PrintConfig.cpp:3056 +#: src/libslic3r/PrintConfig.cpp:3740 msgid "Rotation angle around the Z axis in degrees." -msgstr "" +msgstr "Кут обертання навколо осі Z у градусах." -#: src/libslic3r/PrintConfig.cpp:3060 +#: src/libslic3r/PrintConfig.cpp:3744 msgid "Rotate around X" -msgstr "" +msgstr "Обертати навколо осі X" -#: src/libslic3r/PrintConfig.cpp:3061 +#: src/libslic3r/PrintConfig.cpp:3745 msgid "Rotation angle around the X axis in degrees." -msgstr "" +msgstr "Кут обертання навколо осі Х у градусах." -#: src/libslic3r/PrintConfig.cpp:3065 +#: src/libslic3r/PrintConfig.cpp:3749 msgid "Rotate around Y" -msgstr "" +msgstr "Обертати навколо осі Y" -#: src/libslic3r/PrintConfig.cpp:3066 +#: src/libslic3r/PrintConfig.cpp:3750 msgid "Rotation angle around the Y axis in degrees." -msgstr "" +msgstr "Кут обертання навколо осі Y у градусах." -#: src/libslic3r/PrintConfig.cpp:3071 +#: src/libslic3r/PrintConfig.cpp:3755 msgid "Scaling factor or percentage." -msgstr "" +msgstr "Коефіцієнт масштабування або відсоток." -#: src/libslic3r/PrintConfig.cpp:3076 +#: src/libslic3r/PrintConfig.cpp:3760 msgid "" "Detect unconnected parts in the given model(s) and split them into separate " "objects." msgstr "" +"Визначити непоєднані частини у даній моделі (моделях) та розділити їх на " +"окремі об’єкти." -#: src/libslic3r/PrintConfig.cpp:3079 +#: src/libslic3r/PrintConfig.cpp:3763 msgid "Scale to Fit" -msgstr "" +msgstr "Масштабувати під область друку" -#: src/libslic3r/PrintConfig.cpp:3080 +#: src/libslic3r/PrintConfig.cpp:3764 msgid "Scale to fit the given volume." -msgstr "" +msgstr "Масштабувати під задану область друку." -#: src/libslic3r/PrintConfig.cpp:3089 +#: src/libslic3r/PrintConfig.cpp:3773 msgid "Ignore non-existent config files" -msgstr "" +msgstr "Ігнорувати неіснуючі конфігураційні файли" -#: src/libslic3r/PrintConfig.cpp:3090 +#: src/libslic3r/PrintConfig.cpp:3774 msgid "Do not fail if a file supplied to --load does not exist." -msgstr "" +msgstr "Не відмовляти, якщо файл, який подається до --load, не існує." -#: src/libslic3r/PrintConfig.cpp:3093 +#: src/libslic3r/PrintConfig.cpp:3777 msgid "Load config file" -msgstr "" +msgstr "Завантажити файл конфігурації" -#: src/libslic3r/PrintConfig.cpp:3094 +#: src/libslic3r/PrintConfig.cpp:3778 msgid "" "Load configuration from the specified file. It can be used more than once to " "load options from multiple files." msgstr "" +"Завантажити конфігурацію із зазначеного файлу. Його можна використовувати " +"більше одного разу для завантаження опцій з декількох файлів." -#: src/libslic3r/PrintConfig.cpp:3097 +#: src/libslic3r/PrintConfig.cpp:3781 msgid "Output File" -msgstr "" +msgstr "Вихідний файл" -#: src/libslic3r/PrintConfig.cpp:3098 +#: src/libslic3r/PrintConfig.cpp:3782 msgid "" "The file where the output will be written (if not specified, it will be " "based on the input file)." msgstr "" +"Файл, в який буде записано вихідні дані (якщо не вказано, він базуватиметься " +"на вхідному файлі)." -#: src/libslic3r/PrintConfig.cpp:3108 -msgid "Data directory" +#: src/libslic3r/PrintConfig.cpp:3786 +msgid "Single instance mode" +msgstr "Режим одного екземпляру PrusaSlicer" + +#: src/libslic3r/PrintConfig.cpp:3787 +msgid "" +"If enabled, the command line arguments are sent to an existing instance of " +"GUI PrusaSlicer, or an existing PrusaSlicer window is activated. Overrides " +"the \"single_instance\" configuration value from application preferences." msgstr "" +"Якщо увімкнено, аргументи командного рядка надсилаються до існуючого " +"екземпляра графічного інтерфейсу PrusaSlicer, або ж активується існуюче " +"вікно PrusaSlicer. Замінює значення конфігурації \"single_instance\" у " +"налаштуваннях програми." -#: src/libslic3r/PrintConfig.cpp:3109 +#: src/libslic3r/PrintConfig.cpp:3798 +msgid "Data directory" +msgstr "Каталог даних" + +#: src/libslic3r/PrintConfig.cpp:3799 msgid "" "Load and store settings at the given directory. This is useful for " "maintaining different profiles or including configurations from a network " "storage." msgstr "" +"Завантажити та зберегти налаштування у вказаному каталозі. Це корисно для " +"ведення різних профілів або включення конфігурацій із мережевого сховища." -#: src/libslic3r/PrintConfig.cpp:3112 +#: src/libslic3r/PrintConfig.cpp:3802 msgid "Logging level" -msgstr "" +msgstr "Рівень журналізації" -#: src/libslic3r/PrintConfig.cpp:3113 +#: src/libslic3r/PrintConfig.cpp:3803 msgid "" -"Messages with severity lower or eqal to the loglevel will be printed out. 0:" -"trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal" +"Sets logging sensitivity. 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:" +"trace\n" +"For example. loglevel=2 logs fatal, error and warning level messages." msgstr "" +"Встановлює чутливість журналювання. 0:fatal, 1:помилка, 2:попередження, 3:" +"info, 4:налагодження, 5:trace\n" +"Наприклад. loglevel=2 журнали фатальних, помилок і повідомлень рівня " +"попередження." -#: src/libslic3r/GCode/PreviewData.cpp:176 -msgid "Mixed" +#: src/libslic3r/PrintConfig.cpp:3809 +msgid "Render with a software renderer" +msgstr "Візуалізувати за допомогою програмного засобу візуалізації" + +#: src/libslic3r/PrintConfig.cpp:3810 +msgid "" +"Render with a software renderer. The bundled MESA software renderer is " +"loaded instead of the default OpenGL driver." msgstr "" +"Візуалізувати за допомогою програмного засобу візуалізації. Комплектний " +"візуалізатор програмного забезпечення MESA завантажується замість драйвера " +"OpenGL за замовчуванням." -#: src/libslic3r/GCode/PreviewData.cpp:396 -msgid "Height (mm)" -msgstr "Висота (мм)" +#: src/libslic3r/Zipper.cpp:27 +msgid "Error with zip archive" +msgstr "Помилка ZIP-архіву" -#: src/libslic3r/GCode/PreviewData.cpp:398 -msgid "Width (mm)" -msgstr "Ширина (мм)" +#: src/libslic3r/PrintObject.cpp:112 +msgid "Processing triangulated mesh" +msgstr "Обробка триангульованої сітки" -#: src/libslic3r/GCode/PreviewData.cpp:400 -msgid "Speed (mm/s)" -msgstr "Швидкість (мм/с)" +#: src/libslic3r/PrintObject.cpp:157 +msgid "Generating perimeters" +msgstr "Створення периметрів" -#: src/libslic3r/GCode/PreviewData.cpp:402 -msgid "Volumetric flow rate (mm3/s)" -msgstr "" +#: src/libslic3r/PrintObject.cpp:260 +msgid "Preparing infill" +msgstr "Підготовка заповнення" -#: src/libslic3r/GCode/PreviewData.cpp:491 -msgid "Default print color" -msgstr "" +#: src/libslic3r/PrintObject.cpp:421 +msgid "Generating support material" +msgstr "Створення підтримок" -#: src/libslic3r/GCode/PreviewData.cpp:495 -#, c-format -msgid "up to %.2f mm" -msgstr "" +#~ msgid "About Slic3r" +#~ msgstr "Про Slic3r" -#: src/libslic3r/GCode/PreviewData.cpp:499 -#, c-format -msgid "above %.2f mm" -msgstr "" +#~ msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):" +#~ msgstr "Виберіть файл, щоб імпортувати форму полотна з (STL/OBJ/AMF/PRUSA):" -#: src/libslic3r/GCode/PreviewData.cpp:504 -#, c-format -msgid "%.2f - %.2f mm" -msgstr "" +#~ msgid "Error! " +#~ msgstr "Помилка! " + +#~ msgid "slic3r version" +#~ msgstr "версія slic3r" + +#~ msgid "min slic3r version" +#~ msgstr "мінімальна версія slic3r" + +#~ msgid "max slic3r version" +#~ msgstr "максимальна версія slic3r" + +#~ msgid "Welcome to the Slic3r %s" +#~ msgstr "Ласкаво просимо до Slic3r %s" + +#~ msgid "Cut object:" +#~ msgstr "Розрізати об'єкт:" + +#~ msgid "Left mouse click - add point" +#~ msgstr "Ліва кнопка миші - додати точку" + +#~ msgid "Right mouse click - remove point" +#~ msgstr "Права кнопка миші - видалити точку" + +#~ msgid "SLA Support Points [L]" +#~ msgstr "Точки SLA підтримки [L]" + +#~ msgid "Array of language names and identifiers should have the same size." +#~ msgstr "Масив імен мов та їх ідентифікаторів має бути однакового розміру." + +#~ msgid "Slic3r View Mode" +#~ msgstr "Режим перегляду Slic3r'у" + +#~ msgid "Change Application &Language" +#~ msgstr "Змінити &мову застосування" + +#~ msgid "Application will be restarted after language change." +#~ msgstr "Застосування буде перезапущене після зміни мови." + +#~ msgid "You have unsaved changes " +#~ msgstr "У вас є незбережені зміни " + +#~ msgid ". Discard changes and continue anyway?" +#~ msgstr ". Відхилити зміни і продовжити в будь-якому випадку?" + +#~ msgid "Unsaved Presets" +#~ msgstr "Незбереженні налаштування" + +#~ msgid "Unretractions" +#~ msgstr "Непереривання" + +#~ msgid "Delete All" +#~ msgstr "Видалити все" + +#~ msgid "" +#~ " - Remember to check for updates at http://github.com/prusa3d/slic3r/" +#~ "releases" +#~ msgstr "" +#~ " - Пам'ятайте оновлювати з http://github.com/prusa3d/slic3r/releases" + +#~ msgid "Quit Slic3r" +#~ msgstr "Вийти зі Slic3r" + +#~ msgid "Open the Prusa Edition releases page in your browser" +#~ msgstr "Відкрити сторінку релізів Prusa Edition у своєму браузері" + +#~ msgid "Slic3r &Website" +#~ msgstr "Веб-сайт Slic3r" + +#~ msgid "Open the Slic3r website in your browser" +#~ msgstr "Відкрити сторінку Slic3r у своєму браузері" + +#~ msgid "Slic3r &Manual" +#~ msgstr "Посібник до Slic3r" + +#~ msgid "Open the Slic3r manual in your browser" +#~ msgstr "Відкрити сторінку посібнику до Slic3r у своєму браузері" + +#~ msgid "Report an issue on the Slic3r Prusa Edition" +#~ msgstr "Повідомити про проблему на Slic3r Prusa Edition" + +#~ msgid "&About Slic3r" +#~ msgstr "&Про Slic3r" + +#~ msgid "Save " +#~ msgstr "Зберегти " + +#~ msgid " file as:" +#~ msgstr " файл як:" + +#~ msgid "Processing " +#~ msgstr "Обробка " + +#~ msgid " was successfully sliced." +#~ msgstr " був успішно нарізаний." + +#~ msgid "" +#~ "This file contains several objects positioned at multiple heights. " +#~ "Instead of considering them as multiple objects, should I consider\n" +#~ "this file as a single object having multiple parts?\n" +#~ msgstr "" +#~ "Цей файл містить кілька об'єктів, розташованих на декількох висотах. " +#~ "Замість того, щоб розглядати їх як кілька об'єктів, чи потрібно " +#~ "розглянути\n" +#~ "цей файл як єдиний об'єкт, що має декілька частин?\n" + +#~ msgid "" +#~ "Multiple objects were loaded for a multi-material printer.\n" +#~ "Instead of considering them as multiple objects, should I consider\n" +#~ "these files to represent a single object having multiple parts?\n" +#~ msgstr "" +#~ "До мульти-матеріального принтеру завантажено кілька об'єктів.\n" +#~ "Замість того, щоб розглядати їх як кілька об'єктів, чи потрібно " +#~ "розглянути\n" +#~ "ці файл як єдиний об'єкт, що має декілька частин?\n" + +#~ msgid "Export failed" +#~ msgstr "Експортувати не вдалося" + +#~ msgid "Increase copies" +#~ msgstr "Збільшити копії" + +#~ msgid "Place one more copy of the selected object" +#~ msgstr "Розташувати ще одну копію обраного об'єкта" + +#~ msgid "Decrease copies" +#~ msgstr "Зменшити копії" + +#~ msgid "Remove one copy of the selected object" +#~ msgstr "Вилучіть одну копію обраного об'єкта" + +#~ msgid "Change the number of copies of the selected object" +#~ msgstr "Змінити кількість копій обраного об'єкта" + +#~ msgid "Reload from Disk" +#~ msgstr "Перезавантажити з диска" + +#~ msgid "Reload the selected file from Disk" +#~ msgstr "Перезавантажити вибраний файл із диска" + +#~ msgid "Use legacy OpenGL 1.1 rendering" +#~ msgstr "Використовувати застарілий OpenGL 1.1 рендеринг" + +#~ msgid "" +#~ "If you have rendering issues caused by a buggy OpenGL 2.0 driver, you may " +#~ "try to check this checkbox. This will disable the layer height editing " +#~ "and anti aliasing, so it is likely better to upgrade your graphics driver." +#~ msgstr "" +#~ "Якщо у вас виникають проблеми з візуалізацією, спричинені помилковим " +#~ "драйвером OpenGL 2.0, спробуйте вибрати цю опцію. Це призведе до " +#~ "вимкнення редагування висоти шару та згладжування, тому краще оновити " +#~ "графічний драйвер." + +#~ msgid "You need to restart Slic3r to make the changes effective." +#~ msgstr "З метою ефективності зміни, Вам потрібно буде перезапустити Slic3r." + +#~ msgid "" +#~ "If estimated layer time is below ~%ds, fan will run at %d%% and print " +#~ "speed will be reduced so that no less than %ds are spent on that layer " +#~ "(however, speed will never be reduced below %dmm/s)." +#~ msgstr "" +#~ "Якщо запланований час друку шару нижче ~%dс, вентилятор буде працювати на" +#~ "%d%%, і швидкість друку буде зменшена, так що на цей шар витрачається не " +#~ "менше %dс (однак швидкість ніколи не зменшиться нижче %d mm/s) ." + +#~ msgid "" +#~ "\n" +#~ "If estimated layer time is greater, but still below ~%ds, fan will run at " +#~ "a proportionally decreasing speed between %d%% and %d%%." +#~ msgstr "" +#~ "\n" +#~ "Якщо запланований час друку шару більше, але все ще нижче ~%dс, " +#~ "вентилятор буде працювати з пропорційно зменшуваною швидкістю між %d%% та " +#~ "%d%%." + +#~ msgid "" +#~ "\n" +#~ "During the other layers, fan " +#~ msgstr "" +#~ "\n" +#~ "Під час друку інших шарів вентилятор " + +#~ msgid "Fan " +#~ msgstr "Вентилятор " + +#~ msgid "will always run at %d%% " +#~ msgstr "буде завжди працювати на %d%% " + +#~ msgid "except for the first %d layers" +#~ msgstr "за винятком перших %d шарів" + +#~ msgid "except for the first layer" +#~ msgstr "за винятком першого шару" + +#~ msgid "will be turned off." +#~ msgstr "буде вимкнено." + +#~ msgid " flow rate is maximized " +#~ msgstr " швидкість потоку максимізується " + +#~ msgid "when printing " +#~ msgstr "коли друкуємо " + +#~ msgid " with a volumetric rate " +#~ msgstr " з об'ємною швидкістю " + +#~ msgid "%3.2f mm³/s" +#~ msgstr "%3.2f мм³/с" + +#~ msgid " at filament speed %3.2f mm/s." +#~ msgstr " при швидкості філаменту %3.2f мм/с." + +#~ msgid "Recommended object thin wall thickness for layer height %.2f and " +#~ msgstr "Рекомендована товщина стінки для висоти шару %.2f та " + +#~ msgid "%d lines: %.2lf mm" +#~ msgstr "%d рядків: %.2lf мм" + +#~ msgid "Save current " +#~ msgstr "Зберегти поточний " + +#~ msgid "Extruder clearance (mm)" +#~ msgstr "Розмір екструдера (мм)" + +#~ msgid "" +#~ "The Spiral Vase mode requires:\n" +#~ "- one perimeter\n" +#~ "- no top solid layers\n" +#~ "- 0% fill density\n" +#~ "- no support material\n" +#~ "- no ensure_vertical_shell_thickness\n" +#~ "\n" +#~ "Shall I adjust those settings in order to enable Spiral Vase?" +#~ msgstr "" +#~ "Режим спіральної вази вимагає:\n" +#~ "- один периметр\n" +#~ "- немає верхніх щільних шарів\n" +#~ "- 0% щільність заповнення\n" +#~ "- немає підтримуючого матеріалу\n" +#~ "- не забезпечує товщини вертикальної оболонки\n" +#~ "\n" +#~ "Чи потрібно змінити ці налаштування, щоб увімкнути режим Спіральної вази?" + +#~ msgid "" +#~ "The Wipe Tower currently supports the non-soluble supports only\n" +#~ "if they are printed with the current extruder without triggering a tool " +#~ "change.\n" +#~ "(both support_material_extruder and support_material_interface_extruder " +#~ "need to be set to 0).\n" +#~ "\n" +#~ "Shall I adjust those settings in order to enable the Wipe Tower?" +#~ msgstr "" +#~ "Вичіщуюча веж в даний час підтримує лише нерозчинну підтримку\n" +#~ "якщо вони друкуються з поточним екструдером, не запускаючи зміну " +#~ "інструменту.\n" +#~ "(обидва значення support_material_extruder і " +#~ "support_material_interface_extruder повинні бути встановлені на 0).\n" +#~ "\n" +#~ "Чи потрібно коригувати ці налаштування, щоб увімкнути вичіщуючу веж?" + +#~ msgid "" +#~ "For the Wipe Tower to work with the soluble supports, the support layers\n" +#~ "need to be synchronized with the object layers.\n" +#~ "\n" +#~ "Shall I synchronize support layers in order to enable the Wipe Tower?" +#~ msgstr "" +#~ "Для того, щоб Вичіщуюча веж працювала з розчинними підтримками, шари " +#~ "підтримки\n" +#~ "повинні бути синхронізовані з шаром об'єкта.\n" +#~ "\n" +#~ "Чи потрібно синхронізувати шари підтримки, щоб увімкнути вичіщуючу веж?" + +#~ msgid "" +#~ "Supports work better, if the following feature is enabled:\n" +#~ "- Detect bridging perimeters\n" +#~ "\n" +#~ "Shall I adjust those settings for supports?" +#~ msgstr "" +#~ "Підтримка працює краще, якщо ввімкнено таку функцію:\n" +#~ "- Виявлення висячих периметрів(перемичок)\n" +#~ "\n" +#~ "Чи потрібно змінити ці налаштування для підтримки?" + +#~ msgid "The " +#~ msgstr "Шаблон наповнення " + +#~ msgid "" +#~ " infill pattern is not supposed to work at 100%% density.\n" +#~ "\n" +#~ "Shall I switch to rectilinear fill pattern?" +#~ msgstr "" +#~ " не підтримується на 100% щільності.\n" +#~ "\n" +#~ "Чи потрібно змінити його на Rectilinear шаблон заповнення?" + +#~ msgid "Temperature " +#~ msgstr "Температура " + +#~ msgid " Browse " +#~ msgstr " Переглянути " + +#~ msgid " Set " +#~ msgstr " Встановити " + +#~ msgid "USB/Serial connection" +#~ msgstr "USB/послідовне з'єднання" + +#~ msgid "Serial port" +#~ msgstr "Послідовний порт" + +#~ msgid "Rescan serial ports" +#~ msgstr "Сканувати ще раз послідовні порти" + +#~ msgid "Connection to printer works correctly." +#~ msgstr "Підключення до принтера працює коректно." + +#~ msgid "Connection failed." +#~ msgstr "Підключення не вдалося." + +#~ msgid "Unsaved Changes" +#~ msgstr "Незбережені зміни" + +#~ msgid "Are you sure you want to " +#~ msgstr "Ви впевнені, що хочете " + +#~ msgid " the selected preset?" +#~ msgstr " вибране налаштування?" + +#~ msgid " Preset" +#~ msgstr " Налаштування" + +#~ msgid " as:" +#~ msgstr " як:" + +#~ msgid "" +#~ "When printing multi-material objects, this settings will make slic3r to " +#~ "clip the overlapping object parts one by the other (2nd part will be " +#~ "clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc)." +#~ msgstr "" +#~ "Під час друку багатоматеріальних об'єктів ці налаштування змушують slic3r " +#~ "обрізати частини, що перекриваються один одною (друга частина буде " +#~ "обрізана першою, третя - першою та другою, тощо)." + +#~ msgid "" +#~ "This end procedure is inserted at the end of the output file. Note that " +#~ "you can use placeholder variables for all Slic3r settings." +#~ msgstr "" +#~ "Ця кінцева процедура вставляється в кінці вихідного файлу. Зауважте, що " +#~ "ви можете використовувати заповнювачі змінних для всіх параметрів Slic3r." + +#~ msgid "" +#~ "This end procedure is inserted at the end of the output file, before the " +#~ "printer end gcode. Note that you can use placeholder variables for all " +#~ "Slic3r settings. If you have multiple extruders, the gcode is processed " +#~ "in extruder order." +#~ msgstr "" +#~ "Ця кінцева процедура вставляється в кінці вихідного файлу перед кінцевим " +#~ "кодом принтера. Зауважте, що ви можете використовувати заповнювачі " +#~ "змінних для всіх параметрів Slic3r. Якщо у вас є кілька екструдерів, G-" +#~ "code обробляється в порядку екструдерів." + +#~ msgid "mm or % (leave 0 for default)" +#~ msgstr "мм або % (залиште 0 за замовчанням)" + +#~ msgid "mm or % (leave 0 for auto)" +#~ msgstr "мм або % (залиште 0 для автообчислення)" + +#~ msgid "" +#~ "Extruder temperature for first layer. If you want to control temperature " +#~ "manually during print, set this to zero to disable temperature control " +#~ "commands in the output file." +#~ msgstr "" +#~ "Температура екструдеру для першого шару. Якщо ви хочете контролювати " +#~ "температуру вручну під час друку, встановіть 0, щоб вимкнути команди " +#~ "керування температурою у вихідному файлі." + +#~ msgid "" +#~ "Some G/M-code commands, including temperature control and others, are not " +#~ "universal. Set this option to your printer's firmware to get a compatible " +#~ "output. The \"No extrusion\" flavor prevents Slic3r from exporting any " +#~ "extrusion value at all." +#~ msgstr "" +#~ "Деякі команди G/M-коду, включаючи контроль температури тощо, не є " +#~ "універсальними. Установіть цей параметр на прошивку принтера, щоб " +#~ "отримати сумісний вихід. \"Відсутність екструзії\" не дозволяє Slic3r " +#~ "експортувати будь-яке значення екструзії." + +#~ msgid "" +#~ "This is the acceleration your printer will use for perimeters. A high " +#~ "value like 9000 usually gives good results if your hardware is up to the " +#~ "job. Set zero to disable acceleration control for perimeters." +#~ msgstr "" +#~ "Це прискорення, яке ваш принтер використовуватиме для периметрів. Висока " +#~ "значення, таке як 9000, зазвичай дає хороші результати, якщо ваше " +#~ "апаратне забезпечення відповідає завданню. Встановити 0, щоб вимкнути " +#~ "регулятор прискорення для периметрів." + +#~ msgid "USB/serial port for printer connection." +#~ msgstr "USB / послідовний порт для підключення принтера." + +#~ msgid "Serial port speed" +#~ msgstr "Швидкість послідовного порту" + +#~ msgid "Speed (baud) of USB/serial port for printer connection." +#~ msgstr "Швидкість (бод) USB / послідовного порту для підключення принтера." + +#~ msgid "" +#~ "This feature will raise Z gradually while printing a single-walled object " +#~ "in order to remove any visible seam. This option requires a single " +#~ "perimeter, no infill, no top solid layers and no support material. You " +#~ "can still set any number of bottom solid layers as well as skirt/brim " +#~ "loops. It won't work when printing more than an object." +#~ msgstr "" +#~ "Ця функція буде поступово підвищувати Z протягом друку одного-стінного " +#~ "об'єкта для уникнення будь-якого видимого шву. Цей параметр вимагає " +#~ "одношарового периметру, відсутнє наповнення, відсутність верхніх " +#~ "суцільних шарів і відсутність матеріалу підтримки. Ви все ще можете " +#~ "встановити будь-яку кількість нижніх суцільних шарів, а також петель " +#~ "плінтусу/краю. Це не спрацює при друку більше, ніж одного об'єкта." + +#~ msgid "" +#~ "This start procedure is inserted at the beginning, after bed has reached " +#~ "the target temperature and extruder just started heating, and before " +#~ "extruder has finished heating. If Slic3r detects M104 or M190 in your " +#~ "custom codes, such commands will not be prepended automatically so you're " +#~ "free to customize the order of heating commands and other custom actions. " +#~ "Note that you can use placeholder variables for all Slic3r settings, so " +#~ "you can put a \"M109 S[first_layer_temperature]\" command wherever you " +#~ "want." +#~ msgstr "" +#~ "Ця початкова процедура вставляється на початку, після того, як полотно " +#~ "досягне цільової температури, а екструдер тільки починає нагріватися, і " +#~ "перед тим, як екструдер закінчить нагрівання. Якщо Slic3r виявляє M104 " +#~ "або M190 у ваших користувацьких кодах, такі команди не будуть додаватися " +#~ "автоматично, щоб ви могли вільно налаштовувати порядок команд нагріву та " +#~ "інших спеціальних дій. Зверніть увагу, що ви можете використовувати " +#~ "змінні-заповнювачі для всіх параметрів Slic3r, щоб ви могли поставити " +#~ "команду \"M109 S [first_layer_temperature]\" де завгодно." + +#~ msgid "" +#~ "This start procedure is inserted at the beginning, after any printer " +#~ "start gcode. This is used to override settings for a specific filament. " +#~ "If Slic3r detects M104, M109, M140 or M190 in your custom codes, such " +#~ "commands will not be prepended automatically so you're free to customize " +#~ "the order of heating commands and other custom actions. Note that you can " +#~ "use placeholder variables for all Slic3r settings, so you can put a " +#~ "\"M109 S[first_layer_temperature]\" command wherever you want. If you " +#~ "have multiple extruders, the gcode is processed in extruder order." +#~ msgstr "" +#~ "Ця початкова процедура вставляється на початку, після того, як будь-який " +#~ "принтер запускає G-code. Це використовується для перевизначення " +#~ "параметрів для певної нитки. Якщо Slic3r виявляє M104, M109, M140 або " +#~ "M190 у ваших користувацьких кодах, такі команди не будуть автоматично " +#~ "додаватися, тому ви можете налаштувати порядок команд нагріву та інших " +#~ "спеціальних дій. Зверніть увагу, що ви можете використовувати змінні-" +#~ "заповнювачі для всіх параметрів Slic3r, щоб ви могли поставити команду " +#~ "\"M109 S [first_layer_temperature]\" де завгодно. Якщо у вас є кілька " +#~ "екструдерів, G-code обробляється в порядку екструдерів." + +#~ msgid "soluble" +#~ msgstr "розчинний" + +#~ msgid "detachable" +#~ msgstr "відривний" + +#~ msgid "" +#~ "Extruder temperature for layers after the first one. Set this to zero to " +#~ "disable temperature control commands in the output." +#~ msgstr "" +#~ "Температура екструдеру для шарів після першого. Установіть 0, щоб " +#~ "вимкнути команди керування температурою на виході." + +#~ msgid "" +#~ "This custom code is inserted right before every extruder change. Note " +#~ "that you can use placeholder variables for all Slic3r settings as well as " +#~ "[previous_extruder] and [next_extruder]." +#~ msgstr "" +#~ "Цей спеціальний код вставляється безпосередньо перед кожною зміненою " +#~ "екструдера. Зверніть увагу, що ви можете використовувати змінні-" +#~ "заповнювачі для всіх параметрів Slic3r, а також [previous_extruder] і " +#~ "[next_extruder]." diff --git a/resources/profiles/Anycubic.idx b/resources/profiles/Anycubic.idx index 062a0ec00d..b57fe3e660 100644 --- a/resources/profiles/Anycubic.idx +++ b/resources/profiles/Anycubic.idx @@ -1,8 +1,10 @@ min_slic3r_version = 2.3.0-beta2 +0.0.8 Updated start and end g-code for Anycubic Mega. +0.0.7 Updated start g-code for Anycubic Mega. 0.0.6 Reduced max print height for Predator. Updated end g-code, before layer change g-code and output filename format for Kossel. 0.0.5 Updated end g-code. min_slic3r_version = 2.3.0-alpha2 -0.0.4 Fixed predator output filaname format, infill overlap. +0.0.4 Fixed predator output filename format, infill overlap, start gcode adjustments. 0.0.3 Fixed infill_overlap, start_gcode, end_gcode for Anycubic Predator 0.0.2 Added Anycubic Predator min_slic3r_version = 2.3.0-alpha0 diff --git a/resources/profiles/Anycubic.ini b/resources/profiles/Anycubic.ini index 399495d230..639d5df475 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.0.6 +config_version = 0.0.8 # 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% @@ -1051,7 +1051,7 @@ before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z] default_filament_profile = Generic PLA @MEGA default_print_profile = 0.15mm QUALITY @MEGA deretract_speed = 50 -end_gcode = G4 ; wait\nG92 E0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} E-35 F1000 ; move print head up & retract filament\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors +end_gcode = G4 ; wait\nG92 E0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors extruder_colour = #808080 gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] @@ -1063,7 +1063,7 @@ retract_length = 6 retract_lift = 0.075 retract_lift_below = 204 silent_mode = 0 -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y0 Z1 F100 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0\nG1 E38 F1000; deretract filament\nG92 E0\nG1 X60 Z0 E9 ; intro line\nG1 X100 E12.5 ; intro line\nG92 E0 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG1 Y0 Z1 F100 ; move print head up\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0\nG1 Z0.2 F360\nG1 X60 E9 F700 ; intro line\nG1 X100 E12.5 F700 ; intro line\nG92 E0 use_relative_e_distances = 1 wipe = 1 machine_max_acceleration_e = 5000 diff --git a/resources/profiles/Artillery.idx b/resources/profiles/Artillery.idx new file mode 100644 index 0000000000..eca18b8b44 --- /dev/null +++ b/resources/profiles/Artillery.idx @@ -0,0 +1,2 @@ +min_slic3r_version = 2.3.0 +0.0.1 Initial Artillery bundle diff --git a/resources/profiles/Artillery.ini b/resources/profiles/Artillery.ini new file mode 100644 index 0000000000..5d4a26974d --- /dev/null +++ b/resources/profiles/Artillery.ini @@ -0,0 +1,477 @@ +############### +# AUTHOR: Szabolcs Hornyak / design85@gmail.com +# https://szabolcs.eu/2020/12/29/prusaslicer-sw-x1-genius/ +# Tested with PrusaSlicer 2.2, 2.3 +############### + +# Print profiles for the Artillery printers. + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Artillery +# 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.0.1 +# Where to get the updates from? +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Artillery/ +# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + +############# +## PRINTER ## +############# + +[printer_model:X1] +name = Sidewinder X1 +variants = 0.4 +technology = FFF +bed_model = bed-x1.stl +bed_texture = bed-x1.png +default_materials = Generic PLA @Artillery; Generic ABS @Artillery; Generic PETG @Artillery; Generic TPU @Artillery + +[printer_model:Genius] +name = Genius +variants = 0.4 +technology = FFF +bed_model = bed-genius.stl +bed_texture = bed-genius.png +default_materials = Generic PLA @Artillery; Generic ABS @Artillery; Generic PETG @Artillery; Generic TPU @Artillery + +# Common printer preset +[printer:*common*] +before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0 +between_objects_gcode = +cooling_tube_length = 5 +cooling_tube_retraction = 91.5 +default_filament_profile = Generic PLA @Artillery +default_print_profile = 0.20mm NORMAL @Artillery +deretract_speed = 0 +extruder_colour = #FFFF00 +extruder_offset = 0x0 +gcode_flavor = marlin +layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] +machine_max_acceleration_e = 5000,5000 +machine_max_acceleration_extruding = 1250,1250 +machine_max_acceleration_retracting = 1250,1250 +machine_max_acceleration_x = 1000,960 +machine_max_acceleration_y = 1000,960 +machine_max_acceleration_z = 1000,1000 +machine_max_feedrate_e = 120,120 +machine_max_feedrate_x = 200,100 +machine_max_feedrate_y = 200,100 +machine_max_feedrate_z = 12,12 +machine_max_jerk_e = 1.5,1.5 +machine_max_jerk_x = 8,8 +machine_max_jerk_y = 8,8 +machine_max_jerk_z = 0.4,0.4 +machine_min_extruding_rate = 0,0 +machine_min_travel_rate = 0,0 +max_layer_height = 0.25 +max_print_height = 250 +min_layer_height = 0.07 +nozzle_diameter = 0.4 +pause_print_gcode = +printer_technology = FFF +remaining_times = 0 +retract_before_travel = 1 +retract_before_wipe = 0% +retract_layer_change = 1 +retract_length = 1.9 +retract_length_toolchange = 4 +retract_lift = 0.6 +retract_lift_above = 0 +retract_lift_below = 380 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 35 +silent_mode = 0 +single_extruder_multi_material = 0 +toolchange_gcode = +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 1 +z_offset = 0 +end_gcode = G4 ; wait\nG92 E0 ; prepare to retract\nG1 E-0.5 F3000; retract to avoid stringing\n\n; Anti-stringing end wiggle\nG91 ; use relative coordinates\nG1 X1 Y1 F1200\n\n; Raise nozzle and present bed\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+120, max_print_height)}{endif} ; Move print head up\nG90 ; use absolute coordinates\n\n; Reset print setting overrides\nM200 D0 ; disable volumetric e\nM220 S100 ; reset speed factor to 100%\nM221 S100 ; reset extrusion rate to 100%\n\n; Shut down printer\nM106 S0 ; turn-off fan\nM104 S0 ; turn-off hotend\nM140 S0 ; turn-off bed\nM150 P0 ; turn off led\nM85 S0 ; deactivate idle timeout\nM84 ; disable motors\n + +[printer:*common_STOCK_FW*] +inherits = *common* +start_gcode = ; Initial setups\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM900 W[extrusion_width] H[layer_height] D[filament_diameter]\nM200 D0 ; disable volumetric e\nM220 S100 ; reset speed factor to 100%\nM221 S100 ; reset extrusion rate to 100%\n\n; Set the heating\nM190 S[first_layer_bed_temperature]; wait for bed to heat up\nM104 S[first_layer_temperature]; start nozzle heating but don't wait\n\n; Home\nG1 Z3 F3000 ; move z up little to prevent scratching of surface\nG28 ; home all axes\nG1 X3 Y3 F5000 ; move to corner of the bed to avoid ooze over centre\n\n; Wait for final heating\nM109 S[first_layer_temperature] ; wait for the nozzle to heat up\nM190 S[first_layer_bed_temperature] ; wait for the bed to heat up\n\n; Return to prime position, Prime line routine\nG92 E0 ; Reset Extruder\nG1 Z3 F3000 ; move z up little to prevent scratching of surface\nG1 X10 Y.5 Z0.25 F5000.0 ; Move to start position\nG1 X100 Y.5 Z0.25 F1500.0 E15 ; Draw the first line\nG1 X100 Y.2 Z0.25 F5000.0 ; Move to side a little\nG1 X10 Y.2 Z0.25 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nM221 S{if layer_height<0.075}100{else}95{endif} + +[printer:*common_UPD_FW*] +inherits = *common* +start_gcode = ; Initial setups\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM900 K0.12; K factor\nM900 W[extrusion_width] H[layer_height] D[filament_diameter]\nM200 D0 ; disable volumetric e\nM220 S100 ; reset speed factor to 100%\nM221 S100 ; reset extrusion rate to 100%\n\n; Set the heating\nM190 S[first_layer_bed_temperature]; wait for bed to heat up\nM104 S[first_layer_temperature]; start nozzle heating but don't wait\n\n; Home\nG1 Z3 F3000 ; move z up little to prevent scratching of surface\nG28 ; home all axes\nG1 X3 Y3 F5000 ; move to corner of the bed to avoid ooze over centre\n\n; Wait for final heating\nM109 S[first_layer_temperature] ; wait for the nozzle to heat up\nM190 S[first_layer_bed_temperature] ; wait for the bed to heat up\n\n;Auto bed Leveling\n@BEDLEVELVISUALIZER\nG29 ; ABL T\nM420 S1 Z3 ; reload and fade mesh bed leveling until it reach 3mm Z\n\n; Return to prime position, Prime line routine\nG92 E0 ; Reset Extruder\nG1 Z3 F3000 ; move z up little to prevent scratching of surface\nG1 X10 Y.5 Z0.25 F5000.0 ; Move to start position\nG1 X100 Y.5 Z0.25 F1500.0 E15 ; Draw the first line\nG1 X100 Y.2 Z0.25 F5000.0 ; Move to side a little\nG1 X10 Y.2 Z0.25 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nM221 S{if layer_height<0.075}100{else}95{endif} + +[printer:Sidewinder X1] +inherits = *common_STOCK_FW* +printer_model = X1 +printer_variant = 0.4 +bed_shape = 0x0,300x0,300x300,0x300 +max_print_height = 400 +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_Artillery\nPRINTER_MODEL_X1 + +[printer:Sidewinder X1 BL-TOUCH] +inherits = *common_UPD_FW* +printer_model = X1 +printer_variant = 0.4 +bed_shape = 0x0,300x0,300x300,0x300 +max_print_height = 400 +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_Artillery\nPRINTER_MODEL_X1 + +[printer:Genius] +inherits = *common_STOCK_FW* +printer_model = Genius +printer_variant = 0.4 +bed_shape = 0x0,230x0,230x230,0x230 +max_print_height = 250 +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_Artillery\nPRINTER_MODEL_Genius + +[printer:Genius BL-TOUCH] +inherits = *common_UPD_FW* +printer_model = Genius +printer_variant = 0.4 +bed_shape = 0x0,230x0,230x230,0x230 +max_print_height = 250 +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_Artillery\nPRINTER_MODEL_Genius + +########### +## PRINT ## +########### +# Common print preset +[print:*common*] +# V2.2 # +#bottom_fill_pattern = rectilinear +#top_fill_pattern = rectilinear +#fill_pattern = cubic +# V2.3 # +top_fill_pattern = monotonic +bottom_fill_pattern = monotonic +fill_pattern = adaptivecubic + +avoid_crossing_perimeters = 0 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_flow_ratio = 0.78 +bridge_speed = 20 +# brim_width = 5 +bottom_solid_min_thickness = 1.2 +clip_multipart_objects = 1 +compatible_printers = +complete_objects = 0 +default_acceleration = 1000 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 25 +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 25 +extruder_clearance_radius = 45 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 15% +first_layer_acceleration = 500 +first_layer_extrusion_width = 0.42 +first_layer_height = 150% +first_layer_speed = 20 +gap_fill_speed = 30 +gcode_comments = 1 +gcode_label_objects = 1 +infill_acceleration = 1000 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 50 +interface_shells = 0 +max_print_speed = 150 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +overhangs = 1 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +perimeters = 3 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0 +perimeter_speed = 45 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +single_extruder_multi_material_priming = 0 +skirts = 1 +skirt_distance = 6 +skirt_height = 1 +small_perimeter_speed = 25 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 50 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_extruder = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_enforce_layers = 0 +support_material_contact_distance = 0.15 +support_material_interface_contact_loops = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_synchronize_layers = 0 +support_material_threshold = 55 +support_material_with_sheath = 0 +support_material_xy_spacing = 50% +thin_walls = 1 +travel_speed = 130 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 30 +wipe_tower = 0 +wipe_tower_bridging = 10 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 170 +wipe_tower_y = 125 +xy_size_compensation = 0 + +[print:*0.08mm*] +inherits = *common* +default_acceleration = 500 +layer_height = 0.08 +perimeters = 3 +bottom_solid_layers = 9 +top_solid_layers = 11 + +[print:*0.10mm*] +inherits = *common* +default_acceleration = 500 +layer_height = 0.1 +perimeters = 3 +bottom_solid_layers = 7 +top_solid_layers = 9 + +[print:*0.12mm*] +inherits = *common* +default_acceleration = 500 +layer_height = 0.12 +perimeters = 3 +bottom_solid_layers = 6 +top_solid_layers = 7 + +[print:*0.16mm*] +inherits = *common* +layer_height = 0.16 +bottom_solid_layers = 5 +top_solid_layers = 7 + +[print:*0.20mm*] +inherits = *common* +layer_height = 0.20 +bottom_solid_layers = 4 +top_solid_layers = 5 + +[print:*0.24mm*] +inherits = *common* +layer_height = 0.24 +top_infill_extrusion_width = 0.45 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.28mm*] +inherits = *common* +layer_height = 0.28 +top_infill_extrusion_width = 0.45 +first_layer_extrusion_width = 0.75 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:0.08mm SUPERDETAIL @Artillery] +inherits = *0.08mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.10mm HIGHDETAIL @Artillery] +inherits = *0.10mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.12mm DETAIL @Artillery] +inherits = *0.12mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.16mm OPTIMAL @Artillery] +inherits = *0.16mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.20mm SLOW @Artillery] +inherits = *0.20mm* +external_perimeter_speed = 15 +fill_density = 20% +gap_fill_speed = 25 +infill_speed = 50 +perimeter_speed = 30 +perimeters = 3 +solid_infill_speed = 50 +top_solid_infill_speed = 25 +first_layer_speed = 15 +travel_speed = 100 +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.20mm NORMAL @Artillery] +inherits = *0.20mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.20mm SPEED @Artillery] +inherits = *0.20mm* +external_perimeter_speed = 35 +fill_density = 15% +fill_pattern = grid +gap_fill_speed = 45 +infill_speed = 150 +infill_only_where_needed = 1 +perimeter_speed = 60 +perimeters = 2 +solid_infill_speed = 150 +top_solid_infill_speed = 50 +travel_speed = 170 +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.24mm DRAFT @Artillery] +inherits = *0.24mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +[print:0.28mm SUPERDRAFT @Artillery] +inherits = *0.28mm* +compatible_printers_condition = printer_model=~/(X1|Genius).*/ and nozzle_diameter[0]==0.4 + +############### +## FILAMENTS ## +############### + +# Common filament preset +[filament:*common*] +cooling = 1 +compatible_printers = +extrusion_multiplier = 1 +filament_cost = 0 +filament_density = 0 +filament_diameter = 1.75 +filament_notes = "" +filament_settings_id = "" +filament_soluble = 0 +min_print_speed = 15 +slowdown_below_layer_time = 15 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_Artillery.*/ + +[filament:*PLA*] +inherits = *common* +bed_temperature = 60 +bridge_fan_speed = 100 +cooling = 1 +disable_fan_first_layers = 1 +fan_always_on = 1 +fan_below_layer_time = 100 +filament_colour = #428AF5 +filament_cost = 20 +filament_density = 1.24 +filament_max_volumetric_speed = 15 +filament_type = PLA +first_layer_bed_temperature = 65 +first_layer_temperature = 210 +full_fan_speed_layer = 3 +max_fan_speed = 100 +min_fan_speed = 100 +temperature = 205 + +[filament:*PET*] +inherits = *common* +bed_temperature = 70 +bridge_fan_speed = 100 +cooling = 1 +disable_fan_first_layers = 3 +fan_always_on = 1 +fan_below_layer_time = 20 +filament_colour = #42E9F5 +filament_cost = 30 +filament_density = 1.27 +filament_max_volumetric_speed = 8 +filament_type = PETG +first_layer_bed_temperature = 70 +first_layer_temperature = 235 +max_fan_speed = 50 +min_fan_speed = 20 +temperature = 230 + +[filament:*ABS*] +inherits = *common* +bed_temperature = 90 +bridge_fan_speed = 30 +cooling = 0 +disable_fan_first_layers = 3 +fan_always_on = 0 +fan_below_layer_time = 20 +filament_colour = #6603FC +filament_cost = 20 +filament_density = 1.04 +filament_max_volumetric_speed = 11 +filament_type = ABS +first_layer_bed_temperature = 90 +first_layer_temperature = 240 +max_fan_speed = 0 +min_fan_speed = 0 +temperature = 240 +top_fan_speed = 0 + +[filament:*TPU*] +inherits = *common* +bed_temperature = 55 +cooling = 0 +disable_fan_first_layers = 3 +fan_always_on = 0 +fan_below_layer_time = 20 +filament_colour = #CFFFFB +filament_cost = 30 +filament_density = 1.2 +filament_max_volumetric_speed = 11 +filament_retract_before_travel = 4 +filament_retract_length = 2.5 +filament_retract_speed = 30 +filament_type = TPU +first_layer_bed_temperature = 55 +first_layer_temperature = 210 +max_fan_speed = 70 +min_fan_speed = 0 + +[filament:Generic PLA @Artillery] +inherits = *PLA* +filament_vendor = Generic + +[filament:Generic PETG @Artillery] +inherits = *PET* +filament_vendor = Generic + +[filament:Generic ABS @Artillery] +inherits = *ABS* +filament_vendor = Generic + +[filament:Generic TPU @Artillery] +inherits = *TPU* +filament_vendor = Generic \ No newline at end of file diff --git a/resources/profiles/Artillery/bed-genius.png b/resources/profiles/Artillery/bed-genius.png new file mode 100644 index 0000000000..bcf2e85eb4 Binary files /dev/null and b/resources/profiles/Artillery/bed-genius.png differ diff --git a/resources/profiles/Artillery/bed-genius.stl b/resources/profiles/Artillery/bed-genius.stl new file mode 100644 index 0000000000..69cf15555e Binary files /dev/null and b/resources/profiles/Artillery/bed-genius.stl differ diff --git a/resources/profiles/Artillery/bed-x1.png b/resources/profiles/Artillery/bed-x1.png new file mode 100644 index 0000000000..16062e93c1 Binary files /dev/null and b/resources/profiles/Artillery/bed-x1.png differ diff --git a/resources/profiles/Artillery/bed-x1.stl b/resources/profiles/Artillery/bed-x1.stl new file mode 100644 index 0000000000..6e6ebe94e0 Binary files /dev/null and b/resources/profiles/Artillery/bed-x1.stl differ diff --git a/resources/profiles/Artillery/genius_thumbnail.png b/resources/profiles/Artillery/genius_thumbnail.png new file mode 100644 index 0000000000..227f7ca8a5 Binary files /dev/null and b/resources/profiles/Artillery/genius_thumbnail.png differ diff --git a/resources/profiles/Artillery/x1_thumbnail.png b/resources/profiles/Artillery/x1_thumbnail.png new file mode 100644 index 0000000000..4aa3a0dccc Binary files /dev/null and b/resources/profiles/Artillery/x1_thumbnail.png differ diff --git a/resources/profiles/Creality.idx b/resources/profiles/Creality.idx index 78d67e4ede..328ae4cf33 100644 --- a/resources/profiles/Creality.idx +++ b/resources/profiles/Creality.idx @@ -1,4 +1,5 @@ min_slic3r_version = 2.3.0-rc2 +0.0.14 Optimized start g-code. Added filament profile. Various improvements. 0.0.13 Optimized start and end g-code. General improvements. 0.0.12 Added Ender-3V2 and filament profiles. min_slic3r_version = 2.3.0-beta2 diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini index 68a1015046..1426ee5963 100644 --- a/resources/profiles/Creality.ini +++ b/resources/profiles/Creality.ini @@ -5,7 +5,7 @@ name = Creality # 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.0.13 +config_version = 0.0.14 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/ # changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -23,15 +23,6 @@ bed_model = ender3_bed.stl bed_texture = ender3.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY -[printer_model:ENDER3V2] -name = Creality Ender-3 V2 -variants = 0.4 -technology = FFF -family = ENDER -bed_model = ender3_bed.stl -bed_texture = ender3.svg -default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY - [printer_model:ENDER3BLTOUCH] name = Creality Ender-3 BLTouch variants = 0.4 @@ -41,6 +32,33 @@ bed_model = ender3_bed.stl bed_texture = ender3.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY +[printer_model:ENDER3V2] +name = Creality Ender-3 V2 +variants = 0.4 +technology = FFF +family = ENDER +bed_model = ender3v2_bed.stl +bed_texture = ender3v2.svg +default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + +#[printer_model:ENDER3MAX] +#name = Creality Ender-3 Max +#variants = 0.4 +#technology = FFF +#family = ENDER +#bed_model = cr10v2_bed.stl +#bed_texture = cr10spro.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + +#[printer_model:ENDER4] +#name = Creality Ender-4 +#variants = 0.4 +#technology = FFF +#family = ENDER +#bed_model = ender3v2_bed.stl +#bed_texture = ender3v2.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + [printer_model:ENDER5] name = Creality Ender-5 variants = 0.4 @@ -59,6 +77,15 @@ bed_model = ender5plus_bed.stl bed_texture = ender5plus.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY +#[printer_model:ENDER6] +#name = Creality Ender-6 +#variants = 0.4 +#technology = FFF +#family = ENDER +#bed_model = ender6_bed.stl +#bed_texture = ender6.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + [printer_model:ENDER2] name = Creality Ender-2 variants = 0.4 @@ -73,8 +100,17 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @ #variants = 0.4 #technology = FFF #family = CR -#bed_model = ender3_bed.stl -#bed_texture = cr20.svg +#bed_model = cr6se_bed.stl +#bed_texture = cr6se.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + +#[printer_model:CR6MAX] +#name = Creality CR-6 Max +#variants = 0.4 +#technology = FFF +#family = CR +#bed_model = cr10s4_bed.stl +#bed_texture = cr10s4.svg #default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY [printer_model:CR10MINI] @@ -86,6 +122,15 @@ bed_model = cr10mini_bed.stl bed_texture = cr10mini.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY +#[printer_model:CR10MAX] +#name = Creality CR-10 Max +#variants = 0.4 +#technology = FFF +#family = CR +#bed_model = cr10max_bed.stl +#bed_texture = cr10max.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + [printer_model:CR10] name = Creality CR-10 variants = 0.4 @@ -128,7 +173,7 @@ variants = 0.4 technology = FFF family = CR bed_model = cr10v2_bed.stl -bed_texture = cr10.svg +bed_texture = cr10spro.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY [printer_model:CR10SPROV2] @@ -176,6 +221,33 @@ bed_model = ender3_bed.stl bed_texture = cr20.svg default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY +#[printer_model:CR8] +#name = Creality CR-8 +#variants = 0.4 +#technology = FFF +#family = CR +#bed_model = cr8_bed.stl +#bed_texture = cr8.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + +#[printer_model:CRX] +#name = Creality CR-X +#variants = 0.4 +#technology = FFF +#family = CR-X +#bed_model = cr10v2_bed.stl +#bed_texture = cr10spro.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + +#[printer_model:CRXPRO] +#name = Creality CR-X Pro +#variants = 0.4 +#technology = FFF +#family = CR-X +#bed_model = cr10v2_bed.stl +#bed_texture = cr10spro.svg +#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY + # All presets starting with asterisk, for example *common*, are intermediate and they will # not make it into the user interface. @@ -556,6 +628,17 @@ filament_density = 1.3 filament_colour = #3C4547 filament_spool_weight = 256 +[filament:Extrudr GreenTEC Pro @CREALITY] +inherits = *PLA* +filament_vendor = Extrudr +temperature = 210 +bed_temperature = 60 +first_layer_temperature = 215 +first_layer_bed_temperature = 60 +filament_cost = 56.24 +filament_density = 1.35 +filament_colour = #3C4547 + [filament:Real Filament PLA @CREALITY] inherits = *PLA* filament_vendor = Real Filament @@ -610,6 +693,7 @@ first_layer_temperature = 215 first_layer_bed_temperature = 60 filament_cost = 20.56 filament_density = 1.24 +filament_colour = #C7F935 [filament:Das Filament PETG @CREALITY] inherits = *PET* @@ -620,6 +704,7 @@ first_layer_temperature = 240 first_layer_bed_temperature = 70 filament_cost = 27.44 filament_density = 1.29 +filament_colour = #C7F935 # Common printer preset [printer:*common*] @@ -628,7 +713,7 @@ before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n between_objects_gcode = pause_print_gcode = deretract_speed = 0 -extruder_colour = #FFFF00 +extruder_colour = #FCE94F extruder_offset = 0x0 gcode_flavor = marlin silent_mode = 0 @@ -711,138 +796,208 @@ retract_length = 5 retract_speed = 60 deretract_speed = 40 retract_before_wipe = 70% -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG4 S10 ; wait for partial warmup\nG28 ; home all\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; intro line\nG92 E0 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors -[printer:Creality Ender-3 V2] -inherits = Creality Ender-3 -renamed_from = "Creality Ender-3V2" -printer_model = ENDER3V2 -bed_shape = 0x0,220x0,220x220,0x220 - # Intended for printers with a smaller bed, like the Ender-3 series [printer:*fastabl*] -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG4 S10 ; wait for partial warmup\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; intro line\nG92 E0 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 # Intended for printers with a larger bed, like the CR-10 series [printer:*slowabl*] -start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; intro line\nG92 E0 +start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nG28 ; home all axis\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0 + +# Intended for printers with vendor official firmware verified to support M25 +[printer:*pauseprint*] +pause_print_gcode = M25 ; pause print # Intended for printers where the Z-axis lowers the print bed during printing, like the Ender-5 series -[printer:*invertedz*] -end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down further down\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors +[printer:*descendingz*] +renamed_from = "*invertedz*" +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; move print head out of the way\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed close to the bottom\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +# Intended for printers with dual extruders and a single hotend/nozzle, like the CR-X series +[printer:*dualextruder*] +single_extruder_multi_material = 1 +cooling_tube_length = 5 +cooling_tube_retraction = 91.5 +extra_loading_move = -2 +parking_pos_retraction = 92 +deretract_speed = 40,40 +extruder_colour = #FCE94F;#729FCF +extruder_offset = 0x0,0x0 +max_layer_height = 0.28,0.28 +min_layer_height = 0.08,0.08 +nozzle_diameter = 0.4,0.4 +retract_before_travel = 2,2 +retract_before_wipe = 70%,70% +retract_layer_change = 1,1 +retract_length = 5,5 +retract_length_toolchange = 1,1 +retract_lift = 0,0 +retract_lift_above = 0,0 +retract_lift_below = 0,0 +retract_restart_extra = 0,0 +retract_restart_extra_toolchange = 0,0 +retract_speed = 60,60 +wipe = 1,1 [printer:Creality Ender-3 BLTouch] inherits = Creality Ender-3; *fastabl* renamed_from = "Creality ENDER-3 BLTouch" printer_model = ENDER3BLTOUCH +[printer:Creality Ender-3 V2] +inherits = Creality Ender-3 +renamed_from = "Creality Ender-3V2" +printer_model = ENDER3V2 +bed_shape = 5x0,215x0,215x220,5x220 + +#[printer:Creality Ender-3 Max] +#inherits = Creality Ender-3 +#retract_length = 6 +#bed_shape = 5x5,295x5,295x295,5x295 +#max_print_height = 340 +#printer_model = ENDER3MAX +#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_CREALITY\nPRINTER_MODEL_ENDER3MAX\nPRINTER_HAS_BOWDEN + +#[printer:Creality Ender-4] +#inherits = Creality Ender-3; *descendingz* +#bed_shape = 5x0,215x0,215x220,5x220 +#max_print_height = 300 +#printer_model = ENDER4 +#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_CREALITY\nPRINTER_MODEL_ENDER4\nPRINTER_HAS_BOWDEN + [printer:Creality Ender-5] -inherits = Creality Ender-3; *invertedz* +inherits = Creality Ender-3; *descendingz* retract_length = 6 bed_shape = 5x2.5,225x2.5,225x222.5,5x222.5 +max_print_height = 300 printer_model = ENDER5 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_CREALITY\nPRINTER_MODEL_ENDER5\nPRINTER_HAS_BOWDEN -max_print_height = 300 machine_max_acceleration_e = 1000 machine_max_feedrate_z = 5 [printer:Creality Ender-5 Plus] -inherits = Creality Ender-3; *slowabl*; *invertedz* +inherits = Creality Ender-3; *slowabl*; *descendingz* retract_length = 6 bed_shape = 5x5,355x5,355x355,5x355 +max_print_height = 400 printer_model = ENDER5PLUS 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_CREALITY\nPRINTER_MODEL_ENDER5PLUS\nPRINTER_HAS_BOWDEN -max_print_height = 400 machine_max_acceleration_e = 1000 machine_max_feedrate_z = 5 machine_max_feedrate_x = 300 machine_max_feedrate_y = 300 +#[printer:Creality Ender-6] +#inherits = Creality Ender-3; *descendingz* +#bed_shape = 5x5,255x5,255x255,5x255 +#max_print_height = 400 +#printer_model = ENDER6 +#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_CREALITY\nPRINTER_MODEL_ENDER6\nPRINTER_HAS_BOWDEN + [printer:Creality Ender-2] inherits = Creality Ender-3 renamed_from = "Creality ENDER-2" bed_shape = 0x0,150x0,150x150,0x150 +max_print_height = 200 printer_model = ENDER2 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_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN -max_print_height = 200 #[printer:Creality CR-6 SE] -#inherits = Creality Ender-3; *fastabl* +#inherits = Creality Ender-3; *fastabl*; *pauseprint* +#bed_shape = 5x0,230x0,230x235,5x235 #printer_model = CR6SE #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_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN +#[printer:Creality CR-6 Max] +#inherits = Creality Ender-3; *slowabl* +#retract_length = 6 +#bed_shape = 5x5,395x5,395x395,5x395 +#max_print_height = 400 +#printer_model = CR6MAX +#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_CREALITY\nPRINTER_MODEL_CR6MAX\nPRINTER_HAS_BOWDEN + [printer:Creality CR-10 Mini] inherits = Creality Ender-3 retract_length = 6 bed_shape = 2.5x5,2.5x225,302.5x225,302.5x5 +max_print_height = 300 printer_model = CR10MINI 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_CREALITY\nPRINTER_MODEL_CR10MINI\nPRINTER_HAS_BOWDEN -max_print_height = 300 + +#[printer:Creality CR-10 Max] +#inherits = Creality Ender-3; *slowabl* +#retract_length = 6 +#bed_shape = 5x5,445x5,445x445,5x445 +#max_print_height = 470 +#printer_model = CR10MAX +#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_CREALITY\nPRINTER_MODEL_CR10MAX\nPRINTER_HAS_BOWDEN [printer:Creality CR-10] inherits = Creality Ender-3 retract_length = 6 bed_shape = 5x5,305x5,305x305,5x305 +max_print_height = 400 printer_model = CR10 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_CREALITY\nPRINTER_MODEL_CR10\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 V2] inherits = Creality Ender-3 retract_length = 6 bed_shape = 5x5,305x5,305x305,5x305 +max_print_height = 400 printer_model = CR10V2 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_CREALITY\nPRINTER_MODEL_CR10V2\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 V3] inherits = Creality Ender-3 retract_length = 1 bed_shape = 5x5,305x5,305x305,5x305 +max_print_height = 400 printer_model = CR10V3 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_CREALITY\nPRINTER_MODEL_CR10V3 -max_print_height = 400 [printer:Creality CR-10 S] inherits = Creality Ender-3 retract_length = 6 bed_shape = 5x5,305x5,305x305,5x305 +max_print_height = 400 printer_model = CR10S 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_CREALITY\nPRINTER_MODEL_CR10S\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 S Pro] inherits = Creality Ender-3; *slowabl* retract_length = 6 -bed_shape = 0x0,300x0,300x300,0x300 +bed_shape = 5x5,295x5,295x295,5x295 +max_print_height = 400 printer_model = CR10SPRO 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_CREALITY\nPRINTER_MODEL_CR10SPRO\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 S Pro V2] inherits = Creality Ender-3; *slowabl* retract_length = 6 bed_shape = 5x5,305x5,305x305,5x305 +max_print_height = 400 printer_model = CR10SPROV2 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_CREALITY\nPRINTER_MODEL_CR10SPROV2\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 S4] inherits = Creality Ender-3 retract_length = 6 -bed_shape = 5x5,405x5,405x405,5x405 +bed_shape = 5x5,395x5,395x395,5x395 +max_print_height = 400 printer_model = CR10S4 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_CREALITY\nPRINTER_MODEL_CR10S4\nPRINTER_HAS_BOWDEN -max_print_height = 400 [printer:Creality CR-10 S5] inherits = Creality Ender-3 retract_length = 6 bed_shape = 5x5,505x5,505x505,5x505 +max_print_height = 500 printer_model = CR10S5 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_CREALITY\nPRINTER_MODEL_CR10S5\nPRINTER_HAS_BOWDEN -max_print_height = 500 [printer:Creality CR-20] inherits = Creality Ender-3 @@ -854,3 +1009,26 @@ inherits = Creality Ender-3; *fastabl* retract_length = 4 printer_model = CR20PRO 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_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN + +#[printer:Creality CR-8] +#inherits = Creality Ender-3 +#bed_shape = 5x5,215x5,215x215,5x215 +#max_print_height = 210 +#printer_model = CR8 +#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_CREALITY\nPRINTER_MODEL_CR8\nPRINTER_HAS_BOWDEN + +#[printer:Creality CR-X] +#inherits = Creality Ender-3; *dualextruder* +#retract_length = 6,6 +#bed_shape = 5x5,295x5,295x295,5x295 +#max_print_height = 400 +#printer_model = CRX +#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_CREALITY\nPRINTER_MODEL_CRX\nPRINTER_HAS_BOWDEN + +#[printer:Creality CR-X Pro] +#inherits = Creality Ender-3; *dualextruder*; *slowabl* +#retract_length = 6,6 +#bed_shape = 5x5,295x5,295x295,5x295 +#max_print_height = 400 +#printer_model = CRXPRO +#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_CREALITY\nPRINTER_MODEL_CRXPRO\nPRINTER_HAS_BOWDEN diff --git a/resources/profiles/Creality/CR10MAX_thumbnail.png b/resources/profiles/Creality/CR10MAX_thumbnail.png new file mode 100644 index 0000000000..d54104cc1c Binary files /dev/null and b/resources/profiles/Creality/CR10MAX_thumbnail.png differ diff --git a/resources/profiles/Creality/CR6MAX_thumbnail.png b/resources/profiles/Creality/CR6MAX_thumbnail.png new file mode 100644 index 0000000000..576ce9764a Binary files /dev/null and b/resources/profiles/Creality/CR6MAX_thumbnail.png differ diff --git a/resources/profiles/Creality/CR6SE_thumbnail.png b/resources/profiles/Creality/CR6SE_thumbnail.png index 9dd9d3324f..3ab5a3098a 100644 Binary files a/resources/profiles/Creality/CR6SE_thumbnail.png and b/resources/profiles/Creality/CR6SE_thumbnail.png differ diff --git a/resources/profiles/Creality/CR8_thumbnail.png b/resources/profiles/Creality/CR8_thumbnail.png new file mode 100644 index 0000000000..f698b9abf3 Binary files /dev/null and b/resources/profiles/Creality/CR8_thumbnail.png differ diff --git a/resources/profiles/Creality/CRXPRO_thumbnail.png b/resources/profiles/Creality/CRXPRO_thumbnail.png new file mode 100644 index 0000000000..61f9a5e419 Binary files /dev/null and b/resources/profiles/Creality/CRXPRO_thumbnail.png differ diff --git a/resources/profiles/Creality/CRX_thumbnail.png b/resources/profiles/Creality/CRX_thumbnail.png new file mode 100644 index 0000000000..d8834868ea Binary files /dev/null and b/resources/profiles/Creality/CRX_thumbnail.png differ diff --git a/resources/profiles/Creality/ENDER3MAX_thumbnail.png b/resources/profiles/Creality/ENDER3MAX_thumbnail.png new file mode 100644 index 0000000000..db6fcfab78 Binary files /dev/null and b/resources/profiles/Creality/ENDER3MAX_thumbnail.png differ diff --git a/resources/profiles/Creality/ENDER4_thumbnail.png b/resources/profiles/Creality/ENDER4_thumbnail.png new file mode 100644 index 0000000000..a4b4b6ab26 Binary files /dev/null and b/resources/profiles/Creality/ENDER4_thumbnail.png differ diff --git a/resources/profiles/Creality/ENDER6_thumbnail.png b/resources/profiles/Creality/ENDER6_thumbnail.png new file mode 100644 index 0000000000..af6c037578 Binary files /dev/null and b/resources/profiles/Creality/ENDER6_thumbnail.png differ diff --git a/resources/profiles/Creality/cr10max.svg b/resources/profiles/Creality/cr10max.svg new file mode 100644 index 0000000000..2a6ed9352f --- /dev/null +++ b/resources/profiles/Creality/cr10max.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/cr10max_bed.stl b/resources/profiles/Creality/cr10max_bed.stl new file mode 100644 index 0000000000..595e31d06d --- /dev/null +++ b/resources/profiles/Creality/cr10max_bed.stl @@ -0,0 +1,2774 @@ +solid OpenSCAD_Model + facet normal 0 0 -1 + outer loop + vertex 232.105 -234.998 -3 + vertex 232.002 -234.998 -3 + vertex 232.314 -234.984 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 232.314 -234.984 -3 + vertex 232.002 -234.998 -3 + vertex 232.521 -234.954 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 235 -232 -3 + vertex 232.002 -234.998 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 232.521 -234.954 -3 + vertex 232.002 -234.998 -3 + vertex 232.726 -234.911 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 232.726 -234.911 -3 + vertex 232.002 -234.998 -3 + vertex 232.927 -234.853 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 232.927 -234.853 -3 + vertex 232.002 -234.998 -3 + vertex 233.124 -234.782 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 233.124 -234.782 -3 + vertex 232.002 -234.998 -3 + vertex 233.315 -234.696 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 233.315 -234.696 -3 + vertex 232.002 -234.998 -3 + vertex 233.5 -234.598 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 233.5 -234.598 -3 + vertex 232.002 -234.998 -3 + vertex 233.678 -234.487 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 233.678 -234.487 -3 + vertex 232.002 -234.998 -3 + vertex 233.847 -234.364 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 233.847 -234.364 -3 + vertex 232.002 -234.998 -3 + vertex 234.007 -234.229 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.007 -234.229 -3 + vertex 232.002 -234.998 -3 + vertex 234.158 -234.084 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.158 -234.084 -3 + vertex 232.002 -234.998 -3 + vertex 234.298 -233.928 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.298 -233.928 -3 + vertex 232.002 -234.998 -3 + vertex 234.427 -233.763 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.427 -233.763 -3 + vertex 232.002 -234.998 -3 + vertex 234.544 -233.59 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.544 -233.59 -3 + vertex 232.002 -234.998 -3 + vertex 234.649 -233.408 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.649 -233.408 -3 + vertex 232.002 -234.998 -3 + vertex 234.741 -233.22 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.741 -233.22 -3 + vertex 232.002 -234.998 -3 + vertex 234.819 -233.026 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.819 -233.026 -3 + vertex 232.002 -234.998 -3 + vertex 234.884 -232.827 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.884 -232.827 -3 + vertex 232.002 -234.998 -3 + vertex 234.934 -232.624 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.934 -232.624 -3 + vertex 232.002 -234.998 -3 + vertex 234.971 -232.418 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.971 -232.418 -3 + vertex 232.002 -234.998 -3 + vertex 234.993 -232.209 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 234.993 -232.209 -3 + vertex 232.002 -234.998 -3 + vertex 235 -232 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 235 -232 -3 + vertex 232.002 234.998 -3 + vertex 235 232 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 234.998 -3 + vertex 234.971 232.418 -3 + vertex 234.993 232.209 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 234.884 232.827 -3 + vertex 234.934 232.624 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 234.741 233.22 -3 + vertex 232.002 234.998 -3 + vertex 234.649 233.408 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 234.741 233.22 -3 + vertex 234.819 233.026 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 234.998 -3 + vertex 234.007 234.229 -3 + vertex 234.158 234.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 234.427 233.763 -3 + vertex 232.002 234.998 -3 + vertex 234.298 233.928 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 234.427 233.763 -3 + vertex 234.544 233.59 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 234.298 233.928 -3 + vertex 232.002 234.998 -3 + vertex 234.158 234.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 234.998 -3 + vertex 232.927 234.853 -3 + vertex 233.124 234.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 233.847 234.364 -3 + vertex 232.002 234.998 -3 + vertex 233.678 234.487 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 233.847 234.364 -3 + vertex 234.007 234.229 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 233.678 234.487 -3 + vertex 232.002 234.998 -3 + vertex 233.5 234.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 233.5 234.598 -3 + vertex 232.002 234.998 -3 + vertex 233.315 234.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 233.315 234.696 -3 + vertex 232.002 234.998 -3 + vertex 233.124 234.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 234.649 233.408 -3 + vertex 232.002 234.998 -3 + vertex 234.544 233.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.726 234.911 -3 + vertex 232.002 234.998 -3 + vertex 232.521 234.954 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 232.726 234.911 -3 + vertex 232.927 234.853 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 234.819 233.026 -3 + vertex 234.884 232.827 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 232.314 234.984 -3 + vertex 232.521 234.954 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 234.998 -3 + vertex 234.934 232.624 -3 + vertex 234.971 232.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 234.998 -3 + vertex 232.105 234.998 -3 + vertex 232.314 234.984 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 235 232 -3 + vertex 232.002 234.998 -3 + vertex 234.993 232.209 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -232 235 -3 + vertex 232 235 -3 + vertex -232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex 232 235 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 -234.998 -3 + vertex -232.002 234.998 -3 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -235 -232 -3 + vertex -235 232 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -232.314 234.984 -3 + vertex -232.105 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -232.521 234.954 -3 + vertex -232.314 234.984 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -232.726 234.911 -3 + vertex -232.521 234.954 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -232.927 234.853 -3 + vertex -232.726 234.911 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -233.124 234.782 -3 + vertex -232.927 234.853 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -233.315 234.696 -3 + vertex -233.124 234.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -233.5 234.598 -3 + vertex -233.315 234.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -233.678 234.487 -3 + vertex -233.5 234.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -233.847 234.364 -3 + vertex -233.678 234.487 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.007 234.229 -3 + vertex -233.847 234.364 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.158 234.084 -3 + vertex -234.007 234.229 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.298 233.928 -3 + vertex -234.158 234.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.427 233.763 -3 + vertex -234.298 233.928 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.544 233.59 -3 + vertex -234.427 233.763 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.649 233.408 -3 + vertex -234.544 233.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.741 233.22 -3 + vertex -234.649 233.408 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.819 233.026 -3 + vertex -234.741 233.22 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.884 232.827 -3 + vertex -234.819 233.026 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.934 232.624 -3 + vertex -234.884 232.827 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.971 232.418 -3 + vertex -234.934 232.624 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -234.993 232.209 -3 + vertex -234.971 232.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 234.998 -3 + vertex -235 232 -3 + vertex -234.993 232.209 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -235 232 -3 + vertex -232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 232.002 -234.998 -3 + vertex -232.002 -234.998 -3 + vertex -232.002 234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -234.971 -232.418 -3 + vertex -234.993 -232.209 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.884 -232.827 -3 + vertex -234.934 -232.624 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.741 -233.22 -3 + vertex -232.002 -234.998 -3 + vertex -234.649 -233.408 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.741 -233.22 -3 + vertex -234.819 -233.026 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -234.007 -234.229 -3 + vertex -234.158 -234.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.427 -233.763 -3 + vertex -232.002 -234.998 -3 + vertex -234.298 -233.928 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.427 -233.763 -3 + vertex -234.544 -233.59 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.298 -233.928 -3 + vertex -232.002 -234.998 -3 + vertex -234.158 -234.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -232.927 -234.853 -3 + vertex -233.124 -234.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -233.847 -234.364 -3 + vertex -232.002 -234.998 -3 + vertex -233.678 -234.487 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -233.847 -234.364 -3 + vertex -234.007 -234.229 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -233.678 -234.487 -3 + vertex -232.002 -234.998 -3 + vertex -233.5 -234.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -233.5 -234.598 -3 + vertex -232.002 -234.998 -3 + vertex -233.315 -234.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -233.315 -234.696 -3 + vertex -232.002 -234.998 -3 + vertex -233.124 -234.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.649 -233.408 -3 + vertex -232.002 -234.998 -3 + vertex -234.544 -233.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.726 -234.911 -3 + vertex -232.002 -234.998 -3 + vertex -232.521 -234.954 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.726 -234.911 -3 + vertex -232.927 -234.853 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -234.819 -233.026 -3 + vertex -234.884 -232.827 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.314 -234.984 -3 + vertex -232.521 -234.954 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -234.934 -232.624 -3 + vertex -234.971 -232.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex -232.105 -234.998 -3 + vertex -232.314 -234.984 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 232.002 -234.998 -3 + vertex 232 -235 -3 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -232.002 -234.998 -3 + vertex 232 -235 -3 + vertex -232 -235 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -235 -232 -3 + vertex -232.002 -234.998 -3 + vertex -234.993 -232.209 -3 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.314 -234.984 0 + vertex 232.002 -234.998 0 + vertex 232.105 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.521 -234.954 0 + vertex 232.002 -234.998 0 + vertex 232.314 -234.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 232.002 -234.998 0 + vertex 235 -232 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.726 -234.911 0 + vertex 232.002 -234.998 0 + vertex 232.521 -234.954 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.927 -234.853 0 + vertex 232.002 -234.998 0 + vertex 232.726 -234.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.124 -234.782 0 + vertex 232.002 -234.998 0 + vertex 232.927 -234.853 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.315 -234.696 0 + vertex 232.002 -234.998 0 + vertex 233.124 -234.782 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.5 -234.598 0 + vertex 232.002 -234.998 0 + vertex 233.315 -234.696 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.678 -234.487 0 + vertex 232.002 -234.998 0 + vertex 233.5 -234.598 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.847 -234.364 0 + vertex 232.002 -234.998 0 + vertex 233.678 -234.487 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.007 -234.229 0 + vertex 232.002 -234.998 0 + vertex 233.847 -234.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.158 -234.084 0 + vertex 232.002 -234.998 0 + vertex 234.007 -234.229 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.298 -233.928 0 + vertex 232.002 -234.998 0 + vertex 234.158 -234.084 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.427 -233.763 0 + vertex 232.002 -234.998 0 + vertex 234.298 -233.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.544 -233.59 0 + vertex 232.002 -234.998 0 + vertex 234.427 -233.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.649 -233.408 0 + vertex 232.002 -234.998 0 + vertex 234.544 -233.59 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.741 -233.22 0 + vertex 232.002 -234.998 0 + vertex 234.649 -233.408 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.819 -233.026 0 + vertex 232.002 -234.998 0 + vertex 234.741 -233.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.884 -232.827 0 + vertex 232.002 -234.998 0 + vertex 234.819 -233.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.934 -232.624 0 + vertex 232.002 -234.998 0 + vertex 234.884 -232.827 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.971 -232.418 0 + vertex 232.002 -234.998 0 + vertex 234.934 -232.624 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.993 -232.209 0 + vertex 232.002 -234.998 0 + vertex 234.971 -232.418 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 235 -232 0 + vertex 232.002 -234.998 0 + vertex 234.993 -232.209 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 235 232 0 + vertex 232.002 234.998 0 + vertex 235 -232 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.993 232.209 0 + vertex 234.971 232.418 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 234.934 232.624 0 + vertex 234.884 232.827 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.649 233.408 0 + vertex 232.002 234.998 0 + vertex 234.741 233.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 234.819 233.026 0 + vertex 234.741 233.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.158 234.084 0 + vertex 234.007 234.229 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.298 233.928 0 + vertex 232.002 234.998 0 + vertex 234.427 233.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 234.544 233.59 0 + vertex 234.427 233.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.158 234.084 0 + vertex 232.002 234.998 0 + vertex 234.298 233.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.124 234.782 0 + vertex 232.927 234.853 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.678 234.487 0 + vertex 232.002 234.998 0 + vertex 233.847 234.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 234.007 234.229 0 + vertex 233.847 234.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.5 234.598 0 + vertex 232.002 234.998 0 + vertex 233.678 234.487 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.315 234.696 0 + vertex 232.002 234.998 0 + vertex 233.5 234.598 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 233.124 234.782 0 + vertex 232.002 234.998 0 + vertex 233.315 234.696 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.544 233.59 0 + vertex 232.002 234.998 0 + vertex 234.649 233.408 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.521 234.954 0 + vertex 232.002 234.998 0 + vertex 232.726 234.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 232.927 234.853 0 + vertex 232.726 234.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 234.884 232.827 0 + vertex 234.819 233.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 232.521 234.954 0 + vertex 232.314 234.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.971 232.418 0 + vertex 234.934 232.624 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.314 234.984 0 + vertex 232.105 234.998 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 234.993 232.209 0 + vertex 232.002 234.998 0 + vertex 235 232 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 234.998 0 + vertex 232 235 0 + vertex -232 235 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex 232 235 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 232.002 234.998 0 + vertex -232.002 234.998 0 + vertex 232.002 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -235 232 0 + vertex -235 -232 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.105 234.998 0 + vertex -232.314 234.984 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.314 234.984 0 + vertex -232.521 234.954 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.521 234.954 0 + vertex -232.726 234.911 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.726 234.911 0 + vertex -232.927 234.853 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.927 234.853 0 + vertex -233.124 234.782 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -233.124 234.782 0 + vertex -233.315 234.696 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -233.315 234.696 0 + vertex -233.5 234.598 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -233.5 234.598 0 + vertex -233.678 234.487 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -233.678 234.487 0 + vertex -233.847 234.364 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -233.847 234.364 0 + vertex -234.007 234.229 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.007 234.229 0 + vertex -234.158 234.084 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.158 234.084 0 + vertex -234.298 233.928 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.298 233.928 0 + vertex -234.427 233.763 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.427 233.763 0 + vertex -234.544 233.59 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.544 233.59 0 + vertex -234.649 233.408 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.649 233.408 0 + vertex -234.741 233.22 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.741 233.22 0 + vertex -234.819 233.026 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.819 233.026 0 + vertex -234.884 232.827 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.884 232.827 0 + vertex -234.934 232.624 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.934 232.624 0 + vertex -234.971 232.418 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.971 232.418 0 + vertex -234.993 232.209 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -234.993 232.209 0 + vertex -235 232 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 234.998 0 + vertex -235 232 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 234.998 0 + vertex -232.002 -234.998 0 + vertex 232.002 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -234.993 -232.209 0 + vertex -234.971 -232.418 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -234.934 -232.624 0 + vertex -234.884 -232.827 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -234.649 -233.408 0 + vertex -232.002 -234.998 0 + vertex -234.741 -233.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -234.819 -233.026 0 + vertex -234.741 -233.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -234.158 -234.084 0 + vertex -234.007 -234.229 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -234.298 -233.928 0 + vertex -232.002 -234.998 0 + vertex -234.427 -233.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -234.544 -233.59 0 + vertex -234.427 -233.763 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -234.158 -234.084 0 + vertex -232.002 -234.998 0 + vertex -234.298 -233.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -233.124 -234.782 0 + vertex -232.927 -234.853 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -233.678 -234.487 0 + vertex -232.002 -234.998 0 + vertex -233.847 -234.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -234.007 -234.229 0 + vertex -233.847 -234.364 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -233.5 -234.598 0 + vertex -232.002 -234.998 0 + vertex -233.678 -234.487 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -233.315 -234.696 0 + vertex -232.002 -234.998 0 + vertex -233.5 -234.598 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -233.124 -234.782 0 + vertex -232.002 -234.998 0 + vertex -233.315 -234.696 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -234.544 -233.59 0 + vertex -232.002 -234.998 0 + vertex -234.649 -233.408 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -232.521 -234.954 0 + vertex -232.002 -234.998 0 + vertex -232.726 -234.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -232.927 -234.853 0 + vertex -232.726 -234.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -234.884 -232.827 0 + vertex -234.819 -233.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex -232.521 -234.954 0 + vertex -232.314 -234.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -234.971 -232.418 0 + vertex -234.934 -232.624 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -232.314 -234.984 0 + vertex -232.105 -234.998 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -232.002 -234.998 0 + vertex 232 -235 0 + vertex 232.002 -234.998 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -232 -235 0 + vertex 232 -235 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -234.993 -232.209 0 + vertex -232.002 -234.998 0 + vertex -235 -232 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 232.105 -234.998 -3 + vertex 232.002 -234.998 0 + vertex 232.002 -234.998 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 232.105 -234.998 -3 + vertex 232.105 -234.998 0 + vertex 232.002 -234.998 0 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 232.314 -234.984 -3 + vertex 232.105 -234.998 0 + vertex 232.105 -234.998 -3 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 232.314 -234.984 -3 + vertex 232.314 -234.984 0 + vertex 232.105 -234.998 0 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 232.521 -234.954 -3 + vertex 232.314 -234.984 0 + vertex 232.314 -234.984 -3 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 232.521 -234.954 -3 + vertex 232.521 -234.954 0 + vertex 232.314 -234.984 0 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 232.726 -234.911 -3 + vertex 232.521 -234.954 0 + vertex 232.521 -234.954 -3 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 232.726 -234.911 -3 + vertex 232.726 -234.911 0 + vertex 232.521 -234.954 0 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 232.927 -234.853 -3 + vertex 232.726 -234.911 0 + vertex 232.726 -234.911 -3 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 232.927 -234.853 -3 + vertex 232.927 -234.853 0 + vertex 232.726 -234.911 0 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 233.124 -234.782 -3 + vertex 232.927 -234.853 0 + vertex 232.927 -234.853 -3 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 233.124 -234.782 -3 + vertex 233.124 -234.782 0 + vertex 232.927 -234.853 0 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 233.315 -234.696 -3 + vertex 233.124 -234.782 0 + vertex 233.124 -234.782 -3 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 233.315 -234.696 -3 + vertex 233.315 -234.696 0 + vertex 233.124 -234.782 0 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 233.5 -234.598 -3 + vertex 233.315 -234.696 0 + vertex 233.315 -234.696 -3 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 233.5 -234.598 -3 + vertex 233.5 -234.598 0 + vertex 233.315 -234.696 0 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 233.678 -234.487 -3 + vertex 233.5 -234.598 0 + vertex 233.5 -234.598 -3 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 233.678 -234.487 -3 + vertex 233.678 -234.487 0 + vertex 233.5 -234.598 0 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 233.847 -234.364 -3 + vertex 233.678 -234.487 0 + vertex 233.678 -234.487 -3 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 233.847 -234.364 -3 + vertex 233.847 -234.364 0 + vertex 233.678 -234.487 0 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 234.007 -234.229 -3 + vertex 233.847 -234.364 0 + vertex 233.847 -234.364 -3 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 234.007 -234.229 -3 + vertex 234.007 -234.229 0 + vertex 233.847 -234.364 0 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 234.158 -234.084 -3 + vertex 234.007 -234.229 0 + vertex 234.007 -234.229 -3 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 234.158 -234.084 -3 + vertex 234.158 -234.084 0 + vertex 234.007 -234.229 0 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 234.298 -233.928 -3 + vertex 234.158 -234.084 0 + vertex 234.158 -234.084 -3 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 234.298 -233.928 -3 + vertex 234.298 -233.928 0 + vertex 234.158 -234.084 0 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 234.427 -233.763 -3 + vertex 234.298 -233.928 0 + vertex 234.298 -233.928 -3 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 234.427 -233.763 -3 + vertex 234.427 -233.763 0 + vertex 234.298 -233.928 0 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 234.544 -233.59 -3 + vertex 234.427 -233.763 0 + vertex 234.427 -233.763 -3 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 234.544 -233.59 -3 + vertex 234.544 -233.59 0 + vertex 234.427 -233.763 0 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 234.649 -233.408 -3 + vertex 234.544 -233.59 0 + vertex 234.544 -233.59 -3 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 234.649 -233.408 -3 + vertex 234.649 -233.408 0 + vertex 234.544 -233.59 0 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 234.741 -233.22 -3 + vertex 234.649 -233.408 0 + vertex 234.649 -233.408 -3 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 234.741 -233.22 -3 + vertex 234.741 -233.22 0 + vertex 234.649 -233.408 0 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 234.819 -233.026 -3 + vertex 234.741 -233.22 0 + vertex 234.741 -233.22 -3 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 234.819 -233.026 -3 + vertex 234.819 -233.026 0 + vertex 234.741 -233.22 0 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 234.884 -232.827 -3 + vertex 234.819 -233.026 0 + vertex 234.819 -233.026 -3 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 234.884 -232.827 -3 + vertex 234.884 -232.827 0 + vertex 234.819 -233.026 0 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 234.934 -232.624 -3 + vertex 234.884 -232.827 0 + vertex 234.884 -232.827 -3 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 234.934 -232.624 -3 + vertex 234.934 -232.624 0 + vertex 234.884 -232.827 0 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 234.971 -232.418 -3 + vertex 234.934 -232.624 0 + vertex 234.934 -232.624 -3 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 234.971 -232.418 -3 + vertex 234.971 -232.418 0 + vertex 234.934 -232.624 0 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 234.993 -232.209 -3 + vertex 234.971 -232.418 0 + vertex 234.971 -232.418 -3 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 234.993 -232.209 -3 + vertex 234.993 -232.209 0 + vertex 234.971 -232.418 0 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 235 -232 -3 + vertex 234.993 -232.209 0 + vertex 234.993 -232.209 -3 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 235 -232 -3 + vertex 235 -232 0 + vertex 234.993 -232.209 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 235 232 -3 + vertex 235 -232 0 + vertex 235 -232 -3 + endloop + endfacet + facet normal 1 0 -0 + outer loop + vertex 235 232 -3 + vertex 235 232 0 + vertex 235 -232 0 + endloop + endfacet + facet normal 0.99944 0.0334741 0 + outer loop + vertex 234.993 232.209 -3 + vertex 235 232 0 + vertex 235 232 -3 + endloop + endfacet + facet normal 0.99944 0.0334741 -0 + outer loop + vertex 234.993 232.209 -3 + vertex 234.993 232.209 0 + vertex 235 232 0 + endloop + endfacet + facet normal 0.994505 0.104685 0 + outer loop + vertex 234.971 232.418 -3 + vertex 234.993 232.209 0 + vertex 234.993 232.209 -3 + endloop + endfacet + facet normal 0.994505 0.104685 -0 + outer loop + vertex 234.971 232.418 -3 + vertex 234.971 232.418 0 + vertex 234.993 232.209 0 + endloop + endfacet + facet normal 0.98425 0.176783 0 + outer loop + vertex 234.934 232.624 -3 + vertex 234.971 232.418 0 + vertex 234.971 232.418 -3 + endloop + endfacet + facet normal 0.98425 0.176783 -0 + outer loop + vertex 234.934 232.624 -3 + vertex 234.934 232.624 0 + vertex 234.971 232.418 0 + endloop + endfacet + facet normal 0.970981 0.239158 0 + outer loop + vertex 234.884 232.827 -3 + vertex 234.934 232.624 0 + vertex 234.934 232.624 -3 + endloop + endfacet + facet normal 0.970981 0.239158 -0 + outer loop + vertex 234.884 232.827 -3 + vertex 234.884 232.827 0 + vertex 234.934 232.624 0 + endloop + endfacet + facet normal 0.950577 0.31049 0 + outer loop + vertex 234.819 233.026 -3 + vertex 234.884 232.827 0 + vertex 234.884 232.827 -3 + endloop + endfacet + facet normal 0.950577 0.31049 -0 + outer loop + vertex 234.819 233.026 -3 + vertex 234.819 233.026 0 + vertex 234.884 232.827 0 + endloop + endfacet + facet normal 0.927816 0.373039 0 + outer loop + vertex 234.741 233.22 -3 + vertex 234.819 233.026 0 + vertex 234.819 233.026 -3 + endloop + endfacet + facet normal 0.927816 0.373039 -0 + outer loop + vertex 234.741 233.22 -3 + vertex 234.741 233.22 0 + vertex 234.819 233.026 0 + endloop + endfacet + facet normal 0.898217 0.439553 0 + outer loop + vertex 234.649 233.408 -3 + vertex 234.741 233.22 0 + vertex 234.741 233.22 -3 + endloop + endfacet + facet normal 0.898217 0.439553 -0 + outer loop + vertex 234.649 233.408 -3 + vertex 234.649 233.408 0 + vertex 234.741 233.22 0 + endloop + endfacet + facet normal 0.866186 0.499722 0 + outer loop + vertex 234.544 233.59 -3 + vertex 234.649 233.408 0 + vertex 234.649 233.408 -3 + endloop + endfacet + facet normal 0.866186 0.499722 -0 + outer loop + vertex 234.544 233.59 -3 + vertex 234.544 233.59 0 + vertex 234.649 233.408 0 + endloop + endfacet + facet normal 0.828349 0.560213 0 + outer loop + vertex 234.427 233.763 -3 + vertex 234.544 233.59 0 + vertex 234.544 233.59 -3 + endloop + endfacet + facet normal 0.828349 0.560213 -0 + outer loop + vertex 234.427 233.763 -3 + vertex 234.427 233.763 0 + vertex 234.544 233.59 0 + endloop + endfacet + facet normal 0.787807 0.615922 0 + outer loop + vertex 234.298 233.928 -3 + vertex 234.427 233.763 0 + vertex 234.427 233.763 -3 + endloop + endfacet + facet normal 0.787807 0.615922 -0 + outer loop + vertex 234.298 233.928 -3 + vertex 234.298 233.928 0 + vertex 234.427 233.763 0 + endloop + endfacet + facet normal 0.744242 0.66791 0 + outer loop + vertex 234.158 234.084 -3 + vertex 234.298 233.928 0 + vertex 234.298 233.928 -3 + endloop + endfacet + facet normal 0.744242 0.66791 -0 + outer loop + vertex 234.158 234.084 -3 + vertex 234.158 234.084 0 + vertex 234.298 233.928 0 + endloop + endfacet + facet normal 0.692631 0.721292 0 + outer loop + vertex 234.007 234.229 -3 + vertex 234.158 234.084 0 + vertex 234.158 234.084 -3 + endloop + endfacet + facet normal 0.692631 0.721292 -0 + outer loop + vertex 234.007 234.229 -3 + vertex 234.007 234.229 0 + vertex 234.158 234.084 0 + endloop + endfacet + facet normal 0.644871 0.764291 0 + outer loop + vertex 233.847 234.364 -3 + vertex 234.007 234.229 0 + vertex 234.007 234.229 -3 + endloop + endfacet + facet normal 0.644871 0.764291 -0 + outer loop + vertex 233.847 234.364 -3 + vertex 233.847 234.364 0 + vertex 234.007 234.229 0 + endloop + endfacet + facet normal 0.588456 0.808529 0 + outer loop + vertex 233.678 234.487 -3 + vertex 233.847 234.364 0 + vertex 233.847 234.364 -3 + endloop + endfacet + facet normal 0.588456 0.808529 -0 + outer loop + vertex 233.678 234.487 -3 + vertex 233.678 234.487 0 + vertex 233.847 234.364 0 + endloop + endfacet + facet normal 0.529142 0.848533 0 + outer loop + vertex 233.5 234.598 -3 + vertex 233.678 234.487 0 + vertex 233.678 234.487 -3 + endloop + endfacet + facet normal 0.529142 0.848533 -0 + outer loop + vertex 233.5 234.598 -3 + vertex 233.5 234.598 0 + vertex 233.678 234.487 0 + endloop + endfacet + facet normal 0.468107 0.883672 0 + outer loop + vertex 233.315 234.696 -3 + vertex 233.5 234.598 0 + vertex 233.5 234.598 -3 + endloop + endfacet + facet normal 0.468107 0.883672 -0 + outer loop + vertex 233.315 234.696 -3 + vertex 233.315 234.696 0 + vertex 233.5 234.598 0 + endloop + endfacet + facet normal 0.410563 0.911832 0 + outer loop + vertex 233.124 234.782 -3 + vertex 233.315 234.696 0 + vertex 233.315 234.696 -3 + endloop + endfacet + facet normal 0.410563 0.911832 -0 + outer loop + vertex 233.124 234.782 -3 + vertex 233.124 234.782 0 + vertex 233.315 234.696 0 + endloop + endfacet + facet normal 0.339058 0.940766 0 + outer loop + vertex 232.927 234.853 -3 + vertex 233.124 234.782 0 + vertex 233.124 234.782 -3 + endloop + endfacet + facet normal 0.339058 0.940766 -0 + outer loop + vertex 232.927 234.853 -3 + vertex 232.927 234.853 0 + vertex 233.124 234.782 0 + endloop + endfacet + facet normal 0.277246 0.960799 0 + outer loop + vertex 232.726 234.911 -3 + vertex 232.927 234.853 0 + vertex 232.927 234.853 -3 + endloop + endfacet + facet normal 0.277246 0.960799 -0 + outer loop + vertex 232.726 234.911 -3 + vertex 232.726 234.911 0 + vertex 232.927 234.853 0 + endloop + endfacet + facet normal 0.205289 0.978701 0 + outer loop + vertex 232.521 234.954 -3 + vertex 232.726 234.911 0 + vertex 232.726 234.911 -3 + endloop + endfacet + facet normal 0.205289 0.978701 -0 + outer loop + vertex 232.521 234.954 -3 + vertex 232.521 234.954 0 + vertex 232.726 234.911 0 + endloop + endfacet + facet normal 0.143429 0.989661 0 + outer loop + vertex 232.314 234.984 -3 + vertex 232.521 234.954 0 + vertex 232.521 234.954 -3 + endloop + endfacet + facet normal 0.143429 0.989661 -0 + outer loop + vertex 232.314 234.984 -3 + vertex 232.314 234.984 0 + vertex 232.521 234.954 0 + endloop + endfacet + facet normal 0.0668359 0.997764 0 + outer loop + vertex 232.105 234.998 -3 + vertex 232.314 234.984 0 + vertex 232.314 234.984 -3 + endloop + endfacet + facet normal 0.0668359 0.997764 -0 + outer loop + vertex 232.105 234.998 -3 + vertex 232.105 234.998 0 + vertex 232.314 234.984 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 232.002 234.998 -3 + vertex 232.105 234.998 0 + vertex 232.105 234.998 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 232.002 234.998 -3 + vertex 232.002 234.998 0 + vertex 232.105 234.998 0 + endloop + endfacet + facet normal 0.707107 0.707107 0 + outer loop + vertex 232 235 -3 + vertex 232.002 234.998 0 + vertex 232.002 234.998 -3 + endloop + endfacet + facet normal 0.707107 0.707107 -0 + outer loop + vertex 232 235 -3 + vertex 232 235 0 + vertex 232.002 234.998 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -232 235 -3 + vertex 232 235 0 + vertex 232 235 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -232 235 -3 + vertex -232 235 0 + vertex 232 235 0 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -232.002 234.998 -3 + vertex -232 235 0 + vertex -232 235 -3 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -232.002 234.998 -3 + vertex -232.002 234.998 0 + vertex -232 235 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -232.105 234.998 -3 + vertex -232.002 234.998 0 + vertex -232.002 234.998 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -232.105 234.998 -3 + vertex -232.105 234.998 0 + vertex -232.002 234.998 0 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -232.314 234.984 -3 + vertex -232.105 234.998 0 + vertex -232.105 234.998 -3 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -232.314 234.984 -3 + vertex -232.314 234.984 0 + vertex -232.105 234.998 0 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -232.521 234.954 -3 + vertex -232.314 234.984 0 + vertex -232.314 234.984 -3 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -232.521 234.954 -3 + vertex -232.521 234.954 0 + vertex -232.314 234.984 0 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -232.726 234.911 -3 + vertex -232.521 234.954 0 + vertex -232.521 234.954 -3 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -232.726 234.911 -3 + vertex -232.726 234.911 0 + vertex -232.521 234.954 0 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -232.927 234.853 -3 + vertex -232.726 234.911 0 + vertex -232.726 234.911 -3 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -232.927 234.853 -3 + vertex -232.927 234.853 0 + vertex -232.726 234.911 0 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -233.124 234.782 -3 + vertex -232.927 234.853 0 + vertex -232.927 234.853 -3 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -233.124 234.782 -3 + vertex -233.124 234.782 0 + vertex -232.927 234.853 0 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -233.315 234.696 -3 + vertex -233.124 234.782 0 + vertex -233.124 234.782 -3 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -233.315 234.696 -3 + vertex -233.315 234.696 0 + vertex -233.124 234.782 0 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -233.5 234.598 -3 + vertex -233.315 234.696 0 + vertex -233.315 234.696 -3 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -233.5 234.598 -3 + vertex -233.5 234.598 0 + vertex -233.315 234.696 0 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -233.678 234.487 -3 + vertex -233.5 234.598 0 + vertex -233.5 234.598 -3 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -233.678 234.487 -3 + vertex -233.678 234.487 0 + vertex -233.5 234.598 0 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -233.847 234.364 -3 + vertex -233.678 234.487 0 + vertex -233.678 234.487 -3 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -233.847 234.364 -3 + vertex -233.847 234.364 0 + vertex -233.678 234.487 0 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -234.007 234.229 -3 + vertex -233.847 234.364 0 + vertex -233.847 234.364 -3 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -234.007 234.229 -3 + vertex -234.007 234.229 0 + vertex -233.847 234.364 0 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -234.158 234.084 -3 + vertex -234.007 234.229 0 + vertex -234.007 234.229 -3 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -234.158 234.084 -3 + vertex -234.158 234.084 0 + vertex -234.007 234.229 0 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -234.298 233.928 -3 + vertex -234.158 234.084 0 + vertex -234.158 234.084 -3 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -234.298 233.928 -3 + vertex -234.298 233.928 0 + vertex -234.158 234.084 0 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -234.427 233.763 -3 + vertex -234.298 233.928 0 + vertex -234.298 233.928 -3 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -234.427 233.763 -3 + vertex -234.427 233.763 0 + vertex -234.298 233.928 0 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -234.544 233.59 -3 + vertex -234.427 233.763 0 + vertex -234.427 233.763 -3 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -234.544 233.59 -3 + vertex -234.544 233.59 0 + vertex -234.427 233.763 0 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -234.649 233.408 -3 + vertex -234.544 233.59 0 + vertex -234.544 233.59 -3 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -234.649 233.408 -3 + vertex -234.649 233.408 0 + vertex -234.544 233.59 0 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -234.741 233.22 -3 + vertex -234.649 233.408 0 + vertex -234.649 233.408 -3 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -234.741 233.22 -3 + vertex -234.741 233.22 0 + vertex -234.649 233.408 0 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -234.819 233.026 -3 + vertex -234.741 233.22 0 + vertex -234.741 233.22 -3 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -234.819 233.026 -3 + vertex -234.819 233.026 0 + vertex -234.741 233.22 0 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -234.884 232.827 -3 + vertex -234.819 233.026 0 + vertex -234.819 233.026 -3 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -234.884 232.827 -3 + vertex -234.884 232.827 0 + vertex -234.819 233.026 0 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -234.934 232.624 -3 + vertex -234.884 232.827 0 + vertex -234.884 232.827 -3 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -234.934 232.624 -3 + vertex -234.934 232.624 0 + vertex -234.884 232.827 0 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -234.971 232.418 -3 + vertex -234.934 232.624 0 + vertex -234.934 232.624 -3 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -234.971 232.418 -3 + vertex -234.971 232.418 0 + vertex -234.934 232.624 0 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -234.993 232.209 -3 + vertex -234.971 232.418 0 + vertex -234.971 232.418 -3 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -234.993 232.209 -3 + vertex -234.993 232.209 0 + vertex -234.971 232.418 0 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -235 232 -3 + vertex -234.993 232.209 0 + vertex -234.993 232.209 -3 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -235 232 -3 + vertex -235 232 0 + vertex -234.993 232.209 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -235 -232 -3 + vertex -235 232 0 + vertex -235 232 -3 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -235 -232 -3 + vertex -235 -232 0 + vertex -235 232 0 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -234.993 -232.209 -3 + vertex -235 -232 0 + vertex -235 -232 -3 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -234.993 -232.209 -3 + vertex -234.993 -232.209 0 + vertex -235 -232 0 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -234.971 -232.418 -3 + vertex -234.993 -232.209 0 + vertex -234.993 -232.209 -3 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -234.971 -232.418 -3 + vertex -234.971 -232.418 0 + vertex -234.993 -232.209 0 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -234.934 -232.624 -3 + vertex -234.971 -232.418 0 + vertex -234.971 -232.418 -3 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -234.934 -232.624 -3 + vertex -234.934 -232.624 0 + vertex -234.971 -232.418 0 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -234.884 -232.827 -3 + vertex -234.934 -232.624 0 + vertex -234.934 -232.624 -3 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -234.884 -232.827 -3 + vertex -234.884 -232.827 0 + vertex -234.934 -232.624 0 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -234.819 -233.026 -3 + vertex -234.884 -232.827 0 + vertex -234.884 -232.827 -3 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -234.819 -233.026 -3 + vertex -234.819 -233.026 0 + vertex -234.884 -232.827 0 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -234.741 -233.22 -3 + vertex -234.819 -233.026 0 + vertex -234.819 -233.026 -3 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -234.741 -233.22 -3 + vertex -234.741 -233.22 0 + vertex -234.819 -233.026 0 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -234.649 -233.408 -3 + vertex -234.741 -233.22 0 + vertex -234.741 -233.22 -3 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -234.649 -233.408 -3 + vertex -234.649 -233.408 0 + vertex -234.741 -233.22 0 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -234.544 -233.59 -3 + vertex -234.649 -233.408 0 + vertex -234.649 -233.408 -3 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -234.544 -233.59 -3 + vertex -234.544 -233.59 0 + vertex -234.649 -233.408 0 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -234.427 -233.763 -3 + vertex -234.544 -233.59 0 + vertex -234.544 -233.59 -3 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -234.427 -233.763 -3 + vertex -234.427 -233.763 0 + vertex -234.544 -233.59 0 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -234.298 -233.928 -3 + vertex -234.427 -233.763 0 + vertex -234.427 -233.763 -3 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -234.298 -233.928 -3 + vertex -234.298 -233.928 0 + vertex -234.427 -233.763 0 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -234.158 -234.084 -3 + vertex -234.298 -233.928 0 + vertex -234.298 -233.928 -3 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -234.158 -234.084 -3 + vertex -234.158 -234.084 0 + vertex -234.298 -233.928 0 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -234.007 -234.229 -3 + vertex -234.158 -234.084 0 + vertex -234.158 -234.084 -3 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -234.007 -234.229 -3 + vertex -234.007 -234.229 0 + vertex -234.158 -234.084 0 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -233.847 -234.364 -3 + vertex -234.007 -234.229 0 + vertex -234.007 -234.229 -3 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -233.847 -234.364 -3 + vertex -233.847 -234.364 0 + vertex -234.007 -234.229 0 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -233.678 -234.487 -3 + vertex -233.847 -234.364 0 + vertex -233.847 -234.364 -3 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -233.678 -234.487 -3 + vertex -233.678 -234.487 0 + vertex -233.847 -234.364 0 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -233.5 -234.598 -3 + vertex -233.678 -234.487 0 + vertex -233.678 -234.487 -3 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -233.5 -234.598 -3 + vertex -233.5 -234.598 0 + vertex -233.678 -234.487 0 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -233.315 -234.696 -3 + vertex -233.5 -234.598 0 + vertex -233.5 -234.598 -3 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -233.315 -234.696 -3 + vertex -233.315 -234.696 0 + vertex -233.5 -234.598 0 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -233.124 -234.782 -3 + vertex -233.315 -234.696 0 + vertex -233.315 -234.696 -3 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -233.124 -234.782 -3 + vertex -233.124 -234.782 0 + vertex -233.315 -234.696 0 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -232.927 -234.853 -3 + vertex -233.124 -234.782 0 + vertex -233.124 -234.782 -3 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -232.927 -234.853 -3 + vertex -232.927 -234.853 0 + vertex -233.124 -234.782 0 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -232.726 -234.911 -3 + vertex -232.927 -234.853 0 + vertex -232.927 -234.853 -3 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -232.726 -234.911 -3 + vertex -232.726 -234.911 0 + vertex -232.927 -234.853 0 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -232.521 -234.954 -3 + vertex -232.726 -234.911 0 + vertex -232.726 -234.911 -3 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -232.521 -234.954 -3 + vertex -232.521 -234.954 0 + vertex -232.726 -234.911 0 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -232.314 -234.984 -3 + vertex -232.521 -234.954 0 + vertex -232.521 -234.954 -3 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -232.314 -234.984 -3 + vertex -232.314 -234.984 0 + vertex -232.521 -234.954 0 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -232.105 -234.998 -3 + vertex -232.314 -234.984 0 + vertex -232.314 -234.984 -3 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -232.105 -234.998 -3 + vertex -232.105 -234.998 0 + vertex -232.314 -234.984 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -232.002 -234.998 -3 + vertex -232.105 -234.998 0 + vertex -232.105 -234.998 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -232.002 -234.998 -3 + vertex -232.002 -234.998 0 + vertex -232.105 -234.998 0 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -232 -235 -3 + vertex -232.002 -234.998 0 + vertex -232.002 -234.998 -3 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -232 -235 -3 + vertex -232 -235 0 + vertex -232.002 -234.998 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 232 -235 -3 + vertex -232 -235 0 + vertex -232 -235 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 232 -235 -3 + vertex 232 -235 0 + vertex -232 -235 0 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 232.002 -234.998 -3 + vertex 232 -235 0 + vertex 232 -235 -3 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 232.002 -234.998 -3 + vertex 232.002 -234.998 0 + vertex 232 -235 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/resources/profiles/Creality/cr10s4.svg b/resources/profiles/Creality/cr10s4.svg index c3719456d1..598bc92b8c 100644 --- a/resources/profiles/Creality/cr10s4.svg +++ b/resources/profiles/Creality/cr10s4.svg @@ -1,4 +1,4 @@ - - + + diff --git a/resources/profiles/Creality/cr10spro.svg b/resources/profiles/Creality/cr10spro.svg new file mode 100644 index 0000000000..776243efa8 --- /dev/null +++ b/resources/profiles/Creality/cr10spro.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/cr6se.svg b/resources/profiles/Creality/cr6se.svg new file mode 100644 index 0000000000..d9eb920bc3 --- /dev/null +++ b/resources/profiles/Creality/cr6se.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/cr6se_bed.stl b/resources/profiles/Creality/cr6se_bed.stl new file mode 100644 index 0000000000..31bf786ed2 --- /dev/null +++ b/resources/profiles/Creality/cr6se_bed.stl @@ -0,0 +1,2774 @@ +solid OpenSCAD_Model + facet normal 0 0 -1 + outer loop + vertex 119.605 -127.498 -3 + vertex 119.502 -127.498 -3 + vertex 119.814 -127.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 119.814 -127.484 -3 + vertex 119.502 -127.498 -3 + vertex 120.021 -127.454 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex 119.502 127.498 -3 + vertex -122.5 124.5 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 120.021 -127.454 -3 + vertex 119.502 -127.498 -3 + vertex 120.226 -127.411 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 120.226 -127.411 -3 + vertex 119.502 -127.498 -3 + vertex 120.427 -127.353 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 120.427 -127.353 -3 + vertex 119.502 -127.498 -3 + vertex 120.624 -127.282 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 120.624 -127.282 -3 + vertex 119.502 -127.498 -3 + vertex 120.815 -127.196 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 120.815 -127.196 -3 + vertex 119.502 -127.498 -3 + vertex 121 -127.098 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121 -127.098 -3 + vertex 119.502 -127.498 -3 + vertex 121.178 -126.987 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.178 -126.987 -3 + vertex 119.502 -127.498 -3 + vertex 121.347 -126.864 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.347 -126.864 -3 + vertex 119.502 -127.498 -3 + vertex 121.507 -126.729 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.507 -126.729 -3 + vertex 119.502 -127.498 -3 + vertex 121.658 -126.584 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.658 -126.584 -3 + vertex 119.502 -127.498 -3 + vertex 121.798 -126.428 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.798 -126.428 -3 + vertex 119.502 -127.498 -3 + vertex 121.927 -126.263 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 121.927 -126.263 -3 + vertex 119.502 -127.498 -3 + vertex 122.044 -126.09 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.044 -126.09 -3 + vertex 119.502 -127.498 -3 + vertex 122.149 -125.908 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.149 -125.908 -3 + vertex 119.502 -127.498 -3 + vertex 122.241 -125.72 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.241 -125.72 -3 + vertex 119.502 -127.498 -3 + vertex 122.319 -125.526 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.319 -125.526 -3 + vertex 119.502 -127.498 -3 + vertex 122.384 -125.327 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.384 -125.327 -3 + vertex 119.502 -127.498 -3 + vertex 122.434 -125.124 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.434 -125.124 -3 + vertex 119.502 -127.498 -3 + vertex 122.471 -124.918 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.471 -124.918 -3 + vertex 119.502 -127.498 -3 + vertex 122.493 -124.709 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 122.493 -124.709 -3 + vertex 119.502 -127.498 -3 + vertex 122.5 -124.5 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex 119.5 127.5 -3 + vertex 119.502 127.498 -3 + vertex -119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 122.471 124.918 -3 + vertex 122.493 124.709 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 122.384 125.327 -3 + vertex 122.434 125.124 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 122.241 125.72 -3 + vertex 119.502 127.498 -3 + vertex 122.149 125.908 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 122.241 125.72 -3 + vertex 122.319 125.526 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 121.507 126.729 -3 + vertex 121.658 126.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 121.927 126.263 -3 + vertex 119.502 127.498 -3 + vertex 121.798 126.428 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 121.927 126.263 -3 + vertex 122.044 126.09 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 121.798 126.428 -3 + vertex 119.502 127.498 -3 + vertex 121.658 126.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 120.427 127.353 -3 + vertex 120.624 127.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 121.347 126.864 -3 + vertex 119.502 127.498 -3 + vertex 121.178 126.987 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 121.347 126.864 -3 + vertex 121.507 126.729 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 121.178 126.987 -3 + vertex 119.502 127.498 -3 + vertex 121 127.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 121 127.098 -3 + vertex 119.502 127.498 -3 + vertex 120.815 127.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 120.815 127.196 -3 + vertex 119.502 127.498 -3 + vertex 120.624 127.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 122.149 125.908 -3 + vertex 119.502 127.498 -3 + vertex 122.044 126.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 120.226 127.411 -3 + vertex 119.502 127.498 -3 + vertex 120.021 127.454 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 120.226 127.411 -3 + vertex 120.427 127.353 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 122.319 125.526 -3 + vertex 122.384 125.327 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 119.814 127.484 -3 + vertex 120.021 127.454 -3 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 122.434 125.124 -3 + vertex 122.471 124.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 119.605 127.498 -3 + vertex 119.814 127.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 122.5 124.5 -3 + vertex 119.502 127.498 -3 + vertex 122.493 124.709 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -119.5 127.5 -3 + vertex 119.5 127.5 -3 + vertex -119.502 127.498 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex 119.502 127.498 -3 + vertex 122.5 124.5 -3 + vertex -122.5 124.5 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -122.493 124.709 -3 + vertex -119.502 127.498 -3 + vertex -122.5 124.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.5 124.5 -3 + vertex 122.5 124.5 -3 + vertex 122.5 -124.5 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -119.814 127.484 -3 + vertex -119.605 127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -120.021 127.454 -3 + vertex -119.814 127.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -120.226 127.411 -3 + vertex -120.021 127.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -120.427 127.353 -3 + vertex -120.226 127.411 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -120.624 127.282 -3 + vertex -120.427 127.353 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -120.815 127.196 -3 + vertex -120.624 127.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121 127.098 -3 + vertex -120.815 127.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.178 126.987 -3 + vertex -121 127.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.347 126.864 -3 + vertex -121.178 126.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.507 126.729 -3 + vertex -121.347 126.864 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.658 126.584 -3 + vertex -121.507 126.729 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.798 126.428 -3 + vertex -121.658 126.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -121.927 126.263 -3 + vertex -121.798 126.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.044 126.09 -3 + vertex -121.927 126.263 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.149 125.908 -3 + vertex -122.044 126.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.241 125.72 -3 + vertex -122.149 125.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.319 125.526 -3 + vertex -122.241 125.72 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.384 125.327 -3 + vertex -122.319 125.526 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.434 125.124 -3 + vertex -122.384 125.327 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.471 124.918 -3 + vertex -122.434 125.124 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 127.498 -3 + vertex -122.493 124.709 -3 + vertex -122.471 124.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.5 -124.5 -3 + vertex -122.5 124.5 -3 + vertex 122.5 -124.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 -127.498 -3 + vertex -122.5 -124.5 -3 + vertex 122.5 -124.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 119.502 -127.498 -3 + vertex -119.502 -127.498 -3 + vertex -122.5 -124.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex -122.471 -124.918 -3 + vertex -122.493 -124.709 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.384 -125.327 -3 + vertex -122.434 -125.124 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.241 -125.72 -3 + vertex -119.502 -127.498 -3 + vertex -122.149 -125.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.241 -125.72 -3 + vertex -122.319 -125.526 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex -121.507 -126.729 -3 + vertex -121.658 -126.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.927 -126.263 -3 + vertex -119.502 -127.498 -3 + vertex -121.798 -126.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.927 -126.263 -3 + vertex -122.044 -126.09 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.798 -126.428 -3 + vertex -119.502 -127.498 -3 + vertex -121.658 -126.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex -120.427 -127.353 -3 + vertex -120.624 -127.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.347 -126.864 -3 + vertex -119.502 -127.498 -3 + vertex -121.178 -126.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.347 -126.864 -3 + vertex -121.507 -126.729 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121.178 -126.987 -3 + vertex -119.502 -127.498 -3 + vertex -121 -127.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -121 -127.098 -3 + vertex -119.502 -127.498 -3 + vertex -120.815 -127.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -120.815 -127.196 -3 + vertex -119.502 -127.498 -3 + vertex -120.624 -127.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.149 -125.908 -3 + vertex -119.502 -127.498 -3 + vertex -122.044 -126.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -120.226 -127.411 -3 + vertex -119.502 -127.498 -3 + vertex -120.021 -127.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -120.226 -127.411 -3 + vertex -120.427 -127.353 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.319 -125.526 -3 + vertex -122.384 -125.327 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.814 -127.484 -3 + vertex -120.021 -127.454 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex -122.434 -125.124 -3 + vertex -122.471 -124.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex -119.605 -127.498 -3 + vertex -119.814 -127.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 119.502 -127.498 -3 + vertex 119.5 -127.5 -3 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -119.502 -127.498 -3 + vertex 119.5 -127.5 -3 + vertex -119.5 -127.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -122.5 -124.5 -3 + vertex -119.502 -127.498 -3 + vertex -122.493 -124.709 -3 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.814 -127.484 0 + vertex 119.502 -127.498 0 + vertex 119.605 -127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.021 -127.454 0 + vertex 119.502 -127.498 0 + vertex 119.814 -127.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.5 124.5 0 + vertex 119.502 127.498 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.226 -127.411 0 + vertex 119.502 -127.498 0 + vertex 120.021 -127.454 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.427 -127.353 0 + vertex 119.502 -127.498 0 + vertex 120.226 -127.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.624 -127.282 0 + vertex 119.502 -127.498 0 + vertex 120.427 -127.353 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.815 -127.196 0 + vertex 119.502 -127.498 0 + vertex 120.624 -127.282 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121 -127.098 0 + vertex 119.502 -127.498 0 + vertex 120.815 -127.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.178 -126.987 0 + vertex 119.502 -127.498 0 + vertex 121 -127.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.347 -126.864 0 + vertex 119.502 -127.498 0 + vertex 121.178 -126.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.507 -126.729 0 + vertex 119.502 -127.498 0 + vertex 121.347 -126.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.658 -126.584 0 + vertex 119.502 -127.498 0 + vertex 121.507 -126.729 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.798 -126.428 0 + vertex 119.502 -127.498 0 + vertex 121.658 -126.584 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.927 -126.263 0 + vertex 119.502 -127.498 0 + vertex 121.798 -126.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.044 -126.09 0 + vertex 119.502 -127.498 0 + vertex 121.927 -126.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.149 -125.908 0 + vertex 119.502 -127.498 0 + vertex 122.044 -126.09 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.241 -125.72 0 + vertex 119.502 -127.498 0 + vertex 122.149 -125.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.319 -125.526 0 + vertex 119.502 -127.498 0 + vertex 122.241 -125.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.384 -125.327 0 + vertex 119.502 -127.498 0 + vertex 122.319 -125.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.434 -125.124 0 + vertex 119.502 -127.498 0 + vertex 122.384 -125.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.471 -124.918 0 + vertex 119.502 -127.498 0 + vertex 122.434 -125.124 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.493 -124.709 0 + vertex 119.502 -127.498 0 + vertex 122.471 -124.918 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.5 -124.5 0 + vertex 119.502 -127.498 0 + vertex 122.493 -124.709 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 127.498 0 + vertex 119.502 127.498 0 + vertex 119.5 127.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.493 124.709 0 + vertex 122.471 124.918 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 122.434 125.124 0 + vertex 122.384 125.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.149 125.908 0 + vertex 119.502 127.498 0 + vertex 122.241 125.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 122.319 125.526 0 + vertex 122.241 125.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.658 126.584 0 + vertex 121.507 126.729 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.798 126.428 0 + vertex 119.502 127.498 0 + vertex 121.927 126.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 122.044 126.09 0 + vertex 121.927 126.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.658 126.584 0 + vertex 119.502 127.498 0 + vertex 121.798 126.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.624 127.282 0 + vertex 120.427 127.353 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121.178 126.987 0 + vertex 119.502 127.498 0 + vertex 121.347 126.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 121.507 126.729 0 + vertex 121.347 126.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 121 127.098 0 + vertex 119.502 127.498 0 + vertex 121.178 126.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.815 127.196 0 + vertex 119.502 127.498 0 + vertex 121 127.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.624 127.282 0 + vertex 119.502 127.498 0 + vertex 120.815 127.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.044 126.09 0 + vertex 119.502 127.498 0 + vertex 122.149 125.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 120.021 127.454 0 + vertex 119.502 127.498 0 + vertex 120.226 127.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 120.427 127.353 0 + vertex 120.226 127.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 122.384 125.327 0 + vertex 122.319 125.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.502 127.498 0 + vertex 120.021 127.454 0 + vertex 119.814 127.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.471 124.918 0 + vertex 122.434 125.124 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 119.814 127.484 0 + vertex 119.605 127.498 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.493 124.709 0 + vertex 119.502 127.498 0 + vertex 122.5 124.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 127.498 0 + vertex 119.5 127.5 0 + vertex -119.5 127.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.5 124.5 0 + vertex 122.5 124.5 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.5 124.5 0 + vertex -119.502 127.498 0 + vertex -122.493 124.709 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex 122.5 -124.5 0 + vertex 122.5 124.5 0 + vertex -122.5 124.5 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -119.605 127.498 0 + vertex -119.814 127.484 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -119.814 127.484 0 + vertex -120.021 127.454 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -120.021 127.454 0 + vertex -120.226 127.411 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -120.226 127.411 0 + vertex -120.427 127.353 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -120.427 127.353 0 + vertex -120.624 127.282 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -120.624 127.282 0 + vertex -120.815 127.196 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -120.815 127.196 0 + vertex -121 127.098 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121 127.098 0 + vertex -121.178 126.987 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.178 126.987 0 + vertex -121.347 126.864 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.347 126.864 0 + vertex -121.507 126.729 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.507 126.729 0 + vertex -121.658 126.584 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.658 126.584 0 + vertex -121.798 126.428 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.798 126.428 0 + vertex -121.927 126.263 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -121.927 126.263 0 + vertex -122.044 126.09 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.044 126.09 0 + vertex -122.149 125.908 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.149 125.908 0 + vertex -122.241 125.72 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.241 125.72 0 + vertex -122.319 125.526 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.319 125.526 0 + vertex -122.384 125.327 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.384 125.327 0 + vertex -122.434 125.124 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.434 125.124 0 + vertex -122.471 124.918 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -122.471 124.918 0 + vertex -122.493 124.709 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.5 -124.5 0 + vertex -122.5 124.5 0 + vertex -122.5 -124.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 122.5 -124.5 0 + vertex -122.5 -124.5 0 + vertex 119.502 -127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.5 -124.5 0 + vertex -119.502 -127.498 0 + vertex 119.502 -127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.493 -124.709 0 + vertex -122.471 -124.918 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -122.434 -125.124 0 + vertex -122.384 -125.327 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -122.149 -125.908 0 + vertex -119.502 -127.498 0 + vertex -122.241 -125.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -122.319 -125.526 0 + vertex -122.241 -125.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -121.658 -126.584 0 + vertex -121.507 -126.729 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -121.798 -126.428 0 + vertex -119.502 -127.498 0 + vertex -121.927 -126.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -122.044 -126.09 0 + vertex -121.927 -126.263 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -121.658 -126.584 0 + vertex -119.502 -127.498 0 + vertex -121.798 -126.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -120.624 -127.282 0 + vertex -120.427 -127.353 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -121.178 -126.987 0 + vertex -119.502 -127.498 0 + vertex -121.347 -126.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -121.507 -126.729 0 + vertex -121.347 -126.864 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -121 -127.098 0 + vertex -119.502 -127.498 0 + vertex -121.178 -126.987 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -120.815 -127.196 0 + vertex -119.502 -127.498 0 + vertex -121 -127.098 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -120.624 -127.282 0 + vertex -119.502 -127.498 0 + vertex -120.815 -127.196 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -122.044 -126.09 0 + vertex -119.502 -127.498 0 + vertex -122.149 -125.908 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -120.021 -127.454 0 + vertex -119.502 -127.498 0 + vertex -120.226 -127.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -120.427 -127.353 0 + vertex -120.226 -127.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -122.384 -125.327 0 + vertex -122.319 -125.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex -120.021 -127.454 0 + vertex -119.814 -127.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -122.471 -124.918 0 + vertex -122.434 -125.124 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -119.814 -127.484 0 + vertex -119.605 -127.498 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -119.502 -127.498 0 + vertex 119.5 -127.5 0 + vertex 119.502 -127.498 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -119.5 -127.5 0 + vertex 119.5 -127.5 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -122.493 -124.709 0 + vertex -119.502 -127.498 0 + vertex -122.5 -124.5 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 119.605 -127.498 -3 + vertex 119.502 -127.498 0 + vertex 119.502 -127.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 119.605 -127.498 -3 + vertex 119.605 -127.498 0 + vertex 119.502 -127.498 0 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 119.814 -127.484 -3 + vertex 119.605 -127.498 0 + vertex 119.605 -127.498 -3 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 119.814 -127.484 -3 + vertex 119.814 -127.484 0 + vertex 119.605 -127.498 0 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 120.021 -127.454 -3 + vertex 119.814 -127.484 0 + vertex 119.814 -127.484 -3 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 120.021 -127.454 -3 + vertex 120.021 -127.454 0 + vertex 119.814 -127.484 0 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 120.226 -127.411 -3 + vertex 120.021 -127.454 0 + vertex 120.021 -127.454 -3 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 120.226 -127.411 -3 + vertex 120.226 -127.411 0 + vertex 120.021 -127.454 0 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 120.427 -127.353 -3 + vertex 120.226 -127.411 0 + vertex 120.226 -127.411 -3 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 120.427 -127.353 -3 + vertex 120.427 -127.353 0 + vertex 120.226 -127.411 0 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 120.624 -127.282 -3 + vertex 120.427 -127.353 0 + vertex 120.427 -127.353 -3 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 120.624 -127.282 -3 + vertex 120.624 -127.282 0 + vertex 120.427 -127.353 0 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 120.815 -127.196 -3 + vertex 120.624 -127.282 0 + vertex 120.624 -127.282 -3 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 120.815 -127.196 -3 + vertex 120.815 -127.196 0 + vertex 120.624 -127.282 0 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 121 -127.098 -3 + vertex 120.815 -127.196 0 + vertex 120.815 -127.196 -3 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 121 -127.098 -3 + vertex 121 -127.098 0 + vertex 120.815 -127.196 0 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 121.178 -126.987 -3 + vertex 121 -127.098 0 + vertex 121 -127.098 -3 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 121.178 -126.987 -3 + vertex 121.178 -126.987 0 + vertex 121 -127.098 0 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 121.347 -126.864 -3 + vertex 121.178 -126.987 0 + vertex 121.178 -126.987 -3 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 121.347 -126.864 -3 + vertex 121.347 -126.864 0 + vertex 121.178 -126.987 0 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 121.507 -126.729 -3 + vertex 121.347 -126.864 0 + vertex 121.347 -126.864 -3 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 121.507 -126.729 -3 + vertex 121.507 -126.729 0 + vertex 121.347 -126.864 0 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 121.658 -126.584 -3 + vertex 121.507 -126.729 0 + vertex 121.507 -126.729 -3 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 121.658 -126.584 -3 + vertex 121.658 -126.584 0 + vertex 121.507 -126.729 0 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 121.798 -126.428 -3 + vertex 121.658 -126.584 0 + vertex 121.658 -126.584 -3 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 121.798 -126.428 -3 + vertex 121.798 -126.428 0 + vertex 121.658 -126.584 0 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 121.927 -126.263 -3 + vertex 121.798 -126.428 0 + vertex 121.798 -126.428 -3 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 121.927 -126.263 -3 + vertex 121.927 -126.263 0 + vertex 121.798 -126.428 0 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 122.044 -126.09 -3 + vertex 121.927 -126.263 0 + vertex 121.927 -126.263 -3 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 122.044 -126.09 -3 + vertex 122.044 -126.09 0 + vertex 121.927 -126.263 0 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 122.149 -125.908 -3 + vertex 122.044 -126.09 0 + vertex 122.044 -126.09 -3 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 122.149 -125.908 -3 + vertex 122.149 -125.908 0 + vertex 122.044 -126.09 0 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 122.241 -125.72 -3 + vertex 122.149 -125.908 0 + vertex 122.149 -125.908 -3 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 122.241 -125.72 -3 + vertex 122.241 -125.72 0 + vertex 122.149 -125.908 0 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 122.319 -125.526 -3 + vertex 122.241 -125.72 0 + vertex 122.241 -125.72 -3 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 122.319 -125.526 -3 + vertex 122.319 -125.526 0 + vertex 122.241 -125.72 0 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 122.384 -125.327 -3 + vertex 122.319 -125.526 0 + vertex 122.319 -125.526 -3 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 122.384 -125.327 -3 + vertex 122.384 -125.327 0 + vertex 122.319 -125.526 0 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 122.434 -125.124 -3 + vertex 122.384 -125.327 0 + vertex 122.384 -125.327 -3 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 122.434 -125.124 -3 + vertex 122.434 -125.124 0 + vertex 122.384 -125.327 0 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 122.471 -124.918 -3 + vertex 122.434 -125.124 0 + vertex 122.434 -125.124 -3 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 122.471 -124.918 -3 + vertex 122.471 -124.918 0 + vertex 122.434 -125.124 0 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 122.493 -124.709 -3 + vertex 122.471 -124.918 0 + vertex 122.471 -124.918 -3 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 122.493 -124.709 -3 + vertex 122.493 -124.709 0 + vertex 122.471 -124.918 0 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 122.5 -124.5 -3 + vertex 122.493 -124.709 0 + vertex 122.493 -124.709 -3 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 122.5 -124.5 -3 + vertex 122.5 -124.5 0 + vertex 122.493 -124.709 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 122.5 124.5 -3 + vertex 122.5 -124.5 0 + vertex 122.5 -124.5 -3 + endloop + endfacet + facet normal 1 0 -0 + outer loop + vertex 122.5 124.5 -3 + vertex 122.5 124.5 0 + vertex 122.5 -124.5 0 + endloop + endfacet + facet normal 0.99944 0.0334741 0 + outer loop + vertex 122.493 124.709 -3 + vertex 122.5 124.5 0 + vertex 122.5 124.5 -3 + endloop + endfacet + facet normal 0.99944 0.0334741 -0 + outer loop + vertex 122.493 124.709 -3 + vertex 122.493 124.709 0 + vertex 122.5 124.5 0 + endloop + endfacet + facet normal 0.994505 0.104685 0 + outer loop + vertex 122.471 124.918 -3 + vertex 122.493 124.709 0 + vertex 122.493 124.709 -3 + endloop + endfacet + facet normal 0.994505 0.104685 -0 + outer loop + vertex 122.471 124.918 -3 + vertex 122.471 124.918 0 + vertex 122.493 124.709 0 + endloop + endfacet + facet normal 0.98425 0.176783 0 + outer loop + vertex 122.434 125.124 -3 + vertex 122.471 124.918 0 + vertex 122.471 124.918 -3 + endloop + endfacet + facet normal 0.98425 0.176783 -0 + outer loop + vertex 122.434 125.124 -3 + vertex 122.434 125.124 0 + vertex 122.471 124.918 0 + endloop + endfacet + facet normal 0.970981 0.239158 0 + outer loop + vertex 122.384 125.327 -3 + vertex 122.434 125.124 0 + vertex 122.434 125.124 -3 + endloop + endfacet + facet normal 0.970981 0.239158 -0 + outer loop + vertex 122.384 125.327 -3 + vertex 122.384 125.327 0 + vertex 122.434 125.124 0 + endloop + endfacet + facet normal 0.950577 0.31049 0 + outer loop + vertex 122.319 125.526 -3 + vertex 122.384 125.327 0 + vertex 122.384 125.327 -3 + endloop + endfacet + facet normal 0.950577 0.31049 -0 + outer loop + vertex 122.319 125.526 -3 + vertex 122.319 125.526 0 + vertex 122.384 125.327 0 + endloop + endfacet + facet normal 0.927816 0.373039 0 + outer loop + vertex 122.241 125.72 -3 + vertex 122.319 125.526 0 + vertex 122.319 125.526 -3 + endloop + endfacet + facet normal 0.927816 0.373039 -0 + outer loop + vertex 122.241 125.72 -3 + vertex 122.241 125.72 0 + vertex 122.319 125.526 0 + endloop + endfacet + facet normal 0.898217 0.439553 0 + outer loop + vertex 122.149 125.908 -3 + vertex 122.241 125.72 0 + vertex 122.241 125.72 -3 + endloop + endfacet + facet normal 0.898217 0.439553 -0 + outer loop + vertex 122.149 125.908 -3 + vertex 122.149 125.908 0 + vertex 122.241 125.72 0 + endloop + endfacet + facet normal 0.866186 0.499722 0 + outer loop + vertex 122.044 126.09 -3 + vertex 122.149 125.908 0 + vertex 122.149 125.908 -3 + endloop + endfacet + facet normal 0.866186 0.499722 -0 + outer loop + vertex 122.044 126.09 -3 + vertex 122.044 126.09 0 + vertex 122.149 125.908 0 + endloop + endfacet + facet normal 0.828349 0.560213 0 + outer loop + vertex 121.927 126.263 -3 + vertex 122.044 126.09 0 + vertex 122.044 126.09 -3 + endloop + endfacet + facet normal 0.828349 0.560213 -0 + outer loop + vertex 121.927 126.263 -3 + vertex 121.927 126.263 0 + vertex 122.044 126.09 0 + endloop + endfacet + facet normal 0.787807 0.615922 0 + outer loop + vertex 121.798 126.428 -3 + vertex 121.927 126.263 0 + vertex 121.927 126.263 -3 + endloop + endfacet + facet normal 0.787807 0.615922 -0 + outer loop + vertex 121.798 126.428 -3 + vertex 121.798 126.428 0 + vertex 121.927 126.263 0 + endloop + endfacet + facet normal 0.744242 0.66791 0 + outer loop + vertex 121.658 126.584 -3 + vertex 121.798 126.428 0 + vertex 121.798 126.428 -3 + endloop + endfacet + facet normal 0.744242 0.66791 -0 + outer loop + vertex 121.658 126.584 -3 + vertex 121.658 126.584 0 + vertex 121.798 126.428 0 + endloop + endfacet + facet normal 0.692631 0.721292 0 + outer loop + vertex 121.507 126.729 -3 + vertex 121.658 126.584 0 + vertex 121.658 126.584 -3 + endloop + endfacet + facet normal 0.692631 0.721292 -0 + outer loop + vertex 121.507 126.729 -3 + vertex 121.507 126.729 0 + vertex 121.658 126.584 0 + endloop + endfacet + facet normal 0.644871 0.764291 0 + outer loop + vertex 121.347 126.864 -3 + vertex 121.507 126.729 0 + vertex 121.507 126.729 -3 + endloop + endfacet + facet normal 0.644871 0.764291 -0 + outer loop + vertex 121.347 126.864 -3 + vertex 121.347 126.864 0 + vertex 121.507 126.729 0 + endloop + endfacet + facet normal 0.588456 0.808529 0 + outer loop + vertex 121.178 126.987 -3 + vertex 121.347 126.864 0 + vertex 121.347 126.864 -3 + endloop + endfacet + facet normal 0.588456 0.808529 -0 + outer loop + vertex 121.178 126.987 -3 + vertex 121.178 126.987 0 + vertex 121.347 126.864 0 + endloop + endfacet + facet normal 0.529142 0.848533 0 + outer loop + vertex 121 127.098 -3 + vertex 121.178 126.987 0 + vertex 121.178 126.987 -3 + endloop + endfacet + facet normal 0.529142 0.848533 -0 + outer loop + vertex 121 127.098 -3 + vertex 121 127.098 0 + vertex 121.178 126.987 0 + endloop + endfacet + facet normal 0.468107 0.883672 0 + outer loop + vertex 120.815 127.196 -3 + vertex 121 127.098 0 + vertex 121 127.098 -3 + endloop + endfacet + facet normal 0.468107 0.883672 -0 + outer loop + vertex 120.815 127.196 -3 + vertex 120.815 127.196 0 + vertex 121 127.098 0 + endloop + endfacet + facet normal 0.410563 0.911832 0 + outer loop + vertex 120.624 127.282 -3 + vertex 120.815 127.196 0 + vertex 120.815 127.196 -3 + endloop + endfacet + facet normal 0.410563 0.911832 -0 + outer loop + vertex 120.624 127.282 -3 + vertex 120.624 127.282 0 + vertex 120.815 127.196 0 + endloop + endfacet + facet normal 0.339058 0.940766 0 + outer loop + vertex 120.427 127.353 -3 + vertex 120.624 127.282 0 + vertex 120.624 127.282 -3 + endloop + endfacet + facet normal 0.339058 0.940766 -0 + outer loop + vertex 120.427 127.353 -3 + vertex 120.427 127.353 0 + vertex 120.624 127.282 0 + endloop + endfacet + facet normal 0.277246 0.960799 0 + outer loop + vertex 120.226 127.411 -3 + vertex 120.427 127.353 0 + vertex 120.427 127.353 -3 + endloop + endfacet + facet normal 0.277246 0.960799 -0 + outer loop + vertex 120.226 127.411 -3 + vertex 120.226 127.411 0 + vertex 120.427 127.353 0 + endloop + endfacet + facet normal 0.205289 0.978701 0 + outer loop + vertex 120.021 127.454 -3 + vertex 120.226 127.411 0 + vertex 120.226 127.411 -3 + endloop + endfacet + facet normal 0.205289 0.978701 -0 + outer loop + vertex 120.021 127.454 -3 + vertex 120.021 127.454 0 + vertex 120.226 127.411 0 + endloop + endfacet + facet normal 0.143429 0.989661 0 + outer loop + vertex 119.814 127.484 -3 + vertex 120.021 127.454 0 + vertex 120.021 127.454 -3 + endloop + endfacet + facet normal 0.143429 0.989661 -0 + outer loop + vertex 119.814 127.484 -3 + vertex 119.814 127.484 0 + vertex 120.021 127.454 0 + endloop + endfacet + facet normal 0.0668359 0.997764 0 + outer loop + vertex 119.605 127.498 -3 + vertex 119.814 127.484 0 + vertex 119.814 127.484 -3 + endloop + endfacet + facet normal 0.0668359 0.997764 -0 + outer loop + vertex 119.605 127.498 -3 + vertex 119.605 127.498 0 + vertex 119.814 127.484 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 119.502 127.498 -3 + vertex 119.605 127.498 0 + vertex 119.605 127.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 119.502 127.498 -3 + vertex 119.502 127.498 0 + vertex 119.605 127.498 0 + endloop + endfacet + facet normal 0.707107 0.707107 0 + outer loop + vertex 119.5 127.5 -3 + vertex 119.502 127.498 0 + vertex 119.502 127.498 -3 + endloop + endfacet + facet normal 0.707107 0.707107 -0 + outer loop + vertex 119.5 127.5 -3 + vertex 119.5 127.5 0 + vertex 119.502 127.498 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -119.5 127.5 -3 + vertex 119.5 127.5 0 + vertex 119.5 127.5 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -119.5 127.5 -3 + vertex -119.5 127.5 0 + vertex 119.5 127.5 0 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -119.502 127.498 -3 + vertex -119.5 127.5 0 + vertex -119.5 127.5 -3 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -119.502 127.498 -3 + vertex -119.502 127.498 0 + vertex -119.5 127.5 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -119.605 127.498 -3 + vertex -119.502 127.498 0 + vertex -119.502 127.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -119.605 127.498 -3 + vertex -119.605 127.498 0 + vertex -119.502 127.498 0 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -119.814 127.484 -3 + vertex -119.605 127.498 0 + vertex -119.605 127.498 -3 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -119.814 127.484 -3 + vertex -119.814 127.484 0 + vertex -119.605 127.498 0 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -120.021 127.454 -3 + vertex -119.814 127.484 0 + vertex -119.814 127.484 -3 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -120.021 127.454 -3 + vertex -120.021 127.454 0 + vertex -119.814 127.484 0 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -120.226 127.411 -3 + vertex -120.021 127.454 0 + vertex -120.021 127.454 -3 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -120.226 127.411 -3 + vertex -120.226 127.411 0 + vertex -120.021 127.454 0 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -120.427 127.353 -3 + vertex -120.226 127.411 0 + vertex -120.226 127.411 -3 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -120.427 127.353 -3 + vertex -120.427 127.353 0 + vertex -120.226 127.411 0 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -120.624 127.282 -3 + vertex -120.427 127.353 0 + vertex -120.427 127.353 -3 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -120.624 127.282 -3 + vertex -120.624 127.282 0 + vertex -120.427 127.353 0 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -120.815 127.196 -3 + vertex -120.624 127.282 0 + vertex -120.624 127.282 -3 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -120.815 127.196 -3 + vertex -120.815 127.196 0 + vertex -120.624 127.282 0 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -121 127.098 -3 + vertex -120.815 127.196 0 + vertex -120.815 127.196 -3 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -121 127.098 -3 + vertex -121 127.098 0 + vertex -120.815 127.196 0 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -121.178 126.987 -3 + vertex -121 127.098 0 + vertex -121 127.098 -3 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -121.178 126.987 -3 + vertex -121.178 126.987 0 + vertex -121 127.098 0 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -121.347 126.864 -3 + vertex -121.178 126.987 0 + vertex -121.178 126.987 -3 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -121.347 126.864 -3 + vertex -121.347 126.864 0 + vertex -121.178 126.987 0 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -121.507 126.729 -3 + vertex -121.347 126.864 0 + vertex -121.347 126.864 -3 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -121.507 126.729 -3 + vertex -121.507 126.729 0 + vertex -121.347 126.864 0 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -121.658 126.584 -3 + vertex -121.507 126.729 0 + vertex -121.507 126.729 -3 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -121.658 126.584 -3 + vertex -121.658 126.584 0 + vertex -121.507 126.729 0 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -121.798 126.428 -3 + vertex -121.658 126.584 0 + vertex -121.658 126.584 -3 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -121.798 126.428 -3 + vertex -121.798 126.428 0 + vertex -121.658 126.584 0 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -121.927 126.263 -3 + vertex -121.798 126.428 0 + vertex -121.798 126.428 -3 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -121.927 126.263 -3 + vertex -121.927 126.263 0 + vertex -121.798 126.428 0 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -122.044 126.09 -3 + vertex -121.927 126.263 0 + vertex -121.927 126.263 -3 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -122.044 126.09 -3 + vertex -122.044 126.09 0 + vertex -121.927 126.263 0 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -122.149 125.908 -3 + vertex -122.044 126.09 0 + vertex -122.044 126.09 -3 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -122.149 125.908 -3 + vertex -122.149 125.908 0 + vertex -122.044 126.09 0 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -122.241 125.72 -3 + vertex -122.149 125.908 0 + vertex -122.149 125.908 -3 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -122.241 125.72 -3 + vertex -122.241 125.72 0 + vertex -122.149 125.908 0 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -122.319 125.526 -3 + vertex -122.241 125.72 0 + vertex -122.241 125.72 -3 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -122.319 125.526 -3 + vertex -122.319 125.526 0 + vertex -122.241 125.72 0 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -122.384 125.327 -3 + vertex -122.319 125.526 0 + vertex -122.319 125.526 -3 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -122.384 125.327 -3 + vertex -122.384 125.327 0 + vertex -122.319 125.526 0 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -122.434 125.124 -3 + vertex -122.384 125.327 0 + vertex -122.384 125.327 -3 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -122.434 125.124 -3 + vertex -122.434 125.124 0 + vertex -122.384 125.327 0 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -122.471 124.918 -3 + vertex -122.434 125.124 0 + vertex -122.434 125.124 -3 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -122.471 124.918 -3 + vertex -122.471 124.918 0 + vertex -122.434 125.124 0 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -122.493 124.709 -3 + vertex -122.471 124.918 0 + vertex -122.471 124.918 -3 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -122.493 124.709 -3 + vertex -122.493 124.709 0 + vertex -122.471 124.918 0 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -122.5 124.5 -3 + vertex -122.493 124.709 0 + vertex -122.493 124.709 -3 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -122.5 124.5 -3 + vertex -122.5 124.5 0 + vertex -122.493 124.709 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -122.5 -124.5 -3 + vertex -122.5 124.5 0 + vertex -122.5 124.5 -3 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -122.5 -124.5 -3 + vertex -122.5 -124.5 0 + vertex -122.5 124.5 0 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -122.493 -124.709 -3 + vertex -122.5 -124.5 0 + vertex -122.5 -124.5 -3 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -122.493 -124.709 -3 + vertex -122.493 -124.709 0 + vertex -122.5 -124.5 0 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -122.471 -124.918 -3 + vertex -122.493 -124.709 0 + vertex -122.493 -124.709 -3 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -122.471 -124.918 -3 + vertex -122.471 -124.918 0 + vertex -122.493 -124.709 0 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -122.434 -125.124 -3 + vertex -122.471 -124.918 0 + vertex -122.471 -124.918 -3 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -122.434 -125.124 -3 + vertex -122.434 -125.124 0 + vertex -122.471 -124.918 0 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -122.384 -125.327 -3 + vertex -122.434 -125.124 0 + vertex -122.434 -125.124 -3 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -122.384 -125.327 -3 + vertex -122.384 -125.327 0 + vertex -122.434 -125.124 0 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -122.319 -125.526 -3 + vertex -122.384 -125.327 0 + vertex -122.384 -125.327 -3 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -122.319 -125.526 -3 + vertex -122.319 -125.526 0 + vertex -122.384 -125.327 0 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -122.241 -125.72 -3 + vertex -122.319 -125.526 0 + vertex -122.319 -125.526 -3 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -122.241 -125.72 -3 + vertex -122.241 -125.72 0 + vertex -122.319 -125.526 0 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -122.149 -125.908 -3 + vertex -122.241 -125.72 0 + vertex -122.241 -125.72 -3 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -122.149 -125.908 -3 + vertex -122.149 -125.908 0 + vertex -122.241 -125.72 0 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -122.044 -126.09 -3 + vertex -122.149 -125.908 0 + vertex -122.149 -125.908 -3 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -122.044 -126.09 -3 + vertex -122.044 -126.09 0 + vertex -122.149 -125.908 0 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -121.927 -126.263 -3 + vertex -122.044 -126.09 0 + vertex -122.044 -126.09 -3 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -121.927 -126.263 -3 + vertex -121.927 -126.263 0 + vertex -122.044 -126.09 0 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -121.798 -126.428 -3 + vertex -121.927 -126.263 0 + vertex -121.927 -126.263 -3 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -121.798 -126.428 -3 + vertex -121.798 -126.428 0 + vertex -121.927 -126.263 0 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -121.658 -126.584 -3 + vertex -121.798 -126.428 0 + vertex -121.798 -126.428 -3 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -121.658 -126.584 -3 + vertex -121.658 -126.584 0 + vertex -121.798 -126.428 0 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -121.507 -126.729 -3 + vertex -121.658 -126.584 0 + vertex -121.658 -126.584 -3 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -121.507 -126.729 -3 + vertex -121.507 -126.729 0 + vertex -121.658 -126.584 0 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -121.347 -126.864 -3 + vertex -121.507 -126.729 0 + vertex -121.507 -126.729 -3 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -121.347 -126.864 -3 + vertex -121.347 -126.864 0 + vertex -121.507 -126.729 0 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -121.178 -126.987 -3 + vertex -121.347 -126.864 0 + vertex -121.347 -126.864 -3 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -121.178 -126.987 -3 + vertex -121.178 -126.987 0 + vertex -121.347 -126.864 0 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -121 -127.098 -3 + vertex -121.178 -126.987 0 + vertex -121.178 -126.987 -3 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -121 -127.098 -3 + vertex -121 -127.098 0 + vertex -121.178 -126.987 0 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -120.815 -127.196 -3 + vertex -121 -127.098 0 + vertex -121 -127.098 -3 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -120.815 -127.196 -3 + vertex -120.815 -127.196 0 + vertex -121 -127.098 0 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -120.624 -127.282 -3 + vertex -120.815 -127.196 0 + vertex -120.815 -127.196 -3 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -120.624 -127.282 -3 + vertex -120.624 -127.282 0 + vertex -120.815 -127.196 0 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -120.427 -127.353 -3 + vertex -120.624 -127.282 0 + vertex -120.624 -127.282 -3 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -120.427 -127.353 -3 + vertex -120.427 -127.353 0 + vertex -120.624 -127.282 0 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -120.226 -127.411 -3 + vertex -120.427 -127.353 0 + vertex -120.427 -127.353 -3 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -120.226 -127.411 -3 + vertex -120.226 -127.411 0 + vertex -120.427 -127.353 0 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -120.021 -127.454 -3 + vertex -120.226 -127.411 0 + vertex -120.226 -127.411 -3 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -120.021 -127.454 -3 + vertex -120.021 -127.454 0 + vertex -120.226 -127.411 0 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -119.814 -127.484 -3 + vertex -120.021 -127.454 0 + vertex -120.021 -127.454 -3 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -119.814 -127.484 -3 + vertex -119.814 -127.484 0 + vertex -120.021 -127.454 0 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -119.605 -127.498 -3 + vertex -119.814 -127.484 0 + vertex -119.814 -127.484 -3 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -119.605 -127.498 -3 + vertex -119.605 -127.498 0 + vertex -119.814 -127.484 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -119.502 -127.498 -3 + vertex -119.605 -127.498 0 + vertex -119.605 -127.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -119.502 -127.498 -3 + vertex -119.502 -127.498 0 + vertex -119.605 -127.498 0 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -119.5 -127.5 -3 + vertex -119.502 -127.498 0 + vertex -119.502 -127.498 -3 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -119.5 -127.5 -3 + vertex -119.5 -127.5 0 + vertex -119.502 -127.498 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 119.5 -127.5 -3 + vertex -119.5 -127.5 0 + vertex -119.5 -127.5 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 119.5 -127.5 -3 + vertex 119.5 -127.5 0 + vertex -119.5 -127.5 0 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 119.502 -127.498 -3 + vertex 119.5 -127.5 0 + vertex 119.5 -127.5 -3 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 119.502 -127.498 -3 + vertex 119.502 -127.498 0 + vertex 119.5 -127.5 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/resources/profiles/Creality/cr8.svg b/resources/profiles/Creality/cr8.svg new file mode 100644 index 0000000000..0dbcc9ace9 --- /dev/null +++ b/resources/profiles/Creality/cr8.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/cr8_bed.stl b/resources/profiles/Creality/cr8_bed.stl new file mode 100644 index 0000000000..f5a8cac683 --- /dev/null +++ b/resources/profiles/Creality/cr8_bed.stl @@ -0,0 +1,2774 @@ +solid OpenSCAD_Model + facet normal 0 0 -1 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.502 -117.498 -3 + vertex 114.814 -117.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.502 -117.498 -3 + vertex 115.021 -117.454 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.5 -114.5 -3 + vertex 114.502 -117.498 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.021 -117.454 -3 + vertex 114.502 -117.498 -3 + vertex 115.226 -117.411 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.226 -117.411 -3 + vertex 114.502 -117.498 -3 + vertex 115.427 -117.353 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.427 -117.353 -3 + vertex 114.502 -117.498 -3 + vertex 115.624 -117.282 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.624 -117.282 -3 + vertex 114.502 -117.498 -3 + vertex 115.815 -117.196 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.815 -117.196 -3 + vertex 114.502 -117.498 -3 + vertex 116 -117.098 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116 -117.098 -3 + vertex 114.502 -117.498 -3 + vertex 116.178 -116.987 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.178 -116.987 -3 + vertex 114.502 -117.498 -3 + vertex 116.347 -116.864 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.347 -116.864 -3 + vertex 114.502 -117.498 -3 + vertex 116.507 -116.729 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.507 -116.729 -3 + vertex 114.502 -117.498 -3 + vertex 116.658 -116.584 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.658 -116.584 -3 + vertex 114.502 -117.498 -3 + vertex 116.798 -116.428 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.798 -116.428 -3 + vertex 114.502 -117.498 -3 + vertex 116.927 -116.263 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.927 -116.263 -3 + vertex 114.502 -117.498 -3 + vertex 117.044 -116.09 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.044 -116.09 -3 + vertex 114.502 -117.498 -3 + vertex 117.149 -115.908 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.149 -115.908 -3 + vertex 114.502 -117.498 -3 + vertex 117.241 -115.72 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.241 -115.72 -3 + vertex 114.502 -117.498 -3 + vertex 117.319 -115.526 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.319 -115.526 -3 + vertex 114.502 -117.498 -3 + vertex 117.384 -115.327 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.384 -115.327 -3 + vertex 114.502 -117.498 -3 + vertex 117.434 -115.124 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.434 -115.124 -3 + vertex 114.502 -117.498 -3 + vertex 117.471 -114.918 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.471 -114.918 -3 + vertex 114.502 -117.498 -3 + vertex 117.493 -114.709 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.493 -114.709 -3 + vertex 114.502 -117.498 -3 + vertex 117.5 -114.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.5 -114.5 -3 + vertex 114.502 117.498 -3 + vertex 117.5 114.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 117.471 114.918 -3 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.384 115.327 -3 + vertex 117.434 115.124 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.241 115.72 -3 + vertex 114.502 117.498 -3 + vertex 117.149 115.908 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.241 115.72 -3 + vertex 117.319 115.526 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 116.507 116.729 -3 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.927 116.263 -3 + vertex 114.502 117.498 -3 + vertex 116.798 116.428 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 116.927 116.263 -3 + vertex 117.044 116.09 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.798 116.428 -3 + vertex 114.502 117.498 -3 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 115.427 117.353 -3 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.347 116.864 -3 + vertex 114.502 117.498 -3 + vertex 116.178 116.987 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 116.347 116.864 -3 + vertex 116.507 116.729 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.178 116.987 -3 + vertex 114.502 117.498 -3 + vertex 116 117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116 117.098 -3 + vertex 114.502 117.498 -3 + vertex 115.815 117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 115.815 117.196 -3 + vertex 114.502 117.498 -3 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.149 115.908 -3 + vertex 114.502 117.498 -3 + vertex 117.044 116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 115.226 117.411 -3 + vertex 114.502 117.498 -3 + vertex 115.021 117.454 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 115.226 117.411 -3 + vertex 115.427 117.353 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.319 115.526 -3 + vertex 117.384 115.327 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 114.814 117.484 -3 + vertex 115.021 117.454 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 117.434 115.124 -3 + vertex 117.471 114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 114.605 117.498 -3 + vertex 114.814 117.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.5 114.5 -3 + vertex 114.502 117.498 -3 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -114.5 117.5 -3 + vertex 114.5 117.5 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex 114.5 117.5 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex -114.502 117.498 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 114.5 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -114.814 117.484 -3 + vertex -114.605 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.021 117.454 -3 + vertex -114.814 117.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.226 117.411 -3 + vertex -115.021 117.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.427 117.353 -3 + vertex -115.226 117.411 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.624 117.282 -3 + vertex -115.427 117.353 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.815 117.196 -3 + vertex -115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116 117.098 -3 + vertex -115.815 117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.178 116.987 -3 + vertex -116 117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.347 116.864 -3 + vertex -116.178 116.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.507 116.729 -3 + vertex -116.347 116.864 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.658 116.584 -3 + vertex -116.507 116.729 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.798 116.428 -3 + vertex -116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.927 116.263 -3 + vertex -116.798 116.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.044 116.09 -3 + vertex -116.927 116.263 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.149 115.908 -3 + vertex -117.044 116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.241 115.72 -3 + vertex -117.149 115.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.319 115.526 -3 + vertex -117.241 115.72 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.384 115.327 -3 + vertex -117.319 115.526 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.434 115.124 -3 + vertex -117.384 115.327 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.471 114.918 -3 + vertex -117.434 115.124 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.493 114.709 -3 + vertex -117.471 114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.5 114.5 -3 + vertex -117.493 114.709 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.5 114.5 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex -114.502 -117.498 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.471 -114.918 -3 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.434 -115.124 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.241 -115.72 -3 + vertex -114.502 -117.498 -3 + vertex -117.149 -115.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.319 -115.526 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -116.507 -116.729 -3 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.927 -116.263 -3 + vertex -114.502 -117.498 -3 + vertex -116.798 -116.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.927 -116.263 -3 + vertex -117.044 -116.09 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.798 -116.428 -3 + vertex -114.502 -117.498 -3 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -115.427 -117.353 -3 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.347 -116.864 -3 + vertex -114.502 -117.498 -3 + vertex -116.178 -116.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.507 -116.729 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.178 -116.987 -3 + vertex -114.502 -117.498 -3 + vertex -116 -117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116 -117.098 -3 + vertex -114.502 -117.498 -3 + vertex -115.815 -117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.815 -117.196 -3 + vertex -114.502 -117.498 -3 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.149 -115.908 -3 + vertex -114.502 -117.498 -3 + vertex -117.044 -116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.226 -117.411 -3 + vertex -114.502 -117.498 -3 + vertex -115.021 -117.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.427 -117.353 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.384 -115.327 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.814 -117.484 -3 + vertex -115.021 -117.454 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.434 -115.124 -3 + vertex -117.471 -114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.605 -117.498 -3 + vertex -114.814 -117.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.5 -117.5 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex 114.5 -117.5 -3 + vertex -114.5 -117.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.5 -114.5 -3 + vertex -114.502 -117.498 -3 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.814 -117.484 0 + vertex 114.502 -117.498 0 + vertex 114.605 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.021 -117.454 0 + vertex 114.502 -117.498 0 + vertex 114.814 -117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 114.502 -117.498 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.226 -117.411 0 + vertex 114.502 -117.498 0 + vertex 115.021 -117.454 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.427 -117.353 0 + vertex 114.502 -117.498 0 + vertex 115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 -117.282 0 + vertex 114.502 -117.498 0 + vertex 115.427 -117.353 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.815 -117.196 0 + vertex 114.502 -117.498 0 + vertex 115.624 -117.282 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116 -117.098 0 + vertex 114.502 -117.498 0 + vertex 115.815 -117.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.178 -116.987 0 + vertex 114.502 -117.498 0 + vertex 116 -117.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.347 -116.864 0 + vertex 114.502 -117.498 0 + vertex 116.178 -116.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.507 -116.729 0 + vertex 114.502 -117.498 0 + vertex 116.347 -116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 -116.584 0 + vertex 114.502 -117.498 0 + vertex 116.507 -116.729 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.798 -116.428 0 + vertex 114.502 -117.498 0 + vertex 116.658 -116.584 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.927 -116.263 0 + vertex 114.502 -117.498 0 + vertex 116.798 -116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.044 -116.09 0 + vertex 114.502 -117.498 0 + vertex 116.927 -116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.149 -115.908 0 + vertex 114.502 -117.498 0 + vertex 117.044 -116.09 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.241 -115.72 0 + vertex 114.502 -117.498 0 + vertex 117.149 -115.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.319 -115.526 0 + vertex 114.502 -117.498 0 + vertex 117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.384 -115.327 0 + vertex 114.502 -117.498 0 + vertex 117.319 -115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.434 -115.124 0 + vertex 114.502 -117.498 0 + vertex 117.384 -115.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.471 -114.918 0 + vertex 114.502 -117.498 0 + vertex 117.434 -115.124 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 -114.709 0 + vertex 114.502 -117.498 0 + vertex 117.471 -114.918 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.5 -114.5 0 + vertex 114.502 -117.498 0 + vertex 117.493 -114.709 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.5 114.5 0 + vertex 114.502 117.498 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 114.709 0 + vertex 117.471 114.918 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.434 115.124 0 + vertex 117.384 115.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.149 115.908 0 + vertex 114.502 117.498 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.319 115.526 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 116.584 0 + vertex 116.507 116.729 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.798 116.428 0 + vertex 114.502 117.498 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.044 116.09 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 116.584 0 + vertex 114.502 117.498 0 + vertex 116.798 116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 117.282 0 + vertex 115.427 117.353 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.178 116.987 0 + vertex 114.502 117.498 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 116.507 116.729 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116 117.098 0 + vertex 114.502 117.498 0 + vertex 116.178 116.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.815 117.196 0 + vertex 114.502 117.498 0 + vertex 116 117.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 117.282 0 + vertex 114.502 117.498 0 + vertex 115.815 117.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.044 116.09 0 + vertex 114.502 117.498 0 + vertex 117.149 115.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.021 117.454 0 + vertex 114.502 117.498 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 115.427 117.353 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.384 115.327 0 + vertex 117.319 115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 115.021 117.454 0 + vertex 114.814 117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.471 114.918 0 + vertex 117.434 115.124 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.814 117.484 0 + vertex 114.605 117.498 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 114.709 0 + vertex 114.502 117.498 0 + vertex 117.5 114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex 114.5 117.5 0 + vertex -114.5 117.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 114.5 117.5 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex -114.502 117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.5 114.5 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.605 117.498 0 + vertex -114.814 117.484 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.814 117.484 0 + vertex -115.021 117.454 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.021 117.454 0 + vertex -115.226 117.411 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.226 117.411 0 + vertex -115.427 117.353 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.427 117.353 0 + vertex -115.624 117.282 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.624 117.282 0 + vertex -115.815 117.196 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.815 117.196 0 + vertex -116 117.098 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116 117.098 0 + vertex -116.178 116.987 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.178 116.987 0 + vertex -116.347 116.864 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.347 116.864 0 + vertex -116.507 116.729 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.507 116.729 0 + vertex -116.658 116.584 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.658 116.584 0 + vertex -116.798 116.428 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.798 116.428 0 + vertex -116.927 116.263 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.927 116.263 0 + vertex -117.044 116.09 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.044 116.09 0 + vertex -117.149 115.908 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.149 115.908 0 + vertex -117.241 115.72 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.241 115.72 0 + vertex -117.319 115.526 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.319 115.526 0 + vertex -117.384 115.327 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.384 115.327 0 + vertex -117.434 115.124 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.434 115.124 0 + vertex -117.471 114.918 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.471 114.918 0 + vertex -117.493 114.709 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.493 114.709 0 + vertex -117.5 114.5 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex -117.5 114.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex -114.502 -117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -117.493 -114.709 0 + vertex -117.471 -114.918 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.434 -115.124 0 + vertex -117.384 -115.327 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.149 -115.908 0 + vertex -114.502 -117.498 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.319 -115.526 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -116.658 -116.584 0 + vertex -116.507 -116.729 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.798 -116.428 0 + vertex -114.502 -117.498 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.044 -116.09 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.658 -116.584 0 + vertex -114.502 -117.498 0 + vertex -116.798 -116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -115.624 -117.282 0 + vertex -115.427 -117.353 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.178 -116.987 0 + vertex -114.502 -117.498 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -116.507 -116.729 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116 -117.098 0 + vertex -114.502 -117.498 0 + vertex -116.178 -116.987 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.815 -117.196 0 + vertex -114.502 -117.498 0 + vertex -116 -117.098 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.624 -117.282 0 + vertex -114.502 -117.498 0 + vertex -115.815 -117.196 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.044 -116.09 0 + vertex -114.502 -117.498 0 + vertex -117.149 -115.908 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.021 -117.454 0 + vertex -114.502 -117.498 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -115.427 -117.353 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.384 -115.327 0 + vertex -117.319 -115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -115.021 -117.454 0 + vertex -114.814 -117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -117.471 -114.918 0 + vertex -117.434 -115.124 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.814 -117.484 0 + vertex -114.605 -117.498 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex 114.5 -117.5 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -114.5 -117.5 0 + vertex 114.5 -117.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.493 -114.709 0 + vertex -114.502 -117.498 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.502 -117.498 0 + vertex 114.502 -117.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.605 -117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.605 -117.498 0 + vertex 114.605 -117.498 -3 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.814 -117.484 0 + vertex 114.605 -117.498 0 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 115.021 -117.454 -3 + vertex 114.814 -117.484 0 + vertex 114.814 -117.484 -3 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 115.021 -117.454 -3 + vertex 115.021 -117.454 0 + vertex 114.814 -117.484 0 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 115.226 -117.411 -3 + vertex 115.021 -117.454 0 + vertex 115.021 -117.454 -3 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 115.226 -117.411 -3 + vertex 115.226 -117.411 0 + vertex 115.021 -117.454 0 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 115.427 -117.353 -3 + vertex 115.226 -117.411 0 + vertex 115.226 -117.411 -3 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 115.427 -117.353 -3 + vertex 115.427 -117.353 0 + vertex 115.226 -117.411 0 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 115.624 -117.282 -3 + vertex 115.427 -117.353 0 + vertex 115.427 -117.353 -3 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 115.624 -117.282 -3 + vertex 115.624 -117.282 0 + vertex 115.427 -117.353 0 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 115.815 -117.196 -3 + vertex 115.624 -117.282 0 + vertex 115.624 -117.282 -3 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 115.815 -117.196 -3 + vertex 115.815 -117.196 0 + vertex 115.624 -117.282 0 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 116 -117.098 -3 + vertex 115.815 -117.196 0 + vertex 115.815 -117.196 -3 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 116 -117.098 -3 + vertex 116 -117.098 0 + vertex 115.815 -117.196 0 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 116.178 -116.987 -3 + vertex 116 -117.098 0 + vertex 116 -117.098 -3 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 116.178 -116.987 -3 + vertex 116.178 -116.987 0 + vertex 116 -117.098 0 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 116.347 -116.864 -3 + vertex 116.178 -116.987 0 + vertex 116.178 -116.987 -3 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 116.347 -116.864 -3 + vertex 116.347 -116.864 0 + vertex 116.178 -116.987 0 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 116.507 -116.729 -3 + vertex 116.347 -116.864 0 + vertex 116.347 -116.864 -3 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 116.507 -116.729 -3 + vertex 116.507 -116.729 0 + vertex 116.347 -116.864 0 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 116.658 -116.584 -3 + vertex 116.507 -116.729 0 + vertex 116.507 -116.729 -3 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 116.658 -116.584 -3 + vertex 116.658 -116.584 0 + vertex 116.507 -116.729 0 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 116.798 -116.428 -3 + vertex 116.658 -116.584 0 + vertex 116.658 -116.584 -3 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 116.798 -116.428 -3 + vertex 116.798 -116.428 0 + vertex 116.658 -116.584 0 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 116.927 -116.263 -3 + vertex 116.798 -116.428 0 + vertex 116.798 -116.428 -3 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 116.927 -116.263 -3 + vertex 116.927 -116.263 0 + vertex 116.798 -116.428 0 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 117.044 -116.09 -3 + vertex 116.927 -116.263 0 + vertex 116.927 -116.263 -3 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 117.044 -116.09 -3 + vertex 117.044 -116.09 0 + vertex 116.927 -116.263 0 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 117.149 -115.908 -3 + vertex 117.044 -116.09 0 + vertex 117.044 -116.09 -3 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 117.149 -115.908 -3 + vertex 117.149 -115.908 0 + vertex 117.044 -116.09 0 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 117.241 -115.72 -3 + vertex 117.149 -115.908 0 + vertex 117.149 -115.908 -3 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 117.241 -115.72 -3 + vertex 117.241 -115.72 0 + vertex 117.149 -115.908 0 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 117.319 -115.526 -3 + vertex 117.241 -115.72 0 + vertex 117.241 -115.72 -3 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 117.319 -115.526 -3 + vertex 117.319 -115.526 0 + vertex 117.241 -115.72 0 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 117.384 -115.327 -3 + vertex 117.319 -115.526 0 + vertex 117.319 -115.526 -3 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 117.384 -115.327 -3 + vertex 117.384 -115.327 0 + vertex 117.319 -115.526 0 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 117.434 -115.124 -3 + vertex 117.384 -115.327 0 + vertex 117.384 -115.327 -3 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 117.434 -115.124 -3 + vertex 117.434 -115.124 0 + vertex 117.384 -115.327 0 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 117.471 -114.918 -3 + vertex 117.434 -115.124 0 + vertex 117.434 -115.124 -3 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 117.471 -114.918 -3 + vertex 117.471 -114.918 0 + vertex 117.434 -115.124 0 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 117.493 -114.709 -3 + vertex 117.471 -114.918 0 + vertex 117.471 -114.918 -3 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 117.493 -114.709 -3 + vertex 117.493 -114.709 0 + vertex 117.471 -114.918 0 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 117.5 -114.5 -3 + vertex 117.493 -114.709 0 + vertex 117.493 -114.709 -3 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 117.5 -114.5 -3 + vertex 117.5 -114.5 0 + vertex 117.493 -114.709 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 117.5 114.5 -3 + vertex 117.5 -114.5 0 + vertex 117.5 -114.5 -3 + endloop + endfacet + facet normal 1 0 -0 + outer loop + vertex 117.5 114.5 -3 + vertex 117.5 114.5 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0.99944 0.0334741 0 + outer loop + vertex 117.493 114.709 -3 + vertex 117.5 114.5 0 + vertex 117.5 114.5 -3 + endloop + endfacet + facet normal 0.99944 0.0334741 -0 + outer loop + vertex 117.493 114.709 -3 + vertex 117.493 114.709 0 + vertex 117.5 114.5 0 + endloop + endfacet + facet normal 0.994505 0.104685 0 + outer loop + vertex 117.471 114.918 -3 + vertex 117.493 114.709 0 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal 0.994505 0.104685 -0 + outer loop + vertex 117.471 114.918 -3 + vertex 117.471 114.918 0 + vertex 117.493 114.709 0 + endloop + endfacet + facet normal 0.98425 0.176783 0 + outer loop + vertex 117.434 115.124 -3 + vertex 117.471 114.918 0 + vertex 117.471 114.918 -3 + endloop + endfacet + facet normal 0.98425 0.176783 -0 + outer loop + vertex 117.434 115.124 -3 + vertex 117.434 115.124 0 + vertex 117.471 114.918 0 + endloop + endfacet + facet normal 0.970981 0.239158 0 + outer loop + vertex 117.384 115.327 -3 + vertex 117.434 115.124 0 + vertex 117.434 115.124 -3 + endloop + endfacet + facet normal 0.970981 0.239158 -0 + outer loop + vertex 117.384 115.327 -3 + vertex 117.384 115.327 0 + vertex 117.434 115.124 0 + endloop + endfacet + facet normal 0.950577 0.31049 0 + outer loop + vertex 117.319 115.526 -3 + vertex 117.384 115.327 0 + vertex 117.384 115.327 -3 + endloop + endfacet + facet normal 0.950577 0.31049 -0 + outer loop + vertex 117.319 115.526 -3 + vertex 117.319 115.526 0 + vertex 117.384 115.327 0 + endloop + endfacet + facet normal 0.927816 0.373039 0 + outer loop + vertex 117.241 115.72 -3 + vertex 117.319 115.526 0 + vertex 117.319 115.526 -3 + endloop + endfacet + facet normal 0.927816 0.373039 -0 + outer loop + vertex 117.241 115.72 -3 + vertex 117.241 115.72 0 + vertex 117.319 115.526 0 + endloop + endfacet + facet normal 0.898217 0.439553 0 + outer loop + vertex 117.149 115.908 -3 + vertex 117.241 115.72 0 + vertex 117.241 115.72 -3 + endloop + endfacet + facet normal 0.898217 0.439553 -0 + outer loop + vertex 117.149 115.908 -3 + vertex 117.149 115.908 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0.866186 0.499722 0 + outer loop + vertex 117.044 116.09 -3 + vertex 117.149 115.908 0 + vertex 117.149 115.908 -3 + endloop + endfacet + facet normal 0.866186 0.499722 -0 + outer loop + vertex 117.044 116.09 -3 + vertex 117.044 116.09 0 + vertex 117.149 115.908 0 + endloop + endfacet + facet normal 0.828349 0.560213 0 + outer loop + vertex 116.927 116.263 -3 + vertex 117.044 116.09 0 + vertex 117.044 116.09 -3 + endloop + endfacet + facet normal 0.828349 0.560213 -0 + outer loop + vertex 116.927 116.263 -3 + vertex 116.927 116.263 0 + vertex 117.044 116.09 0 + endloop + endfacet + facet normal 0.787807 0.615922 0 + outer loop + vertex 116.798 116.428 -3 + vertex 116.927 116.263 0 + vertex 116.927 116.263 -3 + endloop + endfacet + facet normal 0.787807 0.615922 -0 + outer loop + vertex 116.798 116.428 -3 + vertex 116.798 116.428 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0.744242 0.66791 0 + outer loop + vertex 116.658 116.584 -3 + vertex 116.798 116.428 0 + vertex 116.798 116.428 -3 + endloop + endfacet + facet normal 0.744242 0.66791 -0 + outer loop + vertex 116.658 116.584 -3 + vertex 116.658 116.584 0 + vertex 116.798 116.428 0 + endloop + endfacet + facet normal 0.692631 0.721292 0 + outer loop + vertex 116.507 116.729 -3 + vertex 116.658 116.584 0 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0.692631 0.721292 -0 + outer loop + vertex 116.507 116.729 -3 + vertex 116.507 116.729 0 + vertex 116.658 116.584 0 + endloop + endfacet + facet normal 0.644871 0.764291 0 + outer loop + vertex 116.347 116.864 -3 + vertex 116.507 116.729 0 + vertex 116.507 116.729 -3 + endloop + endfacet + facet normal 0.644871 0.764291 -0 + outer loop + vertex 116.347 116.864 -3 + vertex 116.347 116.864 0 + vertex 116.507 116.729 0 + endloop + endfacet + facet normal 0.588456 0.808529 0 + outer loop + vertex 116.178 116.987 -3 + vertex 116.347 116.864 0 + vertex 116.347 116.864 -3 + endloop + endfacet + facet normal 0.588456 0.808529 -0 + outer loop + vertex 116.178 116.987 -3 + vertex 116.178 116.987 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0.529142 0.848533 0 + outer loop + vertex 116 117.098 -3 + vertex 116.178 116.987 0 + vertex 116.178 116.987 -3 + endloop + endfacet + facet normal 0.529142 0.848533 -0 + outer loop + vertex 116 117.098 -3 + vertex 116 117.098 0 + vertex 116.178 116.987 0 + endloop + endfacet + facet normal 0.468107 0.883672 0 + outer loop + vertex 115.815 117.196 -3 + vertex 116 117.098 0 + vertex 116 117.098 -3 + endloop + endfacet + facet normal 0.468107 0.883672 -0 + outer loop + vertex 115.815 117.196 -3 + vertex 115.815 117.196 0 + vertex 116 117.098 0 + endloop + endfacet + facet normal 0.410563 0.911832 0 + outer loop + vertex 115.624 117.282 -3 + vertex 115.815 117.196 0 + vertex 115.815 117.196 -3 + endloop + endfacet + facet normal 0.410563 0.911832 -0 + outer loop + vertex 115.624 117.282 -3 + vertex 115.624 117.282 0 + vertex 115.815 117.196 0 + endloop + endfacet + facet normal 0.339058 0.940766 0 + outer loop + vertex 115.427 117.353 -3 + vertex 115.624 117.282 0 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0.339058 0.940766 -0 + outer loop + vertex 115.427 117.353 -3 + vertex 115.427 117.353 0 + vertex 115.624 117.282 0 + endloop + endfacet + facet normal 0.277246 0.960799 0 + outer loop + vertex 115.226 117.411 -3 + vertex 115.427 117.353 0 + vertex 115.427 117.353 -3 + endloop + endfacet + facet normal 0.277246 0.960799 -0 + outer loop + vertex 115.226 117.411 -3 + vertex 115.226 117.411 0 + vertex 115.427 117.353 0 + endloop + endfacet + facet normal 0.205289 0.978701 0 + outer loop + vertex 115.021 117.454 -3 + vertex 115.226 117.411 0 + vertex 115.226 117.411 -3 + endloop + endfacet + facet normal 0.205289 0.978701 -0 + outer loop + vertex 115.021 117.454 -3 + vertex 115.021 117.454 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0.143429 0.989661 0 + outer loop + vertex 114.814 117.484 -3 + vertex 115.021 117.454 0 + vertex 115.021 117.454 -3 + endloop + endfacet + facet normal 0.143429 0.989661 -0 + outer loop + vertex 114.814 117.484 -3 + vertex 114.814 117.484 0 + vertex 115.021 117.454 0 + endloop + endfacet + facet normal 0.0668359 0.997764 0 + outer loop + vertex 114.605 117.498 -3 + vertex 114.814 117.484 0 + vertex 114.814 117.484 -3 + endloop + endfacet + facet normal 0.0668359 0.997764 -0 + outer loop + vertex 114.605 117.498 -3 + vertex 114.605 117.498 0 + vertex 114.814 117.484 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 114.502 117.498 -3 + vertex 114.605 117.498 0 + vertex 114.605 117.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 114.502 117.498 -3 + vertex 114.502 117.498 0 + vertex 114.605 117.498 0 + endloop + endfacet + facet normal 0.707107 0.707107 0 + outer loop + vertex 114.5 117.5 -3 + vertex 114.502 117.498 0 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0.707107 0.707107 -0 + outer loop + vertex 114.5 117.5 -3 + vertex 114.5 117.5 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.5 117.5 -3 + vertex 114.5 117.5 0 + vertex 114.5 117.5 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.5 117.5 -3 + vertex -114.5 117.5 0 + vertex 114.5 117.5 0 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -114.502 117.498 -3 + vertex -114.5 117.5 0 + vertex -114.5 117.5 -3 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -114.502 117.498 -3 + vertex -114.502 117.498 0 + vertex -114.5 117.5 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.605 117.498 -3 + vertex -114.502 117.498 0 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.605 117.498 -3 + vertex -114.605 117.498 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -114.814 117.484 -3 + vertex -114.605 117.498 0 + vertex -114.605 117.498 -3 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -114.814 117.484 -3 + vertex -114.814 117.484 0 + vertex -114.605 117.498 0 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -115.021 117.454 -3 + vertex -114.814 117.484 0 + vertex -114.814 117.484 -3 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -115.021 117.454 -3 + vertex -115.021 117.454 0 + vertex -114.814 117.484 0 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -115.226 117.411 -3 + vertex -115.021 117.454 0 + vertex -115.021 117.454 -3 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -115.226 117.411 -3 + vertex -115.226 117.411 0 + vertex -115.021 117.454 0 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -115.427 117.353 -3 + vertex -115.226 117.411 0 + vertex -115.226 117.411 -3 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -115.427 117.353 -3 + vertex -115.427 117.353 0 + vertex -115.226 117.411 0 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -115.624 117.282 -3 + vertex -115.427 117.353 0 + vertex -115.427 117.353 -3 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -115.624 117.282 -3 + vertex -115.624 117.282 0 + vertex -115.427 117.353 0 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -115.815 117.196 -3 + vertex -115.624 117.282 0 + vertex -115.624 117.282 -3 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -115.815 117.196 -3 + vertex -115.815 117.196 0 + vertex -115.624 117.282 0 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -116 117.098 -3 + vertex -115.815 117.196 0 + vertex -115.815 117.196 -3 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -116 117.098 -3 + vertex -116 117.098 0 + vertex -115.815 117.196 0 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -116.178 116.987 -3 + vertex -116 117.098 0 + vertex -116 117.098 -3 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -116.178 116.987 -3 + vertex -116.178 116.987 0 + vertex -116 117.098 0 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -116.347 116.864 -3 + vertex -116.178 116.987 0 + vertex -116.178 116.987 -3 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -116.347 116.864 -3 + vertex -116.347 116.864 0 + vertex -116.178 116.987 0 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -116.507 116.729 -3 + vertex -116.347 116.864 0 + vertex -116.347 116.864 -3 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -116.507 116.729 -3 + vertex -116.507 116.729 0 + vertex -116.347 116.864 0 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -116.658 116.584 -3 + vertex -116.507 116.729 0 + vertex -116.507 116.729 -3 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -116.658 116.584 -3 + vertex -116.658 116.584 0 + vertex -116.507 116.729 0 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -116.798 116.428 -3 + vertex -116.658 116.584 0 + vertex -116.658 116.584 -3 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -116.798 116.428 -3 + vertex -116.798 116.428 0 + vertex -116.658 116.584 0 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -116.927 116.263 -3 + vertex -116.798 116.428 0 + vertex -116.798 116.428 -3 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -116.927 116.263 -3 + vertex -116.927 116.263 0 + vertex -116.798 116.428 0 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -117.044 116.09 -3 + vertex -116.927 116.263 0 + vertex -116.927 116.263 -3 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -117.044 116.09 -3 + vertex -117.044 116.09 0 + vertex -116.927 116.263 0 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -117.149 115.908 -3 + vertex -117.044 116.09 0 + vertex -117.044 116.09 -3 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -117.149 115.908 -3 + vertex -117.149 115.908 0 + vertex -117.044 116.09 0 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -117.241 115.72 -3 + vertex -117.149 115.908 0 + vertex -117.149 115.908 -3 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -117.241 115.72 -3 + vertex -117.241 115.72 0 + vertex -117.149 115.908 0 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -117.319 115.526 -3 + vertex -117.241 115.72 0 + vertex -117.241 115.72 -3 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -117.319 115.526 -3 + vertex -117.319 115.526 0 + vertex -117.241 115.72 0 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -117.384 115.327 -3 + vertex -117.319 115.526 0 + vertex -117.319 115.526 -3 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -117.384 115.327 -3 + vertex -117.384 115.327 0 + vertex -117.319 115.526 0 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -117.434 115.124 -3 + vertex -117.384 115.327 0 + vertex -117.384 115.327 -3 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -117.434 115.124 -3 + vertex -117.434 115.124 0 + vertex -117.384 115.327 0 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -117.471 114.918 -3 + vertex -117.434 115.124 0 + vertex -117.434 115.124 -3 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -117.471 114.918 -3 + vertex -117.471 114.918 0 + vertex -117.434 115.124 0 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -117.493 114.709 -3 + vertex -117.471 114.918 0 + vertex -117.471 114.918 -3 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -117.493 114.709 -3 + vertex -117.493 114.709 0 + vertex -117.471 114.918 0 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -117.5 114.5 -3 + vertex -117.493 114.709 0 + vertex -117.493 114.709 -3 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -117.5 114.5 -3 + vertex -117.5 114.5 0 + vertex -117.493 114.709 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 114.5 0 + vertex -117.5 114.5 -3 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 -114.5 0 + vertex -117.5 114.5 0 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -117.493 -114.709 -3 + vertex -117.5 -114.5 0 + vertex -117.5 -114.5 -3 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -117.493 -114.709 -3 + vertex -117.493 -114.709 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -117.471 -114.918 -3 + vertex -117.493 -114.709 0 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -117.471 -114.918 -3 + vertex -117.471 -114.918 0 + vertex -117.493 -114.709 0 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -117.434 -115.124 -3 + vertex -117.471 -114.918 0 + vertex -117.471 -114.918 -3 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -117.434 -115.124 -3 + vertex -117.434 -115.124 0 + vertex -117.471 -114.918 0 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.434 -115.124 0 + vertex -117.434 -115.124 -3 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.384 -115.327 0 + vertex -117.434 -115.124 0 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.384 -115.327 0 + vertex -117.384 -115.327 -3 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.319 -115.526 0 + vertex -117.384 -115.327 0 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.319 -115.526 0 + vertex -117.319 -115.526 -3 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.241 -115.72 0 + vertex -117.319 -115.526 0 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -117.149 -115.908 -3 + vertex -117.241 -115.72 0 + vertex -117.241 -115.72 -3 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -117.149 -115.908 -3 + vertex -117.149 -115.908 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -117.044 -116.09 -3 + vertex -117.149 -115.908 0 + vertex -117.149 -115.908 -3 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -117.044 -116.09 -3 + vertex -117.044 -116.09 0 + vertex -117.149 -115.908 0 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -116.927 -116.263 -3 + vertex -117.044 -116.09 0 + vertex -117.044 -116.09 -3 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -116.927 -116.263 -3 + vertex -116.927 -116.263 0 + vertex -117.044 -116.09 0 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -116.798 -116.428 -3 + vertex -116.927 -116.263 0 + vertex -116.927 -116.263 -3 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -116.798 -116.428 -3 + vertex -116.798 -116.428 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -116.658 -116.584 -3 + vertex -116.798 -116.428 0 + vertex -116.798 -116.428 -3 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -116.658 -116.584 -3 + vertex -116.658 -116.584 0 + vertex -116.798 -116.428 0 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -116.507 -116.729 -3 + vertex -116.658 -116.584 0 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -116.507 -116.729 -3 + vertex -116.507 -116.729 0 + vertex -116.658 -116.584 0 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.507 -116.729 0 + vertex -116.507 -116.729 -3 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.347 -116.864 0 + vertex -116.507 -116.729 0 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -116.178 -116.987 -3 + vertex -116.347 -116.864 0 + vertex -116.347 -116.864 -3 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -116.178 -116.987 -3 + vertex -116.178 -116.987 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -116 -117.098 -3 + vertex -116.178 -116.987 0 + vertex -116.178 -116.987 -3 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -116 -117.098 -3 + vertex -116 -117.098 0 + vertex -116.178 -116.987 0 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -115.815 -117.196 -3 + vertex -116 -117.098 0 + vertex -116 -117.098 -3 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -115.815 -117.196 -3 + vertex -115.815 -117.196 0 + vertex -116 -117.098 0 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -115.624 -117.282 -3 + vertex -115.815 -117.196 0 + vertex -115.815 -117.196 -3 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -115.624 -117.282 -3 + vertex -115.624 -117.282 0 + vertex -115.815 -117.196 0 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -115.427 -117.353 -3 + vertex -115.624 -117.282 0 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -115.427 -117.353 -3 + vertex -115.427 -117.353 0 + vertex -115.624 -117.282 0 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.427 -117.353 0 + vertex -115.427 -117.353 -3 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.226 -117.411 0 + vertex -115.427 -117.353 0 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -115.021 -117.454 -3 + vertex -115.226 -117.411 0 + vertex -115.226 -117.411 -3 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -115.021 -117.454 -3 + vertex -115.021 -117.454 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -114.814 -117.484 -3 + vertex -115.021 -117.454 0 + vertex -115.021 -117.454 -3 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -114.814 -117.484 -3 + vertex -114.814 -117.484 0 + vertex -115.021 -117.454 0 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -114.605 -117.498 -3 + vertex -114.814 -117.484 0 + vertex -114.814 -117.484 -3 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -114.605 -117.498 -3 + vertex -114.605 -117.498 0 + vertex -114.814 -117.484 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.605 -117.498 0 + vertex -114.605 -117.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.502 -117.498 0 + vertex -114.605 -117.498 0 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -114.5 -117.5 -3 + vertex -114.502 -117.498 0 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -114.5 -117.5 -3 + vertex -114.5 -117.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.5 -117.5 -3 + vertex -114.5 -117.5 0 + vertex -114.5 -117.5 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.5 -117.5 -3 + vertex 114.5 -117.5 0 + vertex -114.5 -117.5 0 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.5 -117.5 0 + vertex 114.5 -117.5 -3 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.502 -117.498 0 + vertex 114.5 -117.5 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/resources/profiles/Creality/ender3v2.svg b/resources/profiles/Creality/ender3v2.svg new file mode 100644 index 0000000000..7f793c7c01 --- /dev/null +++ b/resources/profiles/Creality/ender3v2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/ender3v2_bed.stl b/resources/profiles/Creality/ender3v2_bed.stl new file mode 100644 index 0000000000..f5a8cac683 --- /dev/null +++ b/resources/profiles/Creality/ender3v2_bed.stl @@ -0,0 +1,2774 @@ +solid OpenSCAD_Model + facet normal 0 0 -1 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.502 -117.498 -3 + vertex 114.814 -117.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.502 -117.498 -3 + vertex 115.021 -117.454 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.5 -114.5 -3 + vertex 114.502 -117.498 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.021 -117.454 -3 + vertex 114.502 -117.498 -3 + vertex 115.226 -117.411 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.226 -117.411 -3 + vertex 114.502 -117.498 -3 + vertex 115.427 -117.353 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.427 -117.353 -3 + vertex 114.502 -117.498 -3 + vertex 115.624 -117.282 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.624 -117.282 -3 + vertex 114.502 -117.498 -3 + vertex 115.815 -117.196 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 115.815 -117.196 -3 + vertex 114.502 -117.498 -3 + vertex 116 -117.098 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116 -117.098 -3 + vertex 114.502 -117.498 -3 + vertex 116.178 -116.987 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.178 -116.987 -3 + vertex 114.502 -117.498 -3 + vertex 116.347 -116.864 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.347 -116.864 -3 + vertex 114.502 -117.498 -3 + vertex 116.507 -116.729 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.507 -116.729 -3 + vertex 114.502 -117.498 -3 + vertex 116.658 -116.584 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.658 -116.584 -3 + vertex 114.502 -117.498 -3 + vertex 116.798 -116.428 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.798 -116.428 -3 + vertex 114.502 -117.498 -3 + vertex 116.927 -116.263 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 116.927 -116.263 -3 + vertex 114.502 -117.498 -3 + vertex 117.044 -116.09 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.044 -116.09 -3 + vertex 114.502 -117.498 -3 + vertex 117.149 -115.908 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.149 -115.908 -3 + vertex 114.502 -117.498 -3 + vertex 117.241 -115.72 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.241 -115.72 -3 + vertex 114.502 -117.498 -3 + vertex 117.319 -115.526 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.319 -115.526 -3 + vertex 114.502 -117.498 -3 + vertex 117.384 -115.327 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.384 -115.327 -3 + vertex 114.502 -117.498 -3 + vertex 117.434 -115.124 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.434 -115.124 -3 + vertex 114.502 -117.498 -3 + vertex 117.471 -114.918 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.471 -114.918 -3 + vertex 114.502 -117.498 -3 + vertex 117.493 -114.709 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 117.493 -114.709 -3 + vertex 114.502 -117.498 -3 + vertex 117.5 -114.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.5 -114.5 -3 + vertex 114.502 117.498 -3 + vertex 117.5 114.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 117.471 114.918 -3 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.384 115.327 -3 + vertex 117.434 115.124 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.241 115.72 -3 + vertex 114.502 117.498 -3 + vertex 117.149 115.908 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.241 115.72 -3 + vertex 117.319 115.526 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 116.507 116.729 -3 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.927 116.263 -3 + vertex 114.502 117.498 -3 + vertex 116.798 116.428 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 116.927 116.263 -3 + vertex 117.044 116.09 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.798 116.428 -3 + vertex 114.502 117.498 -3 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 115.427 117.353 -3 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.347 116.864 -3 + vertex 114.502 117.498 -3 + vertex 116.178 116.987 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 116.347 116.864 -3 + vertex 116.507 116.729 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116.178 116.987 -3 + vertex 114.502 117.498 -3 + vertex 116 117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 116 117.098 -3 + vertex 114.502 117.498 -3 + vertex 115.815 117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 115.815 117.196 -3 + vertex 114.502 117.498 -3 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.149 115.908 -3 + vertex 114.502 117.498 -3 + vertex 117.044 116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 115.226 117.411 -3 + vertex 114.502 117.498 -3 + vertex 115.021 117.454 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 115.226 117.411 -3 + vertex 115.427 117.353 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 117.319 115.526 -3 + vertex 117.384 115.327 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 114.814 117.484 -3 + vertex 115.021 117.454 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 117.434 115.124 -3 + vertex 117.471 114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 117.498 -3 + vertex 114.605 117.498 -3 + vertex 114.814 117.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 117.5 114.5 -3 + vertex 114.502 117.498 -3 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -114.5 117.5 -3 + vertex 114.5 117.5 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex 114.5 117.5 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex -114.502 117.498 -3 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 114.5 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -114.814 117.484 -3 + vertex -114.605 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.021 117.454 -3 + vertex -114.814 117.484 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.226 117.411 -3 + vertex -115.021 117.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.427 117.353 -3 + vertex -115.226 117.411 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.624 117.282 -3 + vertex -115.427 117.353 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -115.815 117.196 -3 + vertex -115.624 117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116 117.098 -3 + vertex -115.815 117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.178 116.987 -3 + vertex -116 117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.347 116.864 -3 + vertex -116.178 116.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.507 116.729 -3 + vertex -116.347 116.864 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.658 116.584 -3 + vertex -116.507 116.729 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.798 116.428 -3 + vertex -116.658 116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -116.927 116.263 -3 + vertex -116.798 116.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.044 116.09 -3 + vertex -116.927 116.263 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.149 115.908 -3 + vertex -117.044 116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.241 115.72 -3 + vertex -117.149 115.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.319 115.526 -3 + vertex -117.241 115.72 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.384 115.327 -3 + vertex -117.319 115.526 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.434 115.124 -3 + vertex -117.384 115.327 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.471 114.918 -3 + vertex -117.434 115.124 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.493 114.709 -3 + vertex -117.471 114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 117.498 -3 + vertex -117.5 114.5 -3 + vertex -117.493 114.709 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.5 114.5 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex -114.502 -117.498 -3 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.471 -114.918 -3 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.434 -115.124 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.241 -115.72 -3 + vertex -114.502 -117.498 -3 + vertex -117.149 -115.908 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.319 -115.526 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -116.507 -116.729 -3 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.927 -116.263 -3 + vertex -114.502 -117.498 -3 + vertex -116.798 -116.428 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.927 -116.263 -3 + vertex -117.044 -116.09 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.798 -116.428 -3 + vertex -114.502 -117.498 -3 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -115.427 -117.353 -3 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.347 -116.864 -3 + vertex -114.502 -117.498 -3 + vertex -116.178 -116.987 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.507 -116.729 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116.178 -116.987 -3 + vertex -114.502 -117.498 -3 + vertex -116 -117.098 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -116 -117.098 -3 + vertex -114.502 -117.498 -3 + vertex -115.815 -117.196 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.815 -117.196 -3 + vertex -114.502 -117.498 -3 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.149 -115.908 -3 + vertex -114.502 -117.498 -3 + vertex -117.044 -116.09 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.226 -117.411 -3 + vertex -114.502 -117.498 -3 + vertex -115.021 -117.454 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.427 -117.353 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.384 -115.327 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.814 -117.484 -3 + vertex -115.021 -117.454 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -117.434 -115.124 -3 + vertex -117.471 -114.918 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.605 -117.498 -3 + vertex -114.814 -117.484 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.5 -117.5 -3 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -114.502 -117.498 -3 + vertex 114.5 -117.5 -3 + vertex -114.5 -117.5 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -117.5 -114.5 -3 + vertex -114.502 -117.498 -3 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.814 -117.484 0 + vertex 114.502 -117.498 0 + vertex 114.605 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.021 -117.454 0 + vertex 114.502 -117.498 0 + vertex 114.814 -117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 114.502 -117.498 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.226 -117.411 0 + vertex 114.502 -117.498 0 + vertex 115.021 -117.454 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.427 -117.353 0 + vertex 114.502 -117.498 0 + vertex 115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 -117.282 0 + vertex 114.502 -117.498 0 + vertex 115.427 -117.353 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.815 -117.196 0 + vertex 114.502 -117.498 0 + vertex 115.624 -117.282 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116 -117.098 0 + vertex 114.502 -117.498 0 + vertex 115.815 -117.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.178 -116.987 0 + vertex 114.502 -117.498 0 + vertex 116 -117.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.347 -116.864 0 + vertex 114.502 -117.498 0 + vertex 116.178 -116.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.507 -116.729 0 + vertex 114.502 -117.498 0 + vertex 116.347 -116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 -116.584 0 + vertex 114.502 -117.498 0 + vertex 116.507 -116.729 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.798 -116.428 0 + vertex 114.502 -117.498 0 + vertex 116.658 -116.584 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.927 -116.263 0 + vertex 114.502 -117.498 0 + vertex 116.798 -116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.044 -116.09 0 + vertex 114.502 -117.498 0 + vertex 116.927 -116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.149 -115.908 0 + vertex 114.502 -117.498 0 + vertex 117.044 -116.09 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.241 -115.72 0 + vertex 114.502 -117.498 0 + vertex 117.149 -115.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.319 -115.526 0 + vertex 114.502 -117.498 0 + vertex 117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.384 -115.327 0 + vertex 114.502 -117.498 0 + vertex 117.319 -115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.434 -115.124 0 + vertex 114.502 -117.498 0 + vertex 117.384 -115.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.471 -114.918 0 + vertex 114.502 -117.498 0 + vertex 117.434 -115.124 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 -114.709 0 + vertex 114.502 -117.498 0 + vertex 117.471 -114.918 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.5 -114.5 0 + vertex 114.502 -117.498 0 + vertex 117.493 -114.709 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.5 114.5 0 + vertex 114.502 117.498 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 114.709 0 + vertex 117.471 114.918 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.434 115.124 0 + vertex 117.384 115.327 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.149 115.908 0 + vertex 114.502 117.498 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.319 115.526 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 116.584 0 + vertex 116.507 116.729 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.798 116.428 0 + vertex 114.502 117.498 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.044 116.09 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.658 116.584 0 + vertex 114.502 117.498 0 + vertex 116.798 116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 117.282 0 + vertex 115.427 117.353 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116.178 116.987 0 + vertex 114.502 117.498 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 116.507 116.729 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 116 117.098 0 + vertex 114.502 117.498 0 + vertex 116.178 116.987 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.815 117.196 0 + vertex 114.502 117.498 0 + vertex 116 117.098 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.624 117.282 0 + vertex 114.502 117.498 0 + vertex 115.815 117.196 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.044 116.09 0 + vertex 114.502 117.498 0 + vertex 117.149 115.908 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 115.021 117.454 0 + vertex 114.502 117.498 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 115.427 117.353 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 117.384 115.327 0 + vertex 117.319 115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 115.021 117.454 0 + vertex 114.814 117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.471 114.918 0 + vertex 117.434 115.124 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.814 117.484 0 + vertex 114.605 117.498 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 117.493 114.709 0 + vertex 114.502 117.498 0 + vertex 117.5 114.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex 114.5 117.5 0 + vertex -114.5 117.5 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex 114.5 117.5 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 114.502 117.498 0 + vertex -114.502 117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.5 114.5 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.605 117.498 0 + vertex -114.814 117.484 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.814 117.484 0 + vertex -115.021 117.454 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.021 117.454 0 + vertex -115.226 117.411 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.226 117.411 0 + vertex -115.427 117.353 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.427 117.353 0 + vertex -115.624 117.282 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.624 117.282 0 + vertex -115.815 117.196 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -115.815 117.196 0 + vertex -116 117.098 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116 117.098 0 + vertex -116.178 116.987 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.178 116.987 0 + vertex -116.347 116.864 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.347 116.864 0 + vertex -116.507 116.729 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.507 116.729 0 + vertex -116.658 116.584 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.658 116.584 0 + vertex -116.798 116.428 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.798 116.428 0 + vertex -116.927 116.263 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -116.927 116.263 0 + vertex -117.044 116.09 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.044 116.09 0 + vertex -117.149 115.908 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.149 115.908 0 + vertex -117.241 115.72 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.241 115.72 0 + vertex -117.319 115.526 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.319 115.526 0 + vertex -117.384 115.327 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.384 115.327 0 + vertex -117.434 115.124 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.434 115.124 0 + vertex -117.471 114.918 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.471 114.918 0 + vertex -117.493 114.709 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -117.493 114.709 0 + vertex -117.5 114.5 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex -117.5 114.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 117.498 0 + vertex -114.502 -117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -117.493 -114.709 0 + vertex -117.471 -114.918 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.434 -115.124 0 + vertex -117.384 -115.327 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.149 -115.908 0 + vertex -114.502 -117.498 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.319 -115.526 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -116.658 -116.584 0 + vertex -116.507 -116.729 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.798 -116.428 0 + vertex -114.502 -117.498 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.044 -116.09 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.658 -116.584 0 + vertex -114.502 -117.498 0 + vertex -116.798 -116.428 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -115.624 -117.282 0 + vertex -115.427 -117.353 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116.178 -116.987 0 + vertex -114.502 -117.498 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -116.507 -116.729 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -116 -117.098 0 + vertex -114.502 -117.498 0 + vertex -116.178 -116.987 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.815 -117.196 0 + vertex -114.502 -117.498 0 + vertex -116 -117.098 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.624 -117.282 0 + vertex -114.502 -117.498 0 + vertex -115.815 -117.196 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.044 -116.09 0 + vertex -114.502 -117.498 0 + vertex -117.149 -115.908 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -115.021 -117.454 0 + vertex -114.502 -117.498 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -115.427 -117.353 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -117.384 -115.327 0 + vertex -117.319 -115.526 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex -115.021 -117.454 0 + vertex -114.814 -117.484 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -117.471 -114.918 0 + vertex -117.434 -115.124 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -114.814 -117.484 0 + vertex -114.605 -117.498 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -114.502 -117.498 0 + vertex 114.5 -117.5 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -114.5 -117.5 0 + vertex 114.5 -117.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -117.493 -114.709 0 + vertex -114.502 -117.498 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.502 -117.498 0 + vertex 114.502 -117.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.605 -117.498 -3 + vertex 114.605 -117.498 0 + vertex 114.502 -117.498 0 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.605 -117.498 0 + vertex 114.605 -117.498 -3 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 114.814 -117.484 -3 + vertex 114.814 -117.484 0 + vertex 114.605 -117.498 0 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 115.021 -117.454 -3 + vertex 114.814 -117.484 0 + vertex 114.814 -117.484 -3 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 115.021 -117.454 -3 + vertex 115.021 -117.454 0 + vertex 114.814 -117.484 0 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 115.226 -117.411 -3 + vertex 115.021 -117.454 0 + vertex 115.021 -117.454 -3 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 115.226 -117.411 -3 + vertex 115.226 -117.411 0 + vertex 115.021 -117.454 0 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 115.427 -117.353 -3 + vertex 115.226 -117.411 0 + vertex 115.226 -117.411 -3 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 115.427 -117.353 -3 + vertex 115.427 -117.353 0 + vertex 115.226 -117.411 0 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 115.624 -117.282 -3 + vertex 115.427 -117.353 0 + vertex 115.427 -117.353 -3 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 115.624 -117.282 -3 + vertex 115.624 -117.282 0 + vertex 115.427 -117.353 0 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 115.815 -117.196 -3 + vertex 115.624 -117.282 0 + vertex 115.624 -117.282 -3 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 115.815 -117.196 -3 + vertex 115.815 -117.196 0 + vertex 115.624 -117.282 0 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 116 -117.098 -3 + vertex 115.815 -117.196 0 + vertex 115.815 -117.196 -3 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 116 -117.098 -3 + vertex 116 -117.098 0 + vertex 115.815 -117.196 0 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 116.178 -116.987 -3 + vertex 116 -117.098 0 + vertex 116 -117.098 -3 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 116.178 -116.987 -3 + vertex 116.178 -116.987 0 + vertex 116 -117.098 0 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 116.347 -116.864 -3 + vertex 116.178 -116.987 0 + vertex 116.178 -116.987 -3 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 116.347 -116.864 -3 + vertex 116.347 -116.864 0 + vertex 116.178 -116.987 0 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 116.507 -116.729 -3 + vertex 116.347 -116.864 0 + vertex 116.347 -116.864 -3 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 116.507 -116.729 -3 + vertex 116.507 -116.729 0 + vertex 116.347 -116.864 0 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 116.658 -116.584 -3 + vertex 116.507 -116.729 0 + vertex 116.507 -116.729 -3 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 116.658 -116.584 -3 + vertex 116.658 -116.584 0 + vertex 116.507 -116.729 0 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 116.798 -116.428 -3 + vertex 116.658 -116.584 0 + vertex 116.658 -116.584 -3 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 116.798 -116.428 -3 + vertex 116.798 -116.428 0 + vertex 116.658 -116.584 0 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 116.927 -116.263 -3 + vertex 116.798 -116.428 0 + vertex 116.798 -116.428 -3 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 116.927 -116.263 -3 + vertex 116.927 -116.263 0 + vertex 116.798 -116.428 0 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 117.044 -116.09 -3 + vertex 116.927 -116.263 0 + vertex 116.927 -116.263 -3 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 117.044 -116.09 -3 + vertex 117.044 -116.09 0 + vertex 116.927 -116.263 0 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 117.149 -115.908 -3 + vertex 117.044 -116.09 0 + vertex 117.044 -116.09 -3 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 117.149 -115.908 -3 + vertex 117.149 -115.908 0 + vertex 117.044 -116.09 0 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 117.241 -115.72 -3 + vertex 117.149 -115.908 0 + vertex 117.149 -115.908 -3 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 117.241 -115.72 -3 + vertex 117.241 -115.72 0 + vertex 117.149 -115.908 0 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 117.319 -115.526 -3 + vertex 117.241 -115.72 0 + vertex 117.241 -115.72 -3 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 117.319 -115.526 -3 + vertex 117.319 -115.526 0 + vertex 117.241 -115.72 0 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 117.384 -115.327 -3 + vertex 117.319 -115.526 0 + vertex 117.319 -115.526 -3 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 117.384 -115.327 -3 + vertex 117.384 -115.327 0 + vertex 117.319 -115.526 0 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 117.434 -115.124 -3 + vertex 117.384 -115.327 0 + vertex 117.384 -115.327 -3 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 117.434 -115.124 -3 + vertex 117.434 -115.124 0 + vertex 117.384 -115.327 0 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 117.471 -114.918 -3 + vertex 117.434 -115.124 0 + vertex 117.434 -115.124 -3 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 117.471 -114.918 -3 + vertex 117.471 -114.918 0 + vertex 117.434 -115.124 0 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 117.493 -114.709 -3 + vertex 117.471 -114.918 0 + vertex 117.471 -114.918 -3 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 117.493 -114.709 -3 + vertex 117.493 -114.709 0 + vertex 117.471 -114.918 0 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 117.5 -114.5 -3 + vertex 117.493 -114.709 0 + vertex 117.493 -114.709 -3 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 117.5 -114.5 -3 + vertex 117.5 -114.5 0 + vertex 117.493 -114.709 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 117.5 114.5 -3 + vertex 117.5 -114.5 0 + vertex 117.5 -114.5 -3 + endloop + endfacet + facet normal 1 0 -0 + outer loop + vertex 117.5 114.5 -3 + vertex 117.5 114.5 0 + vertex 117.5 -114.5 0 + endloop + endfacet + facet normal 0.99944 0.0334741 0 + outer loop + vertex 117.493 114.709 -3 + vertex 117.5 114.5 0 + vertex 117.5 114.5 -3 + endloop + endfacet + facet normal 0.99944 0.0334741 -0 + outer loop + vertex 117.493 114.709 -3 + vertex 117.493 114.709 0 + vertex 117.5 114.5 0 + endloop + endfacet + facet normal 0.994505 0.104685 0 + outer loop + vertex 117.471 114.918 -3 + vertex 117.493 114.709 0 + vertex 117.493 114.709 -3 + endloop + endfacet + facet normal 0.994505 0.104685 -0 + outer loop + vertex 117.471 114.918 -3 + vertex 117.471 114.918 0 + vertex 117.493 114.709 0 + endloop + endfacet + facet normal 0.98425 0.176783 0 + outer loop + vertex 117.434 115.124 -3 + vertex 117.471 114.918 0 + vertex 117.471 114.918 -3 + endloop + endfacet + facet normal 0.98425 0.176783 -0 + outer loop + vertex 117.434 115.124 -3 + vertex 117.434 115.124 0 + vertex 117.471 114.918 0 + endloop + endfacet + facet normal 0.970981 0.239158 0 + outer loop + vertex 117.384 115.327 -3 + vertex 117.434 115.124 0 + vertex 117.434 115.124 -3 + endloop + endfacet + facet normal 0.970981 0.239158 -0 + outer loop + vertex 117.384 115.327 -3 + vertex 117.384 115.327 0 + vertex 117.434 115.124 0 + endloop + endfacet + facet normal 0.950577 0.31049 0 + outer loop + vertex 117.319 115.526 -3 + vertex 117.384 115.327 0 + vertex 117.384 115.327 -3 + endloop + endfacet + facet normal 0.950577 0.31049 -0 + outer loop + vertex 117.319 115.526 -3 + vertex 117.319 115.526 0 + vertex 117.384 115.327 0 + endloop + endfacet + facet normal 0.927816 0.373039 0 + outer loop + vertex 117.241 115.72 -3 + vertex 117.319 115.526 0 + vertex 117.319 115.526 -3 + endloop + endfacet + facet normal 0.927816 0.373039 -0 + outer loop + vertex 117.241 115.72 -3 + vertex 117.241 115.72 0 + vertex 117.319 115.526 0 + endloop + endfacet + facet normal 0.898217 0.439553 0 + outer loop + vertex 117.149 115.908 -3 + vertex 117.241 115.72 0 + vertex 117.241 115.72 -3 + endloop + endfacet + facet normal 0.898217 0.439553 -0 + outer loop + vertex 117.149 115.908 -3 + vertex 117.149 115.908 0 + vertex 117.241 115.72 0 + endloop + endfacet + facet normal 0.866186 0.499722 0 + outer loop + vertex 117.044 116.09 -3 + vertex 117.149 115.908 0 + vertex 117.149 115.908 -3 + endloop + endfacet + facet normal 0.866186 0.499722 -0 + outer loop + vertex 117.044 116.09 -3 + vertex 117.044 116.09 0 + vertex 117.149 115.908 0 + endloop + endfacet + facet normal 0.828349 0.560213 0 + outer loop + vertex 116.927 116.263 -3 + vertex 117.044 116.09 0 + vertex 117.044 116.09 -3 + endloop + endfacet + facet normal 0.828349 0.560213 -0 + outer loop + vertex 116.927 116.263 -3 + vertex 116.927 116.263 0 + vertex 117.044 116.09 0 + endloop + endfacet + facet normal 0.787807 0.615922 0 + outer loop + vertex 116.798 116.428 -3 + vertex 116.927 116.263 0 + vertex 116.927 116.263 -3 + endloop + endfacet + facet normal 0.787807 0.615922 -0 + outer loop + vertex 116.798 116.428 -3 + vertex 116.798 116.428 0 + vertex 116.927 116.263 0 + endloop + endfacet + facet normal 0.744242 0.66791 0 + outer loop + vertex 116.658 116.584 -3 + vertex 116.798 116.428 0 + vertex 116.798 116.428 -3 + endloop + endfacet + facet normal 0.744242 0.66791 -0 + outer loop + vertex 116.658 116.584 -3 + vertex 116.658 116.584 0 + vertex 116.798 116.428 0 + endloop + endfacet + facet normal 0.692631 0.721292 0 + outer loop + vertex 116.507 116.729 -3 + vertex 116.658 116.584 0 + vertex 116.658 116.584 -3 + endloop + endfacet + facet normal 0.692631 0.721292 -0 + outer loop + vertex 116.507 116.729 -3 + vertex 116.507 116.729 0 + vertex 116.658 116.584 0 + endloop + endfacet + facet normal 0.644871 0.764291 0 + outer loop + vertex 116.347 116.864 -3 + vertex 116.507 116.729 0 + vertex 116.507 116.729 -3 + endloop + endfacet + facet normal 0.644871 0.764291 -0 + outer loop + vertex 116.347 116.864 -3 + vertex 116.347 116.864 0 + vertex 116.507 116.729 0 + endloop + endfacet + facet normal 0.588456 0.808529 0 + outer loop + vertex 116.178 116.987 -3 + vertex 116.347 116.864 0 + vertex 116.347 116.864 -3 + endloop + endfacet + facet normal 0.588456 0.808529 -0 + outer loop + vertex 116.178 116.987 -3 + vertex 116.178 116.987 0 + vertex 116.347 116.864 0 + endloop + endfacet + facet normal 0.529142 0.848533 0 + outer loop + vertex 116 117.098 -3 + vertex 116.178 116.987 0 + vertex 116.178 116.987 -3 + endloop + endfacet + facet normal 0.529142 0.848533 -0 + outer loop + vertex 116 117.098 -3 + vertex 116 117.098 0 + vertex 116.178 116.987 0 + endloop + endfacet + facet normal 0.468107 0.883672 0 + outer loop + vertex 115.815 117.196 -3 + vertex 116 117.098 0 + vertex 116 117.098 -3 + endloop + endfacet + facet normal 0.468107 0.883672 -0 + outer loop + vertex 115.815 117.196 -3 + vertex 115.815 117.196 0 + vertex 116 117.098 0 + endloop + endfacet + facet normal 0.410563 0.911832 0 + outer loop + vertex 115.624 117.282 -3 + vertex 115.815 117.196 0 + vertex 115.815 117.196 -3 + endloop + endfacet + facet normal 0.410563 0.911832 -0 + outer loop + vertex 115.624 117.282 -3 + vertex 115.624 117.282 0 + vertex 115.815 117.196 0 + endloop + endfacet + facet normal 0.339058 0.940766 0 + outer loop + vertex 115.427 117.353 -3 + vertex 115.624 117.282 0 + vertex 115.624 117.282 -3 + endloop + endfacet + facet normal 0.339058 0.940766 -0 + outer loop + vertex 115.427 117.353 -3 + vertex 115.427 117.353 0 + vertex 115.624 117.282 0 + endloop + endfacet + facet normal 0.277246 0.960799 0 + outer loop + vertex 115.226 117.411 -3 + vertex 115.427 117.353 0 + vertex 115.427 117.353 -3 + endloop + endfacet + facet normal 0.277246 0.960799 -0 + outer loop + vertex 115.226 117.411 -3 + vertex 115.226 117.411 0 + vertex 115.427 117.353 0 + endloop + endfacet + facet normal 0.205289 0.978701 0 + outer loop + vertex 115.021 117.454 -3 + vertex 115.226 117.411 0 + vertex 115.226 117.411 -3 + endloop + endfacet + facet normal 0.205289 0.978701 -0 + outer loop + vertex 115.021 117.454 -3 + vertex 115.021 117.454 0 + vertex 115.226 117.411 0 + endloop + endfacet + facet normal 0.143429 0.989661 0 + outer loop + vertex 114.814 117.484 -3 + vertex 115.021 117.454 0 + vertex 115.021 117.454 -3 + endloop + endfacet + facet normal 0.143429 0.989661 -0 + outer loop + vertex 114.814 117.484 -3 + vertex 114.814 117.484 0 + vertex 115.021 117.454 0 + endloop + endfacet + facet normal 0.0668359 0.997764 0 + outer loop + vertex 114.605 117.498 -3 + vertex 114.814 117.484 0 + vertex 114.814 117.484 -3 + endloop + endfacet + facet normal 0.0668359 0.997764 -0 + outer loop + vertex 114.605 117.498 -3 + vertex 114.605 117.498 0 + vertex 114.814 117.484 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 114.502 117.498 -3 + vertex 114.605 117.498 0 + vertex 114.605 117.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 114.502 117.498 -3 + vertex 114.502 117.498 0 + vertex 114.605 117.498 0 + endloop + endfacet + facet normal 0.707107 0.707107 0 + outer loop + vertex 114.5 117.5 -3 + vertex 114.502 117.498 0 + vertex 114.502 117.498 -3 + endloop + endfacet + facet normal 0.707107 0.707107 -0 + outer loop + vertex 114.5 117.5 -3 + vertex 114.5 117.5 0 + vertex 114.502 117.498 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.5 117.5 -3 + vertex 114.5 117.5 0 + vertex 114.5 117.5 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.5 117.5 -3 + vertex -114.5 117.5 0 + vertex 114.5 117.5 0 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -114.502 117.498 -3 + vertex -114.5 117.5 0 + vertex -114.5 117.5 -3 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -114.502 117.498 -3 + vertex -114.502 117.498 0 + vertex -114.5 117.5 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.605 117.498 -3 + vertex -114.502 117.498 0 + vertex -114.502 117.498 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -114.605 117.498 -3 + vertex -114.605 117.498 0 + vertex -114.502 117.498 0 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -114.814 117.484 -3 + vertex -114.605 117.498 0 + vertex -114.605 117.498 -3 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -114.814 117.484 -3 + vertex -114.814 117.484 0 + vertex -114.605 117.498 0 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -115.021 117.454 -3 + vertex -114.814 117.484 0 + vertex -114.814 117.484 -3 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -115.021 117.454 -3 + vertex -115.021 117.454 0 + vertex -114.814 117.484 0 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -115.226 117.411 -3 + vertex -115.021 117.454 0 + vertex -115.021 117.454 -3 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -115.226 117.411 -3 + vertex -115.226 117.411 0 + vertex -115.021 117.454 0 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -115.427 117.353 -3 + vertex -115.226 117.411 0 + vertex -115.226 117.411 -3 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -115.427 117.353 -3 + vertex -115.427 117.353 0 + vertex -115.226 117.411 0 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -115.624 117.282 -3 + vertex -115.427 117.353 0 + vertex -115.427 117.353 -3 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -115.624 117.282 -3 + vertex -115.624 117.282 0 + vertex -115.427 117.353 0 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -115.815 117.196 -3 + vertex -115.624 117.282 0 + vertex -115.624 117.282 -3 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -115.815 117.196 -3 + vertex -115.815 117.196 0 + vertex -115.624 117.282 0 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -116 117.098 -3 + vertex -115.815 117.196 0 + vertex -115.815 117.196 -3 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -116 117.098 -3 + vertex -116 117.098 0 + vertex -115.815 117.196 0 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -116.178 116.987 -3 + vertex -116 117.098 0 + vertex -116 117.098 -3 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -116.178 116.987 -3 + vertex -116.178 116.987 0 + vertex -116 117.098 0 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -116.347 116.864 -3 + vertex -116.178 116.987 0 + vertex -116.178 116.987 -3 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -116.347 116.864 -3 + vertex -116.347 116.864 0 + vertex -116.178 116.987 0 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -116.507 116.729 -3 + vertex -116.347 116.864 0 + vertex -116.347 116.864 -3 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -116.507 116.729 -3 + vertex -116.507 116.729 0 + vertex -116.347 116.864 0 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -116.658 116.584 -3 + vertex -116.507 116.729 0 + vertex -116.507 116.729 -3 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -116.658 116.584 -3 + vertex -116.658 116.584 0 + vertex -116.507 116.729 0 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -116.798 116.428 -3 + vertex -116.658 116.584 0 + vertex -116.658 116.584 -3 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -116.798 116.428 -3 + vertex -116.798 116.428 0 + vertex -116.658 116.584 0 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -116.927 116.263 -3 + vertex -116.798 116.428 0 + vertex -116.798 116.428 -3 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -116.927 116.263 -3 + vertex -116.927 116.263 0 + vertex -116.798 116.428 0 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -117.044 116.09 -3 + vertex -116.927 116.263 0 + vertex -116.927 116.263 -3 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -117.044 116.09 -3 + vertex -117.044 116.09 0 + vertex -116.927 116.263 0 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -117.149 115.908 -3 + vertex -117.044 116.09 0 + vertex -117.044 116.09 -3 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -117.149 115.908 -3 + vertex -117.149 115.908 0 + vertex -117.044 116.09 0 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -117.241 115.72 -3 + vertex -117.149 115.908 0 + vertex -117.149 115.908 -3 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -117.241 115.72 -3 + vertex -117.241 115.72 0 + vertex -117.149 115.908 0 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -117.319 115.526 -3 + vertex -117.241 115.72 0 + vertex -117.241 115.72 -3 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -117.319 115.526 -3 + vertex -117.319 115.526 0 + vertex -117.241 115.72 0 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -117.384 115.327 -3 + vertex -117.319 115.526 0 + vertex -117.319 115.526 -3 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -117.384 115.327 -3 + vertex -117.384 115.327 0 + vertex -117.319 115.526 0 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -117.434 115.124 -3 + vertex -117.384 115.327 0 + vertex -117.384 115.327 -3 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -117.434 115.124 -3 + vertex -117.434 115.124 0 + vertex -117.384 115.327 0 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -117.471 114.918 -3 + vertex -117.434 115.124 0 + vertex -117.434 115.124 -3 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -117.471 114.918 -3 + vertex -117.471 114.918 0 + vertex -117.434 115.124 0 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -117.493 114.709 -3 + vertex -117.471 114.918 0 + vertex -117.471 114.918 -3 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -117.493 114.709 -3 + vertex -117.493 114.709 0 + vertex -117.471 114.918 0 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -117.5 114.5 -3 + vertex -117.493 114.709 0 + vertex -117.493 114.709 -3 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -117.5 114.5 -3 + vertex -117.5 114.5 0 + vertex -117.493 114.709 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 114.5 0 + vertex -117.5 114.5 -3 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -117.5 -114.5 -3 + vertex -117.5 -114.5 0 + vertex -117.5 114.5 0 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -117.493 -114.709 -3 + vertex -117.5 -114.5 0 + vertex -117.5 -114.5 -3 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -117.493 -114.709 -3 + vertex -117.493 -114.709 0 + vertex -117.5 -114.5 0 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -117.471 -114.918 -3 + vertex -117.493 -114.709 0 + vertex -117.493 -114.709 -3 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -117.471 -114.918 -3 + vertex -117.471 -114.918 0 + vertex -117.493 -114.709 0 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -117.434 -115.124 -3 + vertex -117.471 -114.918 0 + vertex -117.471 -114.918 -3 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -117.434 -115.124 -3 + vertex -117.434 -115.124 0 + vertex -117.471 -114.918 0 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.434 -115.124 0 + vertex -117.434 -115.124 -3 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -117.384 -115.327 -3 + vertex -117.384 -115.327 0 + vertex -117.434 -115.124 0 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.384 -115.327 0 + vertex -117.384 -115.327 -3 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -117.319 -115.526 -3 + vertex -117.319 -115.526 0 + vertex -117.384 -115.327 0 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.319 -115.526 0 + vertex -117.319 -115.526 -3 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -117.241 -115.72 -3 + vertex -117.241 -115.72 0 + vertex -117.319 -115.526 0 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -117.149 -115.908 -3 + vertex -117.241 -115.72 0 + vertex -117.241 -115.72 -3 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -117.149 -115.908 -3 + vertex -117.149 -115.908 0 + vertex -117.241 -115.72 0 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -117.044 -116.09 -3 + vertex -117.149 -115.908 0 + vertex -117.149 -115.908 -3 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -117.044 -116.09 -3 + vertex -117.044 -116.09 0 + vertex -117.149 -115.908 0 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -116.927 -116.263 -3 + vertex -117.044 -116.09 0 + vertex -117.044 -116.09 -3 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -116.927 -116.263 -3 + vertex -116.927 -116.263 0 + vertex -117.044 -116.09 0 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -116.798 -116.428 -3 + vertex -116.927 -116.263 0 + vertex -116.927 -116.263 -3 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -116.798 -116.428 -3 + vertex -116.798 -116.428 0 + vertex -116.927 -116.263 0 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -116.658 -116.584 -3 + vertex -116.798 -116.428 0 + vertex -116.798 -116.428 -3 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -116.658 -116.584 -3 + vertex -116.658 -116.584 0 + vertex -116.798 -116.428 0 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -116.507 -116.729 -3 + vertex -116.658 -116.584 0 + vertex -116.658 -116.584 -3 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -116.507 -116.729 -3 + vertex -116.507 -116.729 0 + vertex -116.658 -116.584 0 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.507 -116.729 0 + vertex -116.507 -116.729 -3 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -116.347 -116.864 -3 + vertex -116.347 -116.864 0 + vertex -116.507 -116.729 0 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -116.178 -116.987 -3 + vertex -116.347 -116.864 0 + vertex -116.347 -116.864 -3 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -116.178 -116.987 -3 + vertex -116.178 -116.987 0 + vertex -116.347 -116.864 0 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -116 -117.098 -3 + vertex -116.178 -116.987 0 + vertex -116.178 -116.987 -3 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -116 -117.098 -3 + vertex -116 -117.098 0 + vertex -116.178 -116.987 0 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -115.815 -117.196 -3 + vertex -116 -117.098 0 + vertex -116 -117.098 -3 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -115.815 -117.196 -3 + vertex -115.815 -117.196 0 + vertex -116 -117.098 0 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -115.624 -117.282 -3 + vertex -115.815 -117.196 0 + vertex -115.815 -117.196 -3 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -115.624 -117.282 -3 + vertex -115.624 -117.282 0 + vertex -115.815 -117.196 0 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -115.427 -117.353 -3 + vertex -115.624 -117.282 0 + vertex -115.624 -117.282 -3 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -115.427 -117.353 -3 + vertex -115.427 -117.353 0 + vertex -115.624 -117.282 0 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.427 -117.353 0 + vertex -115.427 -117.353 -3 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -115.226 -117.411 -3 + vertex -115.226 -117.411 0 + vertex -115.427 -117.353 0 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -115.021 -117.454 -3 + vertex -115.226 -117.411 0 + vertex -115.226 -117.411 -3 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -115.021 -117.454 -3 + vertex -115.021 -117.454 0 + vertex -115.226 -117.411 0 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -114.814 -117.484 -3 + vertex -115.021 -117.454 0 + vertex -115.021 -117.454 -3 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -114.814 -117.484 -3 + vertex -114.814 -117.484 0 + vertex -115.021 -117.454 0 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -114.605 -117.498 -3 + vertex -114.814 -117.484 0 + vertex -114.814 -117.484 -3 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -114.605 -117.498 -3 + vertex -114.605 -117.498 0 + vertex -114.814 -117.484 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.605 -117.498 0 + vertex -114.605 -117.498 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -114.502 -117.498 -3 + vertex -114.502 -117.498 0 + vertex -114.605 -117.498 0 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -114.5 -117.5 -3 + vertex -114.502 -117.498 0 + vertex -114.502 -117.498 -3 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -114.5 -117.5 -3 + vertex -114.5 -117.5 0 + vertex -114.502 -117.498 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.5 -117.5 -3 + vertex -114.5 -117.5 0 + vertex -114.5 -117.5 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 114.5 -117.5 -3 + vertex 114.5 -117.5 0 + vertex -114.5 -117.5 0 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.5 -117.5 0 + vertex 114.5 -117.5 -3 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 114.502 -117.498 -3 + vertex 114.502 -117.498 0 + vertex 114.5 -117.5 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/resources/profiles/Creality/ender6.svg b/resources/profiles/Creality/ender6.svg new file mode 100644 index 0000000000..0d6a92f19b --- /dev/null +++ b/resources/profiles/Creality/ender6.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/Creality/ender6_bed.stl b/resources/profiles/Creality/ender6_bed.stl new file mode 100644 index 0000000000..f0a708922a --- /dev/null +++ b/resources/profiles/Creality/ender6_bed.stl @@ -0,0 +1,2774 @@ +solid OpenSCAD_Model + facet normal 0 0 -1 + outer loop + vertex 127.105 -129.998 -3 + vertex 127.002 -129.998 -3 + vertex 127.314 -129.984 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 127.314 -129.984 -3 + vertex 127.002 -129.998 -3 + vertex 127.521 -129.954 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 130 -127 -3 + vertex 127.002 -129.998 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 127.521 -129.954 -3 + vertex 127.002 -129.998 -3 + vertex 127.726 -129.911 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 127.726 -129.911 -3 + vertex 127.002 -129.998 -3 + vertex 127.927 -129.853 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 127.927 -129.853 -3 + vertex 127.002 -129.998 -3 + vertex 128.124 -129.782 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 128.124 -129.782 -3 + vertex 127.002 -129.998 -3 + vertex 128.315 -129.696 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 128.315 -129.696 -3 + vertex 127.002 -129.998 -3 + vertex 128.5 -129.598 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 128.5 -129.598 -3 + vertex 127.002 -129.998 -3 + vertex 128.678 -129.487 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 128.678 -129.487 -3 + vertex 127.002 -129.998 -3 + vertex 128.847 -129.364 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 128.847 -129.364 -3 + vertex 127.002 -129.998 -3 + vertex 129.007 -129.229 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.007 -129.229 -3 + vertex 127.002 -129.998 -3 + vertex 129.158 -129.084 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.158 -129.084 -3 + vertex 127.002 -129.998 -3 + vertex 129.298 -128.928 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.298 -128.928 -3 + vertex 127.002 -129.998 -3 + vertex 129.427 -128.763 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.427 -128.763 -3 + vertex 127.002 -129.998 -3 + vertex 129.544 -128.59 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.544 -128.59 -3 + vertex 127.002 -129.998 -3 + vertex 129.649 -128.408 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.649 -128.408 -3 + vertex 127.002 -129.998 -3 + vertex 129.741 -128.22 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.741 -128.22 -3 + vertex 127.002 -129.998 -3 + vertex 129.819 -128.026 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.819 -128.026 -3 + vertex 127.002 -129.998 -3 + vertex 129.884 -127.827 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.884 -127.827 -3 + vertex 127.002 -129.998 -3 + vertex 129.934 -127.624 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.934 -127.624 -3 + vertex 127.002 -129.998 -3 + vertex 129.971 -127.418 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.971 -127.418 -3 + vertex 127.002 -129.998 -3 + vertex 129.993 -127.209 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 129.993 -127.209 -3 + vertex 127.002 -129.998 -3 + vertex 130 -127 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 130 -127 -3 + vertex 127.002 129.998 -3 + vertex 130 127 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 129.998 -3 + vertex 129.971 127.418 -3 + vertex 129.993 127.209 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 129.884 127.827 -3 + vertex 129.934 127.624 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 129.741 128.22 -3 + vertex 127.002 129.998 -3 + vertex 129.649 128.408 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 129.741 128.22 -3 + vertex 129.819 128.026 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 129.998 -3 + vertex 129.007 129.229 -3 + vertex 129.158 129.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 129.427 128.763 -3 + vertex 127.002 129.998 -3 + vertex 129.298 128.928 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 129.427 128.763 -3 + vertex 129.544 128.59 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 129.298 128.928 -3 + vertex 127.002 129.998 -3 + vertex 129.158 129.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 129.998 -3 + vertex 127.927 129.853 -3 + vertex 128.124 129.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 128.847 129.364 -3 + vertex 127.002 129.998 -3 + vertex 128.678 129.487 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 128.847 129.364 -3 + vertex 129.007 129.229 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 128.678 129.487 -3 + vertex 127.002 129.998 -3 + vertex 128.5 129.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 128.5 129.598 -3 + vertex 127.002 129.998 -3 + vertex 128.315 129.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 128.315 129.696 -3 + vertex 127.002 129.998 -3 + vertex 128.124 129.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 129.649 128.408 -3 + vertex 127.002 129.998 -3 + vertex 129.544 128.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.726 129.911 -3 + vertex 127.002 129.998 -3 + vertex 127.521 129.954 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 127.726 129.911 -3 + vertex 127.927 129.853 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 129.819 128.026 -3 + vertex 129.884 127.827 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal -0 -0 -1 + outer loop + vertex 127.314 129.984 -3 + vertex 127.521 129.954 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 129.998 -3 + vertex 129.934 127.624 -3 + vertex 129.971 127.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 129.998 -3 + vertex 127.105 129.998 -3 + vertex 127.314 129.984 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 130 127 -3 + vertex 127.002 129.998 -3 + vertex 129.993 127.209 -3 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex -127 130 -3 + vertex 127 130 -3 + vertex -127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex 127 130 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 -129.998 -3 + vertex -127.002 129.998 -3 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -130 -127 -3 + vertex -130 127 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -127.314 129.984 -3 + vertex -127.105 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -127.521 129.954 -3 + vertex -127.314 129.984 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -127.726 129.911 -3 + vertex -127.521 129.954 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -127.927 129.853 -3 + vertex -127.726 129.911 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -128.124 129.782 -3 + vertex -127.927 129.853 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -128.315 129.696 -3 + vertex -128.124 129.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -128.5 129.598 -3 + vertex -128.315 129.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -128.678 129.487 -3 + vertex -128.5 129.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -128.847 129.364 -3 + vertex -128.678 129.487 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.007 129.229 -3 + vertex -128.847 129.364 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.158 129.084 -3 + vertex -129.007 129.229 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.298 128.928 -3 + vertex -129.158 129.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.427 128.763 -3 + vertex -129.298 128.928 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.544 128.59 -3 + vertex -129.427 128.763 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.649 128.408 -3 + vertex -129.544 128.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.741 128.22 -3 + vertex -129.649 128.408 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.819 128.026 -3 + vertex -129.741 128.22 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.884 127.827 -3 + vertex -129.819 128.026 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.934 127.624 -3 + vertex -129.884 127.827 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.971 127.418 -3 + vertex -129.934 127.624 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -129.993 127.209 -3 + vertex -129.971 127.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 129.998 -3 + vertex -130 127 -3 + vertex -129.993 127.209 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -130 127 -3 + vertex -127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 127.002 -129.998 -3 + vertex -127.002 -129.998 -3 + vertex -127.002 129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -129.971 -127.418 -3 + vertex -129.993 -127.209 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.884 -127.827 -3 + vertex -129.934 -127.624 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.741 -128.22 -3 + vertex -127.002 -129.998 -3 + vertex -129.649 -128.408 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.741 -128.22 -3 + vertex -129.819 -128.026 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -129.007 -129.229 -3 + vertex -129.158 -129.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.427 -128.763 -3 + vertex -127.002 -129.998 -3 + vertex -129.298 -128.928 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.427 -128.763 -3 + vertex -129.544 -128.59 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.298 -128.928 -3 + vertex -127.002 -129.998 -3 + vertex -129.158 -129.084 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -127.927 -129.853 -3 + vertex -128.124 -129.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -128.847 -129.364 -3 + vertex -127.002 -129.998 -3 + vertex -128.678 -129.487 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -128.847 -129.364 -3 + vertex -129.007 -129.229 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -128.678 -129.487 -3 + vertex -127.002 -129.998 -3 + vertex -128.5 -129.598 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -128.5 -129.598 -3 + vertex -127.002 -129.998 -3 + vertex -128.315 -129.696 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -128.315 -129.696 -3 + vertex -127.002 -129.998 -3 + vertex -128.124 -129.782 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.649 -128.408 -3 + vertex -127.002 -129.998 -3 + vertex -129.544 -128.59 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.726 -129.911 -3 + vertex -127.002 -129.998 -3 + vertex -127.521 -129.954 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.726 -129.911 -3 + vertex -127.927 -129.853 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -129.819 -128.026 -3 + vertex -129.884 -127.827 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.314 -129.984 -3 + vertex -127.521 -129.954 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -129.934 -127.624 -3 + vertex -129.971 -127.418 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex -127.105 -129.998 -3 + vertex -127.314 -129.984 -3 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 127.002 -129.998 -3 + vertex 127 -130 -3 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -127.002 -129.998 -3 + vertex 127 -130 -3 + vertex -127 -130 -3 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex -130 -127 -3 + vertex -127.002 -129.998 -3 + vertex -129.993 -127.209 -3 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.314 -129.984 0 + vertex 127.002 -129.998 0 + vertex 127.105 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.521 -129.954 0 + vertex 127.002 -129.998 0 + vertex 127.314 -129.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 127.002 -129.998 0 + vertex 130 -127 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.726 -129.911 0 + vertex 127.002 -129.998 0 + vertex 127.521 -129.954 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.927 -129.853 0 + vertex 127.002 -129.998 0 + vertex 127.726 -129.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.124 -129.782 0 + vertex 127.002 -129.998 0 + vertex 127.927 -129.853 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.315 -129.696 0 + vertex 127.002 -129.998 0 + vertex 128.124 -129.782 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.5 -129.598 0 + vertex 127.002 -129.998 0 + vertex 128.315 -129.696 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.678 -129.487 0 + vertex 127.002 -129.998 0 + vertex 128.5 -129.598 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.847 -129.364 0 + vertex 127.002 -129.998 0 + vertex 128.678 -129.487 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.007 -129.229 0 + vertex 127.002 -129.998 0 + vertex 128.847 -129.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.158 -129.084 0 + vertex 127.002 -129.998 0 + vertex 129.007 -129.229 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.298 -128.928 0 + vertex 127.002 -129.998 0 + vertex 129.158 -129.084 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.427 -128.763 0 + vertex 127.002 -129.998 0 + vertex 129.298 -128.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.544 -128.59 0 + vertex 127.002 -129.998 0 + vertex 129.427 -128.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.649 -128.408 0 + vertex 127.002 -129.998 0 + vertex 129.544 -128.59 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.741 -128.22 0 + vertex 127.002 -129.998 0 + vertex 129.649 -128.408 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.819 -128.026 0 + vertex 127.002 -129.998 0 + vertex 129.741 -128.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.884 -127.827 0 + vertex 127.002 -129.998 0 + vertex 129.819 -128.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.934 -127.624 0 + vertex 127.002 -129.998 0 + vertex 129.884 -127.827 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.971 -127.418 0 + vertex 127.002 -129.998 0 + vertex 129.934 -127.624 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.993 -127.209 0 + vertex 127.002 -129.998 0 + vertex 129.971 -127.418 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 130 -127 0 + vertex 127.002 -129.998 0 + vertex 129.993 -127.209 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 130 127 0 + vertex 127.002 129.998 0 + vertex 130 -127 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.993 127.209 0 + vertex 129.971 127.418 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 129.934 127.624 0 + vertex 129.884 127.827 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.649 128.408 0 + vertex 127.002 129.998 0 + vertex 129.741 128.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 129.819 128.026 0 + vertex 129.741 128.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.158 129.084 0 + vertex 129.007 129.229 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.298 128.928 0 + vertex 127.002 129.998 0 + vertex 129.427 128.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 129.544 128.59 0 + vertex 129.427 128.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.158 129.084 0 + vertex 127.002 129.998 0 + vertex 129.298 128.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.124 129.782 0 + vertex 127.927 129.853 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.678 129.487 0 + vertex 127.002 129.998 0 + vertex 128.847 129.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 129.007 129.229 0 + vertex 128.847 129.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.5 129.598 0 + vertex 127.002 129.998 0 + vertex 128.678 129.487 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.315 129.696 0 + vertex 127.002 129.998 0 + vertex 128.5 129.598 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 128.124 129.782 0 + vertex 127.002 129.998 0 + vertex 128.315 129.696 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.544 128.59 0 + vertex 127.002 129.998 0 + vertex 129.649 128.408 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.521 129.954 0 + vertex 127.002 129.998 0 + vertex 127.726 129.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 127.927 129.853 0 + vertex 127.726 129.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 129.884 127.827 0 + vertex 129.819 128.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 127.521 129.954 0 + vertex 127.314 129.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.971 127.418 0 + vertex 129.934 127.624 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.314 129.984 0 + vertex 127.105 129.998 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 129.993 127.209 0 + vertex 127.002 129.998 0 + vertex 130 127 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 129.998 0 + vertex 127 130 0 + vertex -127 130 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex 127 130 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 127.002 129.998 0 + vertex -127.002 129.998 0 + vertex 127.002 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -130 127 0 + vertex -130 -127 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.105 129.998 0 + vertex -127.314 129.984 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.314 129.984 0 + vertex -127.521 129.954 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.521 129.954 0 + vertex -127.726 129.911 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.726 129.911 0 + vertex -127.927 129.853 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.927 129.853 0 + vertex -128.124 129.782 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -128.124 129.782 0 + vertex -128.315 129.696 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -128.315 129.696 0 + vertex -128.5 129.598 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -128.5 129.598 0 + vertex -128.678 129.487 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -128.678 129.487 0 + vertex -128.847 129.364 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -128.847 129.364 0 + vertex -129.007 129.229 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.007 129.229 0 + vertex -129.158 129.084 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.158 129.084 0 + vertex -129.298 128.928 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.298 128.928 0 + vertex -129.427 128.763 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.427 128.763 0 + vertex -129.544 128.59 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.544 128.59 0 + vertex -129.649 128.408 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.649 128.408 0 + vertex -129.741 128.22 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.741 128.22 0 + vertex -129.819 128.026 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.819 128.026 0 + vertex -129.884 127.827 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.884 127.827 0 + vertex -129.934 127.624 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.934 127.624 0 + vertex -129.971 127.418 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.971 127.418 0 + vertex -129.993 127.209 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -129.993 127.209 0 + vertex -130 127 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 129.998 0 + vertex -130 127 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 129.998 0 + vertex -127.002 -129.998 0 + vertex 127.002 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -129.993 -127.209 0 + vertex -129.971 -127.418 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -129.934 -127.624 0 + vertex -129.884 -127.827 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -129.649 -128.408 0 + vertex -127.002 -129.998 0 + vertex -129.741 -128.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -129.819 -128.026 0 + vertex -129.741 -128.22 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -129.158 -129.084 0 + vertex -129.007 -129.229 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -129.298 -128.928 0 + vertex -127.002 -129.998 0 + vertex -129.427 -128.763 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -129.544 -128.59 0 + vertex -129.427 -128.763 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -129.158 -129.084 0 + vertex -127.002 -129.998 0 + vertex -129.298 -128.928 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -128.124 -129.782 0 + vertex -127.927 -129.853 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -128.678 -129.487 0 + vertex -127.002 -129.998 0 + vertex -128.847 -129.364 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -129.007 -129.229 0 + vertex -128.847 -129.364 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -128.5 -129.598 0 + vertex -127.002 -129.998 0 + vertex -128.678 -129.487 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -128.315 -129.696 0 + vertex -127.002 -129.998 0 + vertex -128.5 -129.598 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -128.124 -129.782 0 + vertex -127.002 -129.998 0 + vertex -128.315 -129.696 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -129.544 -128.59 0 + vertex -127.002 -129.998 0 + vertex -129.649 -128.408 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -127.521 -129.954 0 + vertex -127.002 -129.998 0 + vertex -127.726 -129.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -127.927 -129.853 0 + vertex -127.726 -129.911 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -129.884 -127.827 0 + vertex -129.819 -128.026 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex -127.521 -129.954 0 + vertex -127.314 -129.984 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -129.971 -127.418 0 + vertex -129.934 -127.624 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex -127.314 -129.984 0 + vertex -127.105 -129.998 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal -0 0 1 + outer loop + vertex -127.002 -129.998 0 + vertex 127 -130 0 + vertex 127.002 -129.998 0 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex -127 -130 0 + vertex 127 -130 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal -0 -0 1 + outer loop + vertex -129.993 -127.209 0 + vertex -127.002 -129.998 0 + vertex -130 -127 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 127.105 -129.998 -3 + vertex 127.002 -129.998 0 + vertex 127.002 -129.998 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 127.105 -129.998 -3 + vertex 127.105 -129.998 0 + vertex 127.002 -129.998 0 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 127.314 -129.984 -3 + vertex 127.105 -129.998 0 + vertex 127.105 -129.998 -3 + endloop + endfacet + facet normal 0.0668359 -0.997764 0 + outer loop + vertex 127.314 -129.984 -3 + vertex 127.314 -129.984 0 + vertex 127.105 -129.998 0 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 127.521 -129.954 -3 + vertex 127.314 -129.984 0 + vertex 127.314 -129.984 -3 + endloop + endfacet + facet normal 0.143429 -0.989661 0 + outer loop + vertex 127.521 -129.954 -3 + vertex 127.521 -129.954 0 + vertex 127.314 -129.984 0 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 127.726 -129.911 -3 + vertex 127.521 -129.954 0 + vertex 127.521 -129.954 -3 + endloop + endfacet + facet normal 0.205289 -0.978701 0 + outer loop + vertex 127.726 -129.911 -3 + vertex 127.726 -129.911 0 + vertex 127.521 -129.954 0 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 127.927 -129.853 -3 + vertex 127.726 -129.911 0 + vertex 127.726 -129.911 -3 + endloop + endfacet + facet normal 0.277246 -0.960799 0 + outer loop + vertex 127.927 -129.853 -3 + vertex 127.927 -129.853 0 + vertex 127.726 -129.911 0 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 128.124 -129.782 -3 + vertex 127.927 -129.853 0 + vertex 127.927 -129.853 -3 + endloop + endfacet + facet normal 0.339058 -0.940766 0 + outer loop + vertex 128.124 -129.782 -3 + vertex 128.124 -129.782 0 + vertex 127.927 -129.853 0 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 128.315 -129.696 -3 + vertex 128.124 -129.782 0 + vertex 128.124 -129.782 -3 + endloop + endfacet + facet normal 0.410563 -0.911832 0 + outer loop + vertex 128.315 -129.696 -3 + vertex 128.315 -129.696 0 + vertex 128.124 -129.782 0 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 128.5 -129.598 -3 + vertex 128.315 -129.696 0 + vertex 128.315 -129.696 -3 + endloop + endfacet + facet normal 0.468107 -0.883672 0 + outer loop + vertex 128.5 -129.598 -3 + vertex 128.5 -129.598 0 + vertex 128.315 -129.696 0 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 128.678 -129.487 -3 + vertex 128.5 -129.598 0 + vertex 128.5 -129.598 -3 + endloop + endfacet + facet normal 0.529142 -0.848533 0 + outer loop + vertex 128.678 -129.487 -3 + vertex 128.678 -129.487 0 + vertex 128.5 -129.598 0 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 128.847 -129.364 -3 + vertex 128.678 -129.487 0 + vertex 128.678 -129.487 -3 + endloop + endfacet + facet normal 0.588456 -0.808529 0 + outer loop + vertex 128.847 -129.364 -3 + vertex 128.847 -129.364 0 + vertex 128.678 -129.487 0 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 129.007 -129.229 -3 + vertex 128.847 -129.364 0 + vertex 128.847 -129.364 -3 + endloop + endfacet + facet normal 0.644871 -0.764291 0 + outer loop + vertex 129.007 -129.229 -3 + vertex 129.007 -129.229 0 + vertex 128.847 -129.364 0 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 129.158 -129.084 -3 + vertex 129.007 -129.229 0 + vertex 129.007 -129.229 -3 + endloop + endfacet + facet normal 0.692631 -0.721292 0 + outer loop + vertex 129.158 -129.084 -3 + vertex 129.158 -129.084 0 + vertex 129.007 -129.229 0 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 129.298 -128.928 -3 + vertex 129.158 -129.084 0 + vertex 129.158 -129.084 -3 + endloop + endfacet + facet normal 0.744242 -0.66791 0 + outer loop + vertex 129.298 -128.928 -3 + vertex 129.298 -128.928 0 + vertex 129.158 -129.084 0 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 129.427 -128.763 -3 + vertex 129.298 -128.928 0 + vertex 129.298 -128.928 -3 + endloop + endfacet + facet normal 0.787807 -0.615922 0 + outer loop + vertex 129.427 -128.763 -3 + vertex 129.427 -128.763 0 + vertex 129.298 -128.928 0 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 129.544 -128.59 -3 + vertex 129.427 -128.763 0 + vertex 129.427 -128.763 -3 + endloop + endfacet + facet normal 0.828349 -0.560213 0 + outer loop + vertex 129.544 -128.59 -3 + vertex 129.544 -128.59 0 + vertex 129.427 -128.763 0 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 129.649 -128.408 -3 + vertex 129.544 -128.59 0 + vertex 129.544 -128.59 -3 + endloop + endfacet + facet normal 0.866186 -0.499722 0 + outer loop + vertex 129.649 -128.408 -3 + vertex 129.649 -128.408 0 + vertex 129.544 -128.59 0 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 129.741 -128.22 -3 + vertex 129.649 -128.408 0 + vertex 129.649 -128.408 -3 + endloop + endfacet + facet normal 0.898217 -0.439553 0 + outer loop + vertex 129.741 -128.22 -3 + vertex 129.741 -128.22 0 + vertex 129.649 -128.408 0 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 129.819 -128.026 -3 + vertex 129.741 -128.22 0 + vertex 129.741 -128.22 -3 + endloop + endfacet + facet normal 0.927816 -0.373039 0 + outer loop + vertex 129.819 -128.026 -3 + vertex 129.819 -128.026 0 + vertex 129.741 -128.22 0 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 129.884 -127.827 -3 + vertex 129.819 -128.026 0 + vertex 129.819 -128.026 -3 + endloop + endfacet + facet normal 0.950577 -0.31049 0 + outer loop + vertex 129.884 -127.827 -3 + vertex 129.884 -127.827 0 + vertex 129.819 -128.026 0 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 129.934 -127.624 -3 + vertex 129.884 -127.827 0 + vertex 129.884 -127.827 -3 + endloop + endfacet + facet normal 0.970981 -0.239158 0 + outer loop + vertex 129.934 -127.624 -3 + vertex 129.934 -127.624 0 + vertex 129.884 -127.827 0 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 129.971 -127.418 -3 + vertex 129.934 -127.624 0 + vertex 129.934 -127.624 -3 + endloop + endfacet + facet normal 0.98425 -0.176783 0 + outer loop + vertex 129.971 -127.418 -3 + vertex 129.971 -127.418 0 + vertex 129.934 -127.624 0 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 129.993 -127.209 -3 + vertex 129.971 -127.418 0 + vertex 129.971 -127.418 -3 + endloop + endfacet + facet normal 0.994505 -0.104685 0 + outer loop + vertex 129.993 -127.209 -3 + vertex 129.993 -127.209 0 + vertex 129.971 -127.418 0 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 130 -127 -3 + vertex 129.993 -127.209 0 + vertex 129.993 -127.209 -3 + endloop + endfacet + facet normal 0.99944 -0.0334741 0 + outer loop + vertex 130 -127 -3 + vertex 130 -127 0 + vertex 129.993 -127.209 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 130 127 -3 + vertex 130 -127 0 + vertex 130 -127 -3 + endloop + endfacet + facet normal 1 0 -0 + outer loop + vertex 130 127 -3 + vertex 130 127 0 + vertex 130 -127 0 + endloop + endfacet + facet normal 0.99944 0.0334741 0 + outer loop + vertex 129.993 127.209 -3 + vertex 130 127 0 + vertex 130 127 -3 + endloop + endfacet + facet normal 0.99944 0.0334741 -0 + outer loop + vertex 129.993 127.209 -3 + vertex 129.993 127.209 0 + vertex 130 127 0 + endloop + endfacet + facet normal 0.994505 0.104685 0 + outer loop + vertex 129.971 127.418 -3 + vertex 129.993 127.209 0 + vertex 129.993 127.209 -3 + endloop + endfacet + facet normal 0.994505 0.104685 -0 + outer loop + vertex 129.971 127.418 -3 + vertex 129.971 127.418 0 + vertex 129.993 127.209 0 + endloop + endfacet + facet normal 0.98425 0.176783 0 + outer loop + vertex 129.934 127.624 -3 + vertex 129.971 127.418 0 + vertex 129.971 127.418 -3 + endloop + endfacet + facet normal 0.98425 0.176783 -0 + outer loop + vertex 129.934 127.624 -3 + vertex 129.934 127.624 0 + vertex 129.971 127.418 0 + endloop + endfacet + facet normal 0.970981 0.239158 0 + outer loop + vertex 129.884 127.827 -3 + vertex 129.934 127.624 0 + vertex 129.934 127.624 -3 + endloop + endfacet + facet normal 0.970981 0.239158 -0 + outer loop + vertex 129.884 127.827 -3 + vertex 129.884 127.827 0 + vertex 129.934 127.624 0 + endloop + endfacet + facet normal 0.950577 0.31049 0 + outer loop + vertex 129.819 128.026 -3 + vertex 129.884 127.827 0 + vertex 129.884 127.827 -3 + endloop + endfacet + facet normal 0.950577 0.31049 -0 + outer loop + vertex 129.819 128.026 -3 + vertex 129.819 128.026 0 + vertex 129.884 127.827 0 + endloop + endfacet + facet normal 0.927816 0.373039 0 + outer loop + vertex 129.741 128.22 -3 + vertex 129.819 128.026 0 + vertex 129.819 128.026 -3 + endloop + endfacet + facet normal 0.927816 0.373039 -0 + outer loop + vertex 129.741 128.22 -3 + vertex 129.741 128.22 0 + vertex 129.819 128.026 0 + endloop + endfacet + facet normal 0.898217 0.439553 0 + outer loop + vertex 129.649 128.408 -3 + vertex 129.741 128.22 0 + vertex 129.741 128.22 -3 + endloop + endfacet + facet normal 0.898217 0.439553 -0 + outer loop + vertex 129.649 128.408 -3 + vertex 129.649 128.408 0 + vertex 129.741 128.22 0 + endloop + endfacet + facet normal 0.866186 0.499722 0 + outer loop + vertex 129.544 128.59 -3 + vertex 129.649 128.408 0 + vertex 129.649 128.408 -3 + endloop + endfacet + facet normal 0.866186 0.499722 -0 + outer loop + vertex 129.544 128.59 -3 + vertex 129.544 128.59 0 + vertex 129.649 128.408 0 + endloop + endfacet + facet normal 0.828349 0.560213 0 + outer loop + vertex 129.427 128.763 -3 + vertex 129.544 128.59 0 + vertex 129.544 128.59 -3 + endloop + endfacet + facet normal 0.828349 0.560213 -0 + outer loop + vertex 129.427 128.763 -3 + vertex 129.427 128.763 0 + vertex 129.544 128.59 0 + endloop + endfacet + facet normal 0.787807 0.615922 0 + outer loop + vertex 129.298 128.928 -3 + vertex 129.427 128.763 0 + vertex 129.427 128.763 -3 + endloop + endfacet + facet normal 0.787807 0.615922 -0 + outer loop + vertex 129.298 128.928 -3 + vertex 129.298 128.928 0 + vertex 129.427 128.763 0 + endloop + endfacet + facet normal 0.744242 0.66791 0 + outer loop + vertex 129.158 129.084 -3 + vertex 129.298 128.928 0 + vertex 129.298 128.928 -3 + endloop + endfacet + facet normal 0.744242 0.66791 -0 + outer loop + vertex 129.158 129.084 -3 + vertex 129.158 129.084 0 + vertex 129.298 128.928 0 + endloop + endfacet + facet normal 0.692631 0.721292 0 + outer loop + vertex 129.007 129.229 -3 + vertex 129.158 129.084 0 + vertex 129.158 129.084 -3 + endloop + endfacet + facet normal 0.692631 0.721292 -0 + outer loop + vertex 129.007 129.229 -3 + vertex 129.007 129.229 0 + vertex 129.158 129.084 0 + endloop + endfacet + facet normal 0.644871 0.764291 0 + outer loop + vertex 128.847 129.364 -3 + vertex 129.007 129.229 0 + vertex 129.007 129.229 -3 + endloop + endfacet + facet normal 0.644871 0.764291 -0 + outer loop + vertex 128.847 129.364 -3 + vertex 128.847 129.364 0 + vertex 129.007 129.229 0 + endloop + endfacet + facet normal 0.588456 0.808529 0 + outer loop + vertex 128.678 129.487 -3 + vertex 128.847 129.364 0 + vertex 128.847 129.364 -3 + endloop + endfacet + facet normal 0.588456 0.808529 -0 + outer loop + vertex 128.678 129.487 -3 + vertex 128.678 129.487 0 + vertex 128.847 129.364 0 + endloop + endfacet + facet normal 0.529142 0.848533 0 + outer loop + vertex 128.5 129.598 -3 + vertex 128.678 129.487 0 + vertex 128.678 129.487 -3 + endloop + endfacet + facet normal 0.529142 0.848533 -0 + outer loop + vertex 128.5 129.598 -3 + vertex 128.5 129.598 0 + vertex 128.678 129.487 0 + endloop + endfacet + facet normal 0.468107 0.883672 0 + outer loop + vertex 128.315 129.696 -3 + vertex 128.5 129.598 0 + vertex 128.5 129.598 -3 + endloop + endfacet + facet normal 0.468107 0.883672 -0 + outer loop + vertex 128.315 129.696 -3 + vertex 128.315 129.696 0 + vertex 128.5 129.598 0 + endloop + endfacet + facet normal 0.410563 0.911832 0 + outer loop + vertex 128.124 129.782 -3 + vertex 128.315 129.696 0 + vertex 128.315 129.696 -3 + endloop + endfacet + facet normal 0.410563 0.911832 -0 + outer loop + vertex 128.124 129.782 -3 + vertex 128.124 129.782 0 + vertex 128.315 129.696 0 + endloop + endfacet + facet normal 0.339058 0.940766 0 + outer loop + vertex 127.927 129.853 -3 + vertex 128.124 129.782 0 + vertex 128.124 129.782 -3 + endloop + endfacet + facet normal 0.339058 0.940766 -0 + outer loop + vertex 127.927 129.853 -3 + vertex 127.927 129.853 0 + vertex 128.124 129.782 0 + endloop + endfacet + facet normal 0.277246 0.960799 0 + outer loop + vertex 127.726 129.911 -3 + vertex 127.927 129.853 0 + vertex 127.927 129.853 -3 + endloop + endfacet + facet normal 0.277246 0.960799 -0 + outer loop + vertex 127.726 129.911 -3 + vertex 127.726 129.911 0 + vertex 127.927 129.853 0 + endloop + endfacet + facet normal 0.205289 0.978701 0 + outer loop + vertex 127.521 129.954 -3 + vertex 127.726 129.911 0 + vertex 127.726 129.911 -3 + endloop + endfacet + facet normal 0.205289 0.978701 -0 + outer loop + vertex 127.521 129.954 -3 + vertex 127.521 129.954 0 + vertex 127.726 129.911 0 + endloop + endfacet + facet normal 0.143429 0.989661 0 + outer loop + vertex 127.314 129.984 -3 + vertex 127.521 129.954 0 + vertex 127.521 129.954 -3 + endloop + endfacet + facet normal 0.143429 0.989661 -0 + outer loop + vertex 127.314 129.984 -3 + vertex 127.314 129.984 0 + vertex 127.521 129.954 0 + endloop + endfacet + facet normal 0.0668359 0.997764 0 + outer loop + vertex 127.105 129.998 -3 + vertex 127.314 129.984 0 + vertex 127.314 129.984 -3 + endloop + endfacet + facet normal 0.0668359 0.997764 -0 + outer loop + vertex 127.105 129.998 -3 + vertex 127.105 129.998 0 + vertex 127.314 129.984 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 127.002 129.998 -3 + vertex 127.105 129.998 0 + vertex 127.105 129.998 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 127.002 129.998 -3 + vertex 127.002 129.998 0 + vertex 127.105 129.998 0 + endloop + endfacet + facet normal 0.707107 0.707107 0 + outer loop + vertex 127 130 -3 + vertex 127.002 129.998 0 + vertex 127.002 129.998 -3 + endloop + endfacet + facet normal 0.707107 0.707107 -0 + outer loop + vertex 127 130 -3 + vertex 127 130 0 + vertex 127.002 129.998 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -127 130 -3 + vertex 127 130 0 + vertex 127 130 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -127 130 -3 + vertex -127 130 0 + vertex 127 130 0 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -127.002 129.998 -3 + vertex -127 130 0 + vertex -127 130 -3 + endloop + endfacet + facet normal -0.707107 0.707107 0 + outer loop + vertex -127.002 129.998 -3 + vertex -127.002 129.998 0 + vertex -127 130 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -127.105 129.998 -3 + vertex -127.002 129.998 0 + vertex -127.002 129.998 -3 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex -127.105 129.998 -3 + vertex -127.105 129.998 0 + vertex -127.002 129.998 0 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -127.314 129.984 -3 + vertex -127.105 129.998 0 + vertex -127.105 129.998 -3 + endloop + endfacet + facet normal -0.0668359 0.997764 0 + outer loop + vertex -127.314 129.984 -3 + vertex -127.314 129.984 0 + vertex -127.105 129.998 0 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -127.521 129.954 -3 + vertex -127.314 129.984 0 + vertex -127.314 129.984 -3 + endloop + endfacet + facet normal -0.143429 0.989661 0 + outer loop + vertex -127.521 129.954 -3 + vertex -127.521 129.954 0 + vertex -127.314 129.984 0 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -127.726 129.911 -3 + vertex -127.521 129.954 0 + vertex -127.521 129.954 -3 + endloop + endfacet + facet normal -0.205289 0.978701 0 + outer loop + vertex -127.726 129.911 -3 + vertex -127.726 129.911 0 + vertex -127.521 129.954 0 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -127.927 129.853 -3 + vertex -127.726 129.911 0 + vertex -127.726 129.911 -3 + endloop + endfacet + facet normal -0.277246 0.960799 0 + outer loop + vertex -127.927 129.853 -3 + vertex -127.927 129.853 0 + vertex -127.726 129.911 0 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -128.124 129.782 -3 + vertex -127.927 129.853 0 + vertex -127.927 129.853 -3 + endloop + endfacet + facet normal -0.339058 0.940766 0 + outer loop + vertex -128.124 129.782 -3 + vertex -128.124 129.782 0 + vertex -127.927 129.853 0 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -128.315 129.696 -3 + vertex -128.124 129.782 0 + vertex -128.124 129.782 -3 + endloop + endfacet + facet normal -0.410563 0.911832 0 + outer loop + vertex -128.315 129.696 -3 + vertex -128.315 129.696 0 + vertex -128.124 129.782 0 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -128.5 129.598 -3 + vertex -128.315 129.696 0 + vertex -128.315 129.696 -3 + endloop + endfacet + facet normal -0.468107 0.883672 0 + outer loop + vertex -128.5 129.598 -3 + vertex -128.5 129.598 0 + vertex -128.315 129.696 0 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -128.678 129.487 -3 + vertex -128.5 129.598 0 + vertex -128.5 129.598 -3 + endloop + endfacet + facet normal -0.529142 0.848533 0 + outer loop + vertex -128.678 129.487 -3 + vertex -128.678 129.487 0 + vertex -128.5 129.598 0 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -128.847 129.364 -3 + vertex -128.678 129.487 0 + vertex -128.678 129.487 -3 + endloop + endfacet + facet normal -0.588456 0.808529 0 + outer loop + vertex -128.847 129.364 -3 + vertex -128.847 129.364 0 + vertex -128.678 129.487 0 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -129.007 129.229 -3 + vertex -128.847 129.364 0 + vertex -128.847 129.364 -3 + endloop + endfacet + facet normal -0.644871 0.764291 0 + outer loop + vertex -129.007 129.229 -3 + vertex -129.007 129.229 0 + vertex -128.847 129.364 0 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -129.158 129.084 -3 + vertex -129.007 129.229 0 + vertex -129.007 129.229 -3 + endloop + endfacet + facet normal -0.692631 0.721292 0 + outer loop + vertex -129.158 129.084 -3 + vertex -129.158 129.084 0 + vertex -129.007 129.229 0 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -129.298 128.928 -3 + vertex -129.158 129.084 0 + vertex -129.158 129.084 -3 + endloop + endfacet + facet normal -0.744242 0.66791 0 + outer loop + vertex -129.298 128.928 -3 + vertex -129.298 128.928 0 + vertex -129.158 129.084 0 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -129.427 128.763 -3 + vertex -129.298 128.928 0 + vertex -129.298 128.928 -3 + endloop + endfacet + facet normal -0.787807 0.615922 0 + outer loop + vertex -129.427 128.763 -3 + vertex -129.427 128.763 0 + vertex -129.298 128.928 0 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -129.544 128.59 -3 + vertex -129.427 128.763 0 + vertex -129.427 128.763 -3 + endloop + endfacet + facet normal -0.828349 0.560213 0 + outer loop + vertex -129.544 128.59 -3 + vertex -129.544 128.59 0 + vertex -129.427 128.763 0 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -129.649 128.408 -3 + vertex -129.544 128.59 0 + vertex -129.544 128.59 -3 + endloop + endfacet + facet normal -0.866186 0.499722 0 + outer loop + vertex -129.649 128.408 -3 + vertex -129.649 128.408 0 + vertex -129.544 128.59 0 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -129.741 128.22 -3 + vertex -129.649 128.408 0 + vertex -129.649 128.408 -3 + endloop + endfacet + facet normal -0.898217 0.439553 0 + outer loop + vertex -129.741 128.22 -3 + vertex -129.741 128.22 0 + vertex -129.649 128.408 0 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -129.819 128.026 -3 + vertex -129.741 128.22 0 + vertex -129.741 128.22 -3 + endloop + endfacet + facet normal -0.927816 0.373039 0 + outer loop + vertex -129.819 128.026 -3 + vertex -129.819 128.026 0 + vertex -129.741 128.22 0 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -129.884 127.827 -3 + vertex -129.819 128.026 0 + vertex -129.819 128.026 -3 + endloop + endfacet + facet normal -0.950577 0.31049 0 + outer loop + vertex -129.884 127.827 -3 + vertex -129.884 127.827 0 + vertex -129.819 128.026 0 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -129.934 127.624 -3 + vertex -129.884 127.827 0 + vertex -129.884 127.827 -3 + endloop + endfacet + facet normal -0.970981 0.239158 0 + outer loop + vertex -129.934 127.624 -3 + vertex -129.934 127.624 0 + vertex -129.884 127.827 0 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -129.971 127.418 -3 + vertex -129.934 127.624 0 + vertex -129.934 127.624 -3 + endloop + endfacet + facet normal -0.98425 0.176783 0 + outer loop + vertex -129.971 127.418 -3 + vertex -129.971 127.418 0 + vertex -129.934 127.624 0 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -129.993 127.209 -3 + vertex -129.971 127.418 0 + vertex -129.971 127.418 -3 + endloop + endfacet + facet normal -0.994505 0.104685 0 + outer loop + vertex -129.993 127.209 -3 + vertex -129.993 127.209 0 + vertex -129.971 127.418 0 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -130 127 -3 + vertex -129.993 127.209 0 + vertex -129.993 127.209 -3 + endloop + endfacet + facet normal -0.99944 0.0334741 0 + outer loop + vertex -130 127 -3 + vertex -130 127 0 + vertex -129.993 127.209 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -130 -127 -3 + vertex -130 127 0 + vertex -130 127 -3 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex -130 -127 -3 + vertex -130 -127 0 + vertex -130 127 0 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -129.993 -127.209 -3 + vertex -130 -127 0 + vertex -130 -127 -3 + endloop + endfacet + facet normal -0.99944 -0.0334741 0 + outer loop + vertex -129.993 -127.209 -3 + vertex -129.993 -127.209 0 + vertex -130 -127 0 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -129.971 -127.418 -3 + vertex -129.993 -127.209 0 + vertex -129.993 -127.209 -3 + endloop + endfacet + facet normal -0.994505 -0.104685 0 + outer loop + vertex -129.971 -127.418 -3 + vertex -129.971 -127.418 0 + vertex -129.993 -127.209 0 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -129.934 -127.624 -3 + vertex -129.971 -127.418 0 + vertex -129.971 -127.418 -3 + endloop + endfacet + facet normal -0.98425 -0.176783 0 + outer loop + vertex -129.934 -127.624 -3 + vertex -129.934 -127.624 0 + vertex -129.971 -127.418 0 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -129.884 -127.827 -3 + vertex -129.934 -127.624 0 + vertex -129.934 -127.624 -3 + endloop + endfacet + facet normal -0.970981 -0.239158 0 + outer loop + vertex -129.884 -127.827 -3 + vertex -129.884 -127.827 0 + vertex -129.934 -127.624 0 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -129.819 -128.026 -3 + vertex -129.884 -127.827 0 + vertex -129.884 -127.827 -3 + endloop + endfacet + facet normal -0.950577 -0.31049 0 + outer loop + vertex -129.819 -128.026 -3 + vertex -129.819 -128.026 0 + vertex -129.884 -127.827 0 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -129.741 -128.22 -3 + vertex -129.819 -128.026 0 + vertex -129.819 -128.026 -3 + endloop + endfacet + facet normal -0.927816 -0.373039 0 + outer loop + vertex -129.741 -128.22 -3 + vertex -129.741 -128.22 0 + vertex -129.819 -128.026 0 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -129.649 -128.408 -3 + vertex -129.741 -128.22 0 + vertex -129.741 -128.22 -3 + endloop + endfacet + facet normal -0.898217 -0.439553 0 + outer loop + vertex -129.649 -128.408 -3 + vertex -129.649 -128.408 0 + vertex -129.741 -128.22 0 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -129.544 -128.59 -3 + vertex -129.649 -128.408 0 + vertex -129.649 -128.408 -3 + endloop + endfacet + facet normal -0.866186 -0.499722 0 + outer loop + vertex -129.544 -128.59 -3 + vertex -129.544 -128.59 0 + vertex -129.649 -128.408 0 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -129.427 -128.763 -3 + vertex -129.544 -128.59 0 + vertex -129.544 -128.59 -3 + endloop + endfacet + facet normal -0.828349 -0.560213 0 + outer loop + vertex -129.427 -128.763 -3 + vertex -129.427 -128.763 0 + vertex -129.544 -128.59 0 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -129.298 -128.928 -3 + vertex -129.427 -128.763 0 + vertex -129.427 -128.763 -3 + endloop + endfacet + facet normal -0.787807 -0.615922 0 + outer loop + vertex -129.298 -128.928 -3 + vertex -129.298 -128.928 0 + vertex -129.427 -128.763 0 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -129.158 -129.084 -3 + vertex -129.298 -128.928 0 + vertex -129.298 -128.928 -3 + endloop + endfacet + facet normal -0.744242 -0.66791 0 + outer loop + vertex -129.158 -129.084 -3 + vertex -129.158 -129.084 0 + vertex -129.298 -128.928 0 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -129.007 -129.229 -3 + vertex -129.158 -129.084 0 + vertex -129.158 -129.084 -3 + endloop + endfacet + facet normal -0.692631 -0.721292 0 + outer loop + vertex -129.007 -129.229 -3 + vertex -129.007 -129.229 0 + vertex -129.158 -129.084 0 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -128.847 -129.364 -3 + vertex -129.007 -129.229 0 + vertex -129.007 -129.229 -3 + endloop + endfacet + facet normal -0.644871 -0.764291 0 + outer loop + vertex -128.847 -129.364 -3 + vertex -128.847 -129.364 0 + vertex -129.007 -129.229 0 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -128.678 -129.487 -3 + vertex -128.847 -129.364 0 + vertex -128.847 -129.364 -3 + endloop + endfacet + facet normal -0.588456 -0.808529 0 + outer loop + vertex -128.678 -129.487 -3 + vertex -128.678 -129.487 0 + vertex -128.847 -129.364 0 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -128.5 -129.598 -3 + vertex -128.678 -129.487 0 + vertex -128.678 -129.487 -3 + endloop + endfacet + facet normal -0.529142 -0.848533 0 + outer loop + vertex -128.5 -129.598 -3 + vertex -128.5 -129.598 0 + vertex -128.678 -129.487 0 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -128.315 -129.696 -3 + vertex -128.5 -129.598 0 + vertex -128.5 -129.598 -3 + endloop + endfacet + facet normal -0.468107 -0.883672 0 + outer loop + vertex -128.315 -129.696 -3 + vertex -128.315 -129.696 0 + vertex -128.5 -129.598 0 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -128.124 -129.782 -3 + vertex -128.315 -129.696 0 + vertex -128.315 -129.696 -3 + endloop + endfacet + facet normal -0.410563 -0.911832 0 + outer loop + vertex -128.124 -129.782 -3 + vertex -128.124 -129.782 0 + vertex -128.315 -129.696 0 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -127.927 -129.853 -3 + vertex -128.124 -129.782 0 + vertex -128.124 -129.782 -3 + endloop + endfacet + facet normal -0.339058 -0.940766 0 + outer loop + vertex -127.927 -129.853 -3 + vertex -127.927 -129.853 0 + vertex -128.124 -129.782 0 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -127.726 -129.911 -3 + vertex -127.927 -129.853 0 + vertex -127.927 -129.853 -3 + endloop + endfacet + facet normal -0.277246 -0.960799 0 + outer loop + vertex -127.726 -129.911 -3 + vertex -127.726 -129.911 0 + vertex -127.927 -129.853 0 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -127.521 -129.954 -3 + vertex -127.726 -129.911 0 + vertex -127.726 -129.911 -3 + endloop + endfacet + facet normal -0.205289 -0.978701 0 + outer loop + vertex -127.521 -129.954 -3 + vertex -127.521 -129.954 0 + vertex -127.726 -129.911 0 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -127.314 -129.984 -3 + vertex -127.521 -129.954 0 + vertex -127.521 -129.954 -3 + endloop + endfacet + facet normal -0.143429 -0.989661 0 + outer loop + vertex -127.314 -129.984 -3 + vertex -127.314 -129.984 0 + vertex -127.521 -129.954 0 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -127.105 -129.998 -3 + vertex -127.314 -129.984 0 + vertex -127.314 -129.984 -3 + endloop + endfacet + facet normal -0.0668359 -0.997764 0 + outer loop + vertex -127.105 -129.998 -3 + vertex -127.105 -129.998 0 + vertex -127.314 -129.984 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -127.002 -129.998 -3 + vertex -127.105 -129.998 0 + vertex -127.105 -129.998 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex -127.002 -129.998 -3 + vertex -127.002 -129.998 0 + vertex -127.105 -129.998 0 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -127 -130 -3 + vertex -127.002 -129.998 0 + vertex -127.002 -129.998 -3 + endloop + endfacet + facet normal -0.707107 -0.707107 0 + outer loop + vertex -127 -130 -3 + vertex -127 -130 0 + vertex -127.002 -129.998 0 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 127 -130 -3 + vertex -127 -130 0 + vertex -127 -130 -3 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 127 -130 -3 + vertex 127 -130 0 + vertex -127 -130 0 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 127.002 -129.998 -3 + vertex 127 -130 0 + vertex 127 -130 -3 + endloop + endfacet + facet normal 0.707107 -0.707107 0 + outer loop + vertex 127.002 -129.998 -3 + vertex 127.002 -129.998 0 + vertex 127 -130 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/resources/profiles/INAT.idx b/resources/profiles/INAT.idx new file mode 100644 index 0000000000..ff2873c12b --- /dev/null +++ b/resources/profiles/INAT.idx @@ -0,0 +1,2 @@ +min_slic3r_version = 2.3.0 +0.0.1 Initial version diff --git a/resources/profiles/INAT.ini b/resources/profiles/INAT.ini new file mode 100644 index 0000000000..0c4cbe5f4d --- /dev/null +++ b/resources/profiles/INAT.ini @@ -0,0 +1,467 @@ +# generated by PrusaSlicer 2.1.1+win64 on 2020-02-25 at 01:51:21 UTC + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = INAT s.r.o. +config_version = 0.0.1 +config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/INAT/ + +### +### PRINTER LIST +### + +[printer_model:PROTON_X_RAIL] +name = INAT Proton X Rail +variants = 0.4 +technology = FFF +family = Proton + +[printer_model:PROTON_X_ROD] +name = INAT Proton X Rod +variants = 0.4 +technology = FFF +family = Proton + + +### +### QUALITY DEFINITIONS +### + +[print:*common*] +#layers +layer_height = 0.2 +first_layer_height = 0.2 +perimeters = 3 +spiral_vase = 0 +top_solid_layers = 4 +bottom_solid_layers = 3 +top_solid_min_thickness = 0.8 +bottom_solid_min_thickness = 0.6 +extra_perimeters = 1 +ensure_vertical_shell_thickness = 1 +avoid_crossing_perimeters = 0 +thin_walls = 0 +overhangs = 1 +seam_position = aligned +external_perimeters_first = 0 +#infill +fill_density = 30% +fill_pattern = cubic +infill_anchor = 600% +infill_anchor_max = 30 +top_fill_pattern = monotonic +bottom_fill_patter = monotonic +ironing = 0 +ironing_type = top +infill_every_layers = 1 +infill_only_where_needed = 0 +solid_infill_every_layers = 0 +fill_angle = 45 +solid_infill_below_area = 20 +bridge_angle = 0 +only_retract_when_crossing_perimeters = 0 +infill_first = 0 +#skirt brim +skirts = 5 +skirt_distance = 15 +skirt_height = 1 +draft_shield = 0 +min_skirt_length = 5 +brim_width = 0 +#support +support_material = 0 +support_material_auto = 1 +support_material_threshold = 0 +support_material_enforce_layers = 0 +raft_layers = 0 +support_material_contact_distance = 0.2 +support_material_pattern = rectilinear +support_material_with_sheath = 0 +support_material_spacing = 5 +support_material_angle = 45 +support_material_interface_layers = 3 +support_material_interface_spacing = 0 +support_material_interface_contact_loops = 0 +support_material_buildplate_only = 0 +support_material_xy_spacing = 1 +dont_support_bridges = 1 +#speed +perimeter_speed = 60 +small_perimeter_speed = 75% +external_perimeter_speed = 50% +infill_speed = 80 +solid_infill_speed = 100% +top_solid_infill_speed = 30 +support_material_speed = 80 +support_material_interface_speed = 100% +bridge_speed = 60 +gap_fill_speed = 40 +ironing_speed = 30 +travel_speed = 150 +first_layer_speed = 30 +default_acceleration = 0 +max_print_speed = 80 +max_volumetric_speed = 12 +#multiple extruders +perimeter_extruder = 1 +infill_extruder = 1 +solid_infill_extruder = 1 +support_material_extruder = 1 +support_material_interface_extruder = 1 +ooze_prevention = 0 +wipe_tower = 0 +interface_shells = 0 +#advanced +extrusion_width = 0 +first_layer_extrusion_width = 0 +perimeter_extrusion_width = 0 +external_perimeter_extrusion_width = 0 +infill_extrusion_width = 0 +solid_infill_extrusion_width = 0 +top_infill_extrusion_width = 0 +support_material_extrusion_width = 0 +infill_overlap = 25% +bridge_flow_ratio = 1 +slice_closing_radius = 0.049 +resolution = 0 +xy_size_compensation = 0 +elefant_foot_compensation = 0.3 +clip_multipart_objects = 0 +#output +complete_objects = 0 +extruder_clearance_radius = 85 +extruder_clearance_height = 34 +gcode_comments = 0 +gcode_label_objects = 0 +output_filename_format = {input_filename_base}_{filament_type[0]}_{print_time}.gcode + + +[print:0.2mm Standard @PROTON_X] +inherits = *common* + +[print:0.2mm Strong @PROTON_X] +inherits = *common* +fill_density = 50% +perimeters = 6 + +[print:0.2mm Advanced Material @PROTON_X] +inherits = *common* +bottom_solid_layers = 5 +top_solid_layers = 6 +skirts = 0 +brim_width = 30 +infill_speed = 60 +support_material_speed = 60 +travel_speed = 100 +first_layer_speed = 20 +elefant_foot_compensation = 0 + +[print:0.12mm Fine @PROTON_X] +inherits = *common* +bottom_solid_layers = 7 +top_solid_layers = 7 +infill_every_layers = 2 +perimeter_speed = 50 +infill_speed = 50 + +[print:0.32mm Draft @PROTON_X] +inherits = *common* +perimeter_speed = 80 +external_perimeter_speed = 75% +infill_speed = 100 +top_solid_infill_speed = 60 +fill_density = 15% + +### +### PRINTER DEFINITIONS +### + +[printer:*common*] +printer_vendor = INAT s.r.o. +default_filament_profile = "PLA @PROTON_X" +#general +printer_technology = FFF +bed_shape = 0x0,304x0,304x304,0x304 +max_print_height = 650 +z_offset = 0 +extruders_count = 1 +gcode_flavor = marlin +silent_mode = 0 +remaining_times = 1 +use_relative_e_distances = 0 +use_firmware_retraction = 0 +use_volumetric_e = 0 +variable_layer_height = 1 +#gcodes +start_gcode = G28 ;Home\nG0 Z0.3 F200 ;Move nozzle down\nM192 S50 ; Wait for probe temperature to settle\nG29\nG0 X0 Y0 Z30 F6000\nM84 E\nM0\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0\n +end_gcode = M400\nM104 S0\nM140 S0\nM107\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X R5\nG0 Y300 F2000\nM84\n +color_change_gcode = M600 +#limits +machine_limits_usage = emit_to_gcode +machine_max_feedrate_x = 200,200 +machine_max_feedrate_y = 200,200 +machine_max_feedrate_z = 10,10 +machine_max_feedrate_e = 100,100 +machine_max_acceleration_x = 500,500 +machine_max_acceleration_y = 500,500 +machine_max_acceleration_z = 100,100 +machine_max_acceleration_e = 2000,2000 +machine_max_acceleration_extruding = 1000,1000 +machine_max_acceleration_retracting = 1500,1500 +machine_max_jerk_x = 8,8 +machine_max_jerk_y = 8,8 +machine_max_jerk_z = 1,1 +machine_max_jerk_e = 2.5,2.5 +machine_min_extruding_rate = 5 +#extruder 1 +nozzle_diameter = 0.4 +min_layer_height = 0.05 +max_layer_height = 0.33 +extruder_offset = 0x0 +retract_length = 1.5 +retract_lift = 0.6 +retract_lift_above = 0 +retract_lift_below = 0 +retract_speed = 45 +deretract_speed = 0 +retract_restart_extra = 0 +retract_before_travel = 2 +retract_layer_change = 0 +wipe = 1 +retract_before_wipe = 100% + + +[printer:Proton X Rail] +inherits = *common* +printer_model = PROTON_X_RAIL +printer_variant = 0.4 +default_print_profile = 0.2mm Standard @PROTON_X +gcode_flavor = marlin +machine_max_acceleration_y = 800,800 + +[printer:Proton X Rod] +inherits = *common* +printer_model = PROTON_X_ROD +printer_variant = 0.4 +default_print_profile = 0.2mm Standard @PROTON_X +gcode_flavor = marlin + + +### +### MATERIAL DEFINITIONS +### + +[filament:*common*] +#filament +filament_colour = #29B2B2 +filament_diameter = 1.75 +extrusion_multiplier = 1 +filament_vendor = Generic +#cooling +fan_always_on = 0 +cooling = 1 +bridge_fan_speed = 100 +disable_fan_first_layers = 3 +full_fan_speed_layer = 0 +fan_below_layer_time = 10 +slowdown_below_layer_time = 5 +min_print_speed = 10 +#advanced +filament_soluble = 0 + + +[filament:PLA @PROTON_X] +inherits = *common* +temperature = 210 +bed_temperature = 60 +first_layer_temperature = 210 +first_layer_bed_temperature = 60 +filament_type = PLA +filament_cost = 20 +filament_density = 1.25 +min_fan_speed = 50 +max_fan_speed = 100 + + +[filament:PETG @PROTON_X] +inherits = *common* +temperature = 240 +bed_temperature = 80 +first_layer_temperature = 240 +first_layer_bed_temperature = 80 +filament_type = PETG +filament_cost = 25 +filament_density = 1.27 +min_fan_speed = 0 +max_fan_speed = 50 + +[filament:ABS @PROTON_X] +inherits = *common* +temperature = 235 +bed_temperature = 100 +first_layer_temperature = 235 +first_layer_bed_temperature = 100 +filament_type = ABS +filament_cost = 20 +filament_density = 1.01 +cooling = 0 +bridge_fan_speed = 0 + +[filament:ASA @PROTON_X] +inherits = *common* +temperature = 240 +bed_temperature = 110 +first_layer_temperature = 240 +first_layer_bed_temperature = 110 +filament_type = ASA +filament_cost = 22 +filament_density = 1.07 +cooling = 0 + +[filament:TPE @PROTON_X] +inherits = *common* +temperature = 220 +bed_temperature = 40 +first_layer_temperature = 220 +first_layer_bed_temperature = 40 +filament_type = TPE +filament_cost = 32 +filament_density = 0.9 +min_fan_speed = 0 +max_fan_speed = 50 +filament_retract_length = 0.8 +filament_retract_speed = 25 + +[filament:HIPS @PROTON_X] +inherits = *common* +temperature = 245 +bed_temperature = 100 +first_layer_temperature = 245 +first_layer_bed_temperature = 100 +filament_type = HIPS +filament_cost = 15 +filament_density = 1.04 +min_fan_speed = 0 +max_fan_speed = 50 +filament_soluble = 1 + +[filament:Nylon @PROTON_X] +inherits = *common* +temperature = 235 +bed_temperature = 130 +first_layer_temperature = 235 +first_layer_bed_temperature = 130 +filament_type = Nylon +filament_cost = 70 +filament_density = 1.01 +cooling = 0 +bridge_fan_speed = 0 + +[filament:PC @PROTON_X] +inherits = *common* +temperature = 270 +bed_temperature = 130 +first_layer_temperature = 270 +first_layer_bed_temperature = 130 +filament_type = PC +filament_cost = 65 +filament_density = 1.19 +cooling = 0 +bridge_fan_speed = 0 + +[filament:CPE @PROTON_X] +inherits = *common* +temperature = 280 +bed_temperature = 90 +first_layer_temperature = 280 +first_layer_bed_temperature = 90 +filament_type = PEI +filament_cost = 380 +filament_density = 1.27 +cooling = 0 +bridge_fan_speed = 0 + +[filament:PEEK @PROTON_X] +inherits = *common* +temperature = 440 +bed_temperature = 150 +first_layer_temperature = 440 +first_layer_bed_temperature = 150 +filament_type = PEEK +filament_cost = 500 +filament_density = 1.3 +cooling = 0 +bridge_fan_speed = 0 + +[filament:PEI @PROTON_X] +inherits = *common* +temperature = 400 +bed_temperature = 150 +first_layer_temperature = 400 +first_layer_bed_temperature = 150 +filament_type = PEI +filament_cost = 380 +filament_density = 1.27 +cooling = 0 +bridge_fan_speed = 0 + +[filament:Polymaker PolyMide CoPA @PROTON_X] +inherits = *common* +filament_vendor = Polymaker +temperature = 265 +bed_temperature = 50 +first_layer_temperature = 265 +first_layer_bed_temperature = 50 +filament_type = Nylon +filament_cost = 93 +filament_density = 1.12 +cooling = 0 + +[filament:Polymaker PolyMide PA6-CF @PROTON_X] +inherits = *common* +filament_vendor = Polymaker +temperature = 300 +bed_temperature = 40 +first_layer_temperature = 300 +first_layer_bed_temperature = 40 +filament_type = Nylon +filament_cost = 95 +filament_density = 1.17 +cooling = 0 + +[filament:Polymaker PolyMide PA6-GF @PROTON_X] +inherits = *common* +filament_vendor = Polymaker +temperature = 300 +bed_temperature = 40 +first_layer_temperature = 300 +first_layer_bed_temperature = 40 +filament_type = Nylon +filament_cost = 95 +filament_density = 1.2 +cooling = 0 + +[filament:Devil Design PETG @PROTON_X] +inherits = *common* +filament_vendor = Devil Design +temperature = 250 +bed_temperature = 80 +first_layer_temperature = 250 +first_layer_bed_temperature = 80 +filament_type = PETG +filament_cost = 22 +filament_density = 1.23 +min_fan_speed = 0 +max_fan_speed = 50 + +[filament:Filament PM PETG FRJet @PROTON_X] +inherits = *common* +filament_vendor = Filament PM +temperature = 250 +bed_temperature = 90 +first_layer_temperature = 250 +first_layer_bed_temperature = 90 +filament_type = PETG +filament_cost = 45.5 +filament_density = 1.27 +cooling = 0 diff --git a/resources/profiles/INAT/PROTON_X_RAIL_thumbnail.png b/resources/profiles/INAT/PROTON_X_RAIL_thumbnail.png new file mode 100644 index 0000000000..eabc7e47c9 Binary files /dev/null and b/resources/profiles/INAT/PROTON_X_RAIL_thumbnail.png differ diff --git a/resources/profiles/INAT/PROTON_X_ROD_thumbnail.png b/resources/profiles/INAT/PROTON_X_ROD_thumbnail.png new file mode 100644 index 0000000000..c5e0362f79 Binary files /dev/null and b/resources/profiles/INAT/PROTON_X_ROD_thumbnail.png differ diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index b3077932cc..8c14026ce1 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,4 +1,6 @@ min_slic3r_version = 2.3.0-rc1 +1.2.4 Updated cost/density values in filament settings. Various changes in print settings. +1.2.3 Updated firmware version. Updated end g-code in MMU2 printer profiles. 1.2.2 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles. 1.2.1 Updated FW version for MK2.5 family printers. 1.2.0 Added full_fan_speed_layer value for PETG. Increased support interface spacing for 0.6mm nozzle profiles. Updated firmware version. @@ -10,6 +12,7 @@ min_slic3r_version = 2.3.0-alpha4 1.2.0-alpha1 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles. 1.2.0-alpha0 Added filament spool weights min_slic3r_version = 2.2.0-alpha3 +1.1.13 Updated firmware version. Updated end g-code in MMU2 printer profiles. 1.1.12 Added Prusament PVB filament profile. Added 0.8mm nozzle profiles. 1.1.11 Renamed MK3S and MINI printer profiles. Updated end g-code (MINI). Added new SLA materials and filament profiles. 1.1.10 Updated firmware version. @@ -32,6 +35,7 @@ min_slic3r_version = 2.2.0-alpha0 1.1.1-alpha2 Bumped up config version, so our in house customer will get updated profiles. 1.1.0 Filament aliases, Creality profiles and other goodies for PrusaSlicer 2.2.0-alpha0 min_slic3r_version = 2.1.1-beta0 +1.0.11 Updated firmware version. 1.0.10 Updated firmware version for MK2.5/S and MK3/S. 1.0.9 Updated firmware version for MK2.5/S and MK3/S. 1.0.8 Various changes in FFF profiles, new filaments/materials added. See changelog. @@ -50,6 +54,7 @@ min_slic3r_version = 2.1.0-alpha0 1.0.0-alpha1 Added Prusament ASA profile 1.0.0-alpha0 Filament specific retract for PET and similar copolymers, and for FLEX min_slic3r_version = 1.42.0-alpha6 +0.8.10 Updated firmware version. 0.8.9 Updated firmware version for MK2.5/S and MK3/S. 0.8.8 Updated firmware version for MK2.5/S and MK3/S. 0.8.7 Updated firmware version diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index ecdd57e121..796d578226 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.2.2 +config_version = 1.2.4 # 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% @@ -207,7 +207,7 @@ support_material_contact_distance = 0.1 support_material_interface_contact_loops = 0 support_material_interface_layers = 2 support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% +support_material_interface_speed = 80% support_material_pattern = rectilinear support_material_spacing = 2 support_material_speed = 50 @@ -272,7 +272,7 @@ infill_extrusion_width = 0.25 perimeter_extrusion_width = 0.25 solid_infill_extrusion_width = 0.25 top_infill_extrusion_width = 0.25 -support_material_extrusion_width = 0.2 +support_material_extrusion_width = 0.25 support_material_interface_layers = 0 support_material_interface_spacing = 0.15 support_material_spacing = 1 @@ -336,6 +336,7 @@ top_infill_extrusion_width = 0.8 support_material_extrusion_width = 0.7 support_material_contact_distance = 0.25 support_material_interface_spacing = 0.4 +support_material_interface_speed = 100% support_material_spacing = 2 support_material_xy_spacing = 80% support_material_threshold = 50 @@ -370,18 +371,9 @@ bridge_flow_ratio = 0.95 bridge_speed = 25 [print:*0.6nozzleMINI*] -external_perimeter_extrusion_width = 0.65 -extrusion_width = 0.65 -first_layer_extrusion_width = 0.65 +inherits = *0.6nozzleMK3* infill_extrusion_width = 0.68 -perimeter_extrusion_width = 0.65 solid_infill_extrusion_width = 0.68 -top_infill_extrusion_width = 0.6 -support_material_extrusion_width = 0.55 -bridge_flow_ratio = 0.95 -bridge_speed = 25 -support_material_contact_distance = 0.15 -support_material_xy_spacing = 80% fill_pattern = gyroid fill_density = 15% travel_speed = 150 @@ -391,11 +383,7 @@ bridge_acceleration = 1000 first_layer_acceleration = 1000 default_acceleration = 1250 support_material_speed = 40 -output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode -infill_anchor_max = 15 -support_material_interface_spacing = 0.3 -top_solid_min_thickness = 0.9 -bottom_solid_min_thickness = 0.6 +support_material_interface_speed = 100% [print:*soluble_support*] overhangs = 1 @@ -443,14 +431,12 @@ top_solid_layers = 15 [print:0.05mm ULTRADETAIL] inherits = *0.05mm* -# alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1 infill_extrusion_width = 0.5 # MK3 # [print:0.05mm ULTRADETAIL @MK3] inherits = *0.05mm*; *MK3* -# alias = 0.05mm ULTRADETAIL fill_pattern = gyroid fill_density = 15% compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and ! single_extruder_multi_material @@ -459,7 +445,6 @@ top_infill_extrusion_width = 0.4 # MK2 # [print:0.05mm ULTRADETAIL @0.25 nozzle] inherits = *0.05mm*; *0.25nozzle* -# alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 fill_density = 20% infill_speed = 20 @@ -472,7 +457,6 @@ support_material_speed = 20 # MK3 # [print:0.05mm ULTRADETAIL @0.25 nozzle MK3] inherits = *0.05mm*; *0.25nozzle*; *MK3* -# alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 fill_pattern = grid fill_density = 20% @@ -510,14 +494,12 @@ top_solid_layers = 11 # MK3 # [print:0.07mm ULTRADETAIL @MK3] inherits = *0.07mm*; *MK3* -# alias = 0.07mm ULTRADETAIL fill_pattern = gyroid compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and ! single_extruder_multi_material top_infill_extrusion_width = 0.4 [print:0.07mm ULTRADETAIL @0.25 nozzle MK3] inherits = *0.07mm*; *0.25nozzle*; *MK3* -# alias = 0.07mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1 infill_speed = 30 solid_infill_speed = 30 @@ -543,18 +525,17 @@ top_solid_layers = 9 # MK2 # [print:0.10mm DETAIL] inherits = *0.10mm* -# alias = 0.10mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1 external_perimeter_speed = 40 infill_acceleration = 2000 infill_speed = 60 perimeter_speed = 50 solid_infill_speed = 50 +perimeters = 3 # MK3 # [print:0.10mm DETAIL @MK3] inherits = *0.10mm*; *MK3* -# alias = 0.10mm DETAIL bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 25 @@ -567,11 +548,11 @@ top_infill_extrusion_width = 0.4 top_solid_infill_speed = 40 fill_pattern = gyroid fill_density = 15% +perimeters = 3 # MK2 # [print:0.10mm DETAIL @0.25 nozzle] inherits = *0.10mm*; *0.25nozzle* -# alias = 0.10mm DETAIL bridge_acceleration = 600 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 external_perimeter_speed = 20 @@ -586,7 +567,6 @@ top_solid_infill_speed = 30 # MK3 # [print:0.10mm DETAIL @0.25 nozzle MK3] inherits = *0.10mm*; *0.25nozzleMK3*; *MK3* -# alias = 0.10mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% @@ -625,14 +605,12 @@ top_solid_infill_speed = 70 # MK2 # [print:0.15mm OPTIMAL] inherits = *0.15mm* -# alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2[^\.].*/ and nozzle_diameter[0]==0.4 top_infill_extrusion_width = 0.45 # MK2 # [print:0.15mm OPTIMAL @0.25 nozzle] inherits = *0.15mm*; *0.25nozzle* -# alias = 0.15mm OPTIMAL bridge_acceleration = 600 bridge_flow_ratio = 0.7 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 @@ -648,13 +626,11 @@ top_solid_infill_speed = 30 # MK2 # [print:0.15mm OPTIMAL @0.6 nozzle] inherits = *0.15mm*; *0.6nozzle* -# alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 # MK3 # [print:0.15mm QUALITY @MK3] inherits = *0.15mm*; *MK3* -# alias = 0.15mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 25 @@ -669,7 +645,6 @@ fill_density = 15% [print:0.15mm SPEED @MK3] inherits = *0.15mm*; *MK3* -# alias = 0.15mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 35 @@ -697,7 +672,6 @@ support_material_speed = 45 # MK3 MMU # [print:0.15mm SOLUBLE INTERFACE @MK3] inherits = 0.15mm SOLUBLE FULL @MK3 -# alias = 0.15mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -706,7 +680,6 @@ support_material_with_sheath = 0 # MK2 MMU # [print:0.15mm OPTIMAL SOLUBLE FULL] inherits = *0.15mm*; *soluble_support* -# alias = 0.15mm OPTIMAL SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2[^\.].*/ and nozzle_diameter[0]==0.4 and num_extruders>1 external_perimeter_speed = 25 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder @@ -718,7 +691,6 @@ top_solid_infill_speed = 30 # MK2 MMU # [print:0.15mm OPTIMAL SOLUBLE INTERFACE] inherits = 0.15mm OPTIMAL SOLUBLE FULL -# alias = 0.15mm OPTIMAL SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -728,7 +700,6 @@ support_material_xy_spacing = 80% # MK3 # [print:0.15mm QUALITY @0.25 nozzle MK3] inherits = *0.15mm*; *0.25nozzleMK3*; *MK3* -# alias = 0.15mm QUALITY compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% @@ -736,7 +707,6 @@ fill_density = 20% # MK3 # [print:0.15mm DETAIL @0.6 nozzle MK3] inherits = *0.15mm*; *0.6nozzleMK3*; *MK306* -# alias = 0.15mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1000 @@ -780,7 +750,6 @@ top_solid_infill_speed = 70 # MK3 # [print:0.20mm QUALITY @MK3] inherits = *0.20mm*; *MK3* -# alias = 0.20mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 25 @@ -795,7 +764,6 @@ fill_density = 15% [print:0.20mm SPEED @MK3] inherits = *0.20mm*; *MK3* -# alias = 0.20mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 35 @@ -809,7 +777,6 @@ top_solid_infill_speed = 50 # MK3 MMU # [print:0.20mm SOLUBLE FULL @MK3] inherits = 0.20mm SPEED @MK3; *soluble_support* -# alias = 0.20mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder support_material_extruder = 5 @@ -824,7 +791,6 @@ support_material_speed = 45 # MK3 MMU # [print:0.20mm SOLUBLE INTERFACE @MK3] inherits = 0.20mm SOLUBLE FULL @MK3 -# alias = 0.20mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -838,7 +804,6 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2 # [print:0.20mm NORMAL @0.6 nozzle] inherits = *0.20mm*; *0.6nozzle* -# alias = 0.20mm NORMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 # MK2 MMU # @@ -863,7 +828,6 @@ support_material_xy_spacing = 80% # MK3 # [print:0.20mm DETAIL @0.6 nozzle MK3] inherits = *0.20mm*; *0.6nozzleMK3*; *MK306* -# alias = 0.20mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1000 @@ -908,7 +872,6 @@ top_solid_layers = 4 [print:0.30mm QUALITY @0.6 nozzle MK3] inherits = *0.30mm*; *0.6nozzleMK3*; *MK306* -# alias = 0.30mm QUALITY compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1000 @@ -920,7 +883,6 @@ top_solid_infill_speed = 45 [print:0.30mm SOLUBLE FULL @0.6 nozzle MK3] inherits = 0.30mm QUALITY @0.6 nozzle MK3; *soluble_support* -# alias = 0.30mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 and num_extruders>1 notes = Set your soluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder support_material_extruder = 5 @@ -935,7 +897,6 @@ support_material_xy_spacing = 80% [print:0.30mm SOLUBLE INTERFACE @0.6 nozzle MK3] inherits = 0.30mm SOLUBLE FULL @0.6 nozzle MK3 -# alias = 0.30mm SOLUBLE INTERFACE notes = Set your soluble extruder in Multiple Extruders > Support material/raft interface extruder support_material_extruder = 0 support_material_interface_layers = 3 @@ -943,7 +904,6 @@ support_material_with_sheath = 0 [print:0.30mm DRAFT @MK3] inherits = *0.30mm*; *MK3* -# alias = 0.30mm DRAFT bottom_solid_layers = 3 bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4 @@ -1006,7 +966,6 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2 MMU # [print:0.35mm FAST sol full @0.6 nozzle] inherits = *0.35mm*; *0.6nozzle*; *soluble_support* -# alias = 0.35mm FAST SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_model=="MK2SMM" and nozzle_diameter[0]==0.6 and num_extruders>1 external_perimeter_extrusion_width = 0.6 external_perimeter_speed = 30 @@ -1021,7 +980,6 @@ support_material_extrusion_width = 0.6 # MK2 MMU # [print:0.35mm FAST sol int @0.6 nozzle] inherits = 0.35mm FAST sol full @0.6 nozzle -# alias = 0.35mm FAST SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_layers = 3 support_material_with_sheath = 0 @@ -1030,7 +988,6 @@ support_material_xy_spacing = 150% # MK3 # [print:0.35mm SPEED @0.6 nozzle MK3] inherits = *0.35mm*; *0.6nozzleMK3*; *MK306* -# alias = 0.35mm SPEED compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1000 @@ -1068,7 +1025,6 @@ top_solid_layers = 4 # MK3 # [print:0.40mm DRAFT @0.6 nozzle MK3] inherits = *0.40mm*; *0.6nozzleMK3*; *MK306* -# alias = 0.40mm DRAFT compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_acceleration = 1000 @@ -1095,7 +1051,6 @@ single_extruder_multi_material_priming = 0 # MK2.5 # [print:0.15mm OPTIMAL @MK2.5] inherits = 0.15mm OPTIMAL -# alias = 0.15mm OPTIMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 @@ -1108,7 +1063,6 @@ single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.15mm OPTIMAL SOLUBLE FULL @MK2.5] inherits = 0.15mm OPTIMAL SOLUBLE FULL -# alias = 0.15mm OPTIMAL SOLUBLE FULL support_material_extruder = 5 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -1116,7 +1070,6 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2.5 MMU2 # [print:0.15mm OPTIMAL SOLUBLE INTERFACE @MK2.5] inherits = 0.15mm OPTIMAL SOLUBLE INTERFACE -# alias = 0.15mm OPTIMAL SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -1124,21 +1077,18 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and # MK2.5 # [print:0.20mm 100mms Linear Advance @MK2.5] inherits = 0.20mm 100mms Linear Advance -# alias = 0.20mm 100mms Linear Advance compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 # [print:0.20mm NORMAL @MK2.5] inherits = 0.20mm NORMAL -# alias = 0.20mm NORMAL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.20mm NORMAL SOLUBLE FULL @MK2.5] inherits = 0.20mm NORMAL SOLUBLE FULL -# alias = 0.20mm NORMAL SOLUBLE FULL support_material_extruder = 5 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -1147,7 +1097,6 @@ single_extruder_multi_material_priming = 0 # MK2.5 MMU2 # [print:0.20mm NORMAL SOLUBLE INTERFACE @MK2.5] inherits = 0.20mm NORMAL SOLUBLE INTERFACE -# alias = 0.20mm NORMAL SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_extruder = 5 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and nozzle_diameter[0]==0.4 and num_extruders>1 @@ -1163,7 +1112,6 @@ single_extruder_multi_material_priming = 0 # MK2.5 MMU2 0.6 nozzle # [print:0.35mm SOLUBLE FULL @0.6 nozzle MK2.5] inherits = *0.35mm*; *0.6nozzle*; *soluble_support* -# alias = 0.35mm SOLUBLE FULL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and printer_model!="MK2SMM" and nozzle_diameter[0]==0.6 and num_extruders>1 external_perimeter_extrusion_width = 0.6 external_perimeter_speed = 30 @@ -1179,7 +1127,6 @@ support_material_extrusion_width = 0.6 [print:0.35mm SOLUBLE INTERFACE @0.6 nozzle MK2.5] inherits = 0.35mm SOLUBLE FULL @0.6 nozzle MK2.5 -# alias = 0.35mm SOLUBLE INTERFACE support_material_extruder = 0 support_material_interface_layers = 3 support_material_with_sheath = 0 @@ -1238,7 +1185,6 @@ perimeter_extrusion_width = 1 [print:0.05mm ULTRADETAIL @MINI] inherits = *0.05mm*; *MINI* -# alias = 0.05mm ULTRADETAIL fill_pattern = gyroid fill_density = 15% compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 @@ -1247,10 +1193,10 @@ small_perimeter_speed = 15 perimeter_extrusion_width = 0.4 external_perimeter_extrusion_width = 0.4 support_material_xy_spacing = 60% +support_material_speed = 30 [print:0.07mm ULTRADETAIL @MINI] inherits = *0.07mm*; *MINI* -# alias = 0.07mm ULTRADETAIL fill_pattern = gyroid fill_density = 15% compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 @@ -1262,7 +1208,6 @@ support_material_xy_spacing = 60% [print:0.10mm DETAIL @MINI] inherits = *0.10mm*; *MINI* -# alias = 0.10mm DETAIL bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 perimeter_speed = 40 @@ -1279,7 +1224,6 @@ support_material_xy_spacing = 60% [print:0.15mm QUALITY @MINI] inherits = *0.15mm*; *MINI* -# alias = 0.15mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 perimeter_speed = 40 @@ -1294,7 +1238,6 @@ support_material_xy_spacing = 60% [print:0.15mm SPEED @MINI] inherits = *0.15mm*; *MINI* -# alias = 0.15mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 perimeter_speed = 50 @@ -1307,7 +1250,6 @@ support_material_xy_spacing = 60% [print:0.20mm QUALITY @MINI] inherits = *0.20mm*; *MINI* -# alias = 0.20mm QUALITY bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 perimeter_speed = 40 @@ -1321,7 +1263,6 @@ support_material_xy_spacing = 60% [print:0.20mm SPEED @MINI] inherits = *0.20mm*; *MINI* -# alias = 0.20mm SPEED bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 perimeter_speed = 50 @@ -1334,7 +1275,6 @@ support_material_xy_spacing = 60% [print:0.25mm DRAFT @MINI] inherits = *0.25mm*; *MINI* -# alias = 0.25mm DRAFT bridge_speed = 30 compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4 external_perimeter_speed = 40 @@ -1353,14 +1293,13 @@ support_material_xy_spacing = 60% [print:0.05mm ULTRADETAIL @0.25 nozzle MINI] inherits = *0.05mm*; *0.25nozzle*; *MINI* -# alias = 0.05mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% +support_material_speed = 30 [print:0.07mm ULTRADETAIL @0.25 nozzle MINI] inherits = *0.07mm*; *0.25nozzle*; *MINI* -# alias = 0.07mm ULTRADETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 infill_speed = 30 solid_infill_speed = 30 @@ -1371,14 +1310,12 @@ fill_density = 20% [print:0.10mm DETAIL @0.25 nozzle MINI] inherits = *0.10mm*; *0.25nozzleMINI*; *MINI* -# alias = 0.10mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% [print:0.15mm QUALITY @0.25 nozzle MINI] inherits = *0.15mm*; *0.25nozzleMINI*; *MINI* -# alias = 0.15mm QUALITY compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.25 fill_pattern = grid fill_density = 20% @@ -1387,7 +1324,6 @@ fill_density = 20% [print:0.15mm DETAIL @0.6 nozzle MINI] inherits = *0.15mm*; *0.6nozzleMINI* -# alias = 0.15mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_speed = 70 @@ -1400,7 +1336,6 @@ solid_infill_extrusion_width = 0.65 [print:0.20mm DETAIL @0.6 nozzle MINI] inherits = *0.20mm*; *0.6nozzleMINI* -# alias = 0.20mm DETAIL compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6 external_perimeter_speed = 35 infill_speed = 70 @@ -1703,7 +1638,7 @@ inherits = *PLA* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 49.99 +filament_cost = 80.65 filament_density = 3.9 filament_spool_weight = 236 filament_colour = #804040 @@ -1714,7 +1649,7 @@ inherits = *PLA* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 49.99 +filament_cost = 80.65 filament_density = 3.13 filament_spool_weight = 236 filament_colour = #808080 @@ -1725,7 +1660,7 @@ inherits = *PLA* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.2 -filament_cost = 72.89 +filament_cost = 80.65 filament_density = 3.9 filament_spool_weight = 236 filament_colour = #82603E @@ -1752,7 +1687,7 @@ temperature = 270 [filament:ColorFabb PLA-PHA] inherits = *PLA* filament_vendor = ColorFabb -filament_cost = 52.46 +filament_cost = 54.84 filament_density = 1.24 filament_spool_weight = 236 @@ -1761,7 +1696,7 @@ inherits = *PLA* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.1 -filament_cost = 38.99 +filament_cost = 78.63 filament_density = 1.15 filament_spool_weight = 236 filament_colour = #dfc287 @@ -1776,7 +1711,7 @@ inherits = *PLA* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>0.35 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) extrusion_multiplier = 1.1 -filament_cost = 38.99 +filament_cost = 78.63 filament_density = 1.18 filament_spool_weight = 236 filament_colour = #634d33 @@ -1789,7 +1724,7 @@ filament_retract_lift = 0.2 [filament:ColorFabb XT] inherits = *PET* filament_vendor = ColorFabb -filament_cost = 38.99 +filament_cost = 62.90 filament_density = 1.27 filament_spool_weight = 236 first_layer_bed_temperature = 90 @@ -1800,7 +1735,7 @@ temperature = 270 inherits = *PET* filament_vendor = ColorFabb extrusion_multiplier = 1.05 -filament_cost = 49.99 +filament_cost = 80.65 filament_density = 1.35 filament_spool_weight = 236 filament_colour = #804040 @@ -1853,7 +1788,7 @@ compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MINI inherits = *PET* filament_vendor = Kimya extrusion_multiplier = 1.05 -filament_cost = 150 +filament_cost = 150.02 filament_density = 1.317 filament_colour = #804040 filament_max_volumetric_speed = 6 @@ -1868,7 +1803,7 @@ compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2S [filament:Kimya ABS Carbon] inherits = *ABSC* filament_vendor = Kimya -filament_cost = 140.4 +filament_cost = 140.34 filament_density = 1.032 filament_colour = #804040 filament_max_volumetric_speed = 6 @@ -1901,7 +1836,7 @@ temperature = 270 [filament:Fillamentum PLA] inherits = *PLA* filament_vendor = Fillamentum -filament_cost = 21.99 +filament_cost = 35.48 filament_density = 1.24 filament_spool_weight = 230 @@ -1933,7 +1868,7 @@ filament_type = ASA [filament:Prusament ASA] inherits = *ABS* filament_vendor = Prusa Polymers -filament_cost = 35.28 +filament_cost = 42.69 filament_density = 1.07 filament_spool_weight = 201 fan_always_on = 1 @@ -1956,7 +1891,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI [filament:Prusament PC Blend] inherits = *ABS* filament_vendor = Prusa Polymers -filament_cost = 49.99 +filament_cost = 60.49 filament_density = 1.22 filament_spool_weight = 201 fan_always_on = 0 @@ -1983,7 +1918,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Prusament PC Blend @MK2] inherits = *ABS* filament_vendor = Prusa Polymers -filament_cost = 49.99 +filament_cost = 60.49 filament_density = 1.22 filament_spool_weight = 201 fan_always_on = 0 @@ -2017,7 +1952,7 @@ start_filament_gcode = "M900 K200 ; Filament gcode LA 1.0" [filament:Fillamentum CPE] inherits = *PET* filament_vendor = Fillamentum -filament_cost = 34.99 +filament_cost = 56.45 filament_density = 1.25 filament_spool_weight = 230 filament_type = CPE @@ -2070,7 +2005,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI inherits = *ABSC* filament_vendor = Esun filament_cost = 27.82 -filament_density = 1.04 +filament_density = 1.01 filament_spool_weight = 265 [filament:Hatchbox ABS] @@ -2211,7 +2146,7 @@ bridge_fan_speed = 100 max_fan_speed = 50 min_fan_speed = 50 filament_retract_before_travel = 3 -filament_cost = 34.99 +filament_cost = 84.68 filament_density = 1.22 filament_retract_length = 2 filament_retract_speed = 50 @@ -2241,7 +2176,7 @@ filament_max_volumetric_speed = 8 [filament:PrimaSelect PVA+] inherits = *PLA* filament_vendor = PrimaSelect -filament_cost = 45.01 +filament_cost = 122.1 filament_density = 1.23 cooling = 0 fan_always_on = 0 @@ -2257,7 +2192,7 @@ temperature = 195 [filament:Prusa ABS] inherits = *ABSC* filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.08 filament_spool_weight = 230 compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) @@ -2308,7 +2243,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Prusament ASA @MMU2] inherits = *ABS MMU2* filament_vendor = Prusa Polymers -filament_cost = 35.28 +filament_cost = 42.69 filament_density = 1.07 filament_spool_weight = 201 fan_always_on = 1 @@ -2333,7 +2268,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Prusament PC Blend @MMU2] inherits = *ABS MMU2* filament_vendor = Prusa Polymers -filament_cost = 49.99 +filament_cost = 60.49 filament_density = 1.22 filament_spool_weight = 201 fan_always_on = 0 @@ -2363,13 +2298,14 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Prusa ABS @MMU2] inherits = *ABS MMU2* filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_spool_weight = 230 [filament:Plasty Mladec ABS @MMU2] inherits = *ABS MMU2* filament_vendor = Plasty Mladec filament_density = 1.08 +filament_cost = 27.82 filament_spool_weight = 230 [filament:Prusa HIPS] @@ -2417,7 +2353,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI inherits = *PET* renamed_from = "Prusa PET" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) @@ -2442,7 +2378,7 @@ inherits = *PET* filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 -filament_cost = 29.99 +filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 filament_type = PETG @@ -2452,7 +2388,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!= inherits = *PET06* renamed_from = "Prusa PET 0.6 nozzle"; "Prusa PETG 0.6 nozzle" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 @@ -2461,7 +2397,7 @@ inherits = *PET06* filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 -filament_cost = 29.99 +filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 filament_type = PETG @@ -2471,7 +2407,7 @@ inherits = *PET06* filament_vendor = Plasty Mladec first_layer_temperature = 230 temperature = 240 -filament_cost = 27.92 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 filament_type = PETG @@ -2544,14 +2480,14 @@ filament_spool_weight = 230 inherits = *PET MMU2* renamed_from = "Prusa PET MMU2"; "Prusa PETG MMU2" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_spool_weight = 230 [filament:Prusament PETG @MMU2] inherits = *PET MMU2* filament_type = PETG filament_vendor = Prusa Polymers -filament_cost = 29.99 +filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 @@ -2570,7 +2506,7 @@ filament_spool_weight = 230 inherits = *PET MMU2 06* filament_type = PETG filament_vendor = Prusa Polymers -filament_cost = 29.99 +filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 @@ -2583,7 +2519,7 @@ filament_spool_weight = 230 [filament:Prusa PLA] inherits = *PLA* filament_vendor = Made for Prusa -filament_cost = 20.99 +filament_cost = 27.82 filament_density = 1.24 filament_spool_weight = 230 compatible_printers_condition = nozzle_diameter[0]!=0.8 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) @@ -2597,7 +2533,7 @@ filament_density = 1.24 [filament:Plasty Mladec PLA] inherits = *PLA* filament_vendor = Plasty Mladec -filament_cost = 25.4 +filament_cost = 27.82 filament_density = 1.24 filament_spool_weight = 230 @@ -2618,7 +2554,7 @@ filament_spool_weight = 235 inherits = *PLA* filament_vendor = Hatchbox filament_cost = 25.4 -filament_density = 1.24 +filament_density = 1.27 filament_spool_weight = 245 [filament:Esun PLA] @@ -2650,7 +2586,7 @@ filament_density = 1.24 inherits = *PLA* filament_vendor = Prusa Polymers temperature = 215 -filament_cost = 24.99 +filament_cost = 30.24 filament_density = 1.24 filament_spool_weight = 201 filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" @@ -2662,7 +2598,7 @@ filament_vendor = Prusa Polymers temperature = 215 bed_temperature = 75 first_layer_bed_temperature = 75 -filament_cost = 49.98 +filament_cost = 60.48 filament_density = 1.09 filament_spool_weight = 201 filament_max_volumetric_speed = 8 @@ -2697,20 +2633,20 @@ filament_vendor = Generic [filament:Prusa PLA @MMU2] inherits = *PLA MMU2* filament_vendor = Made for Prusa -filament_cost = 20.99 +filament_cost = 27.82 filament_spool_weight = 230 [filament:Prusament PLA @MMU2] inherits = *PLA MMU2* filament_vendor = Prusa Polymers -filament_cost = 24.99 +filament_cost = 30.24 filament_density = 1.24 filament_spool_weight = 201 [filament:Prusament PVB @MMU2] inherits = *PLA MMU2* filament_vendor = Prusa Polymers -filament_cost = 49.98 +filament_cost = 60.48 filament_density = 1.09 filament_max_volumetric_speed = 8 filament_soluble = 1 @@ -2724,21 +2660,21 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Fillamentum PLA @MMU2] inherits = *PLA MMU2* filament_vendor = Fillamentum -filament_cost = 21.99 +filament_cost = 35.48 filament_density = 1.24 filament_spool_weight = 230 [filament:SemiFlex or Flexfill 98A] inherits = *FLEX* filament_vendor = Generic -filament_cost = 33.99 +filament_cost = 82.26 filament_density = 1.22 filament_max_volumetric_speed = 1.35 [filament:Fillamentum Flexfill 98A] inherits = *FLEX* filament_vendor = Fillamentum -filament_cost = 33.99 +filament_cost = 82.26 filament_density = 1.23 filament_spool_weight = 230 filament_max_volumetric_speed = 1.35 @@ -2799,7 +2735,7 @@ temperature = 250 [filament:Fiberthree F3 PA Pure Pro] inherits = *common* filament_vendor = Fiberthree -filament_cost = 165.98 +filament_cost = 200.84 filament_density = 1.2 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -2829,7 +2765,7 @@ compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI [filament:Fiberthree F3 PA-CF Pro] inherits = *common* filament_vendor = Fiberthree -filament_cost = 171.98 +filament_cost = 208.1 filament_density = 1.25 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -2859,7 +2795,7 @@ compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2S [filament:Fiberthree F3 PA-GF Pro] inherits = Fiberthree F3 PA-CF Pro filament_vendor = Fiberthree -filament_cost = 169.98 +filament_cost = 205.68 filament_density = 1.27 fan_always_on = 1 max_fan_speed = 15 @@ -2889,8 +2825,8 @@ filament_spool_weight = 235 [filament:Verbatim BVOH] inherits = *common* filament_vendor = Verbatim -filament_cost = 79.99 -filament_density = 1.23 +filament_cost = 193.58 +filament_density = 1.14 filament_spool_weight = 235 bed_temperature = 60 bridge_fan_speed = 100 @@ -2944,7 +2880,7 @@ filament_colour = #FFFFD7 filament_cooling_final_speed = 2 filament_cooling_initial_speed = 4 filament_cooling_moves = 2 -filament_cost = 45.01 +filament_cost = 122.1 filament_density = 1.24 filament_diameter = 1.75 filament_load_time = 15 @@ -3016,7 +2952,7 @@ temperature = 270 inherits = *PETMMU1* filament_vendor = ColorFabb filament_type = PETG -filament_cost = 38.99 +filament_cost = 62.90 filament_density = 1.27 filament_spool_weight = 236 first_layer_bed_temperature = 90 @@ -3028,7 +2964,7 @@ inherits = *PETMMU1* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MK2SMM" extrusion_multiplier = 1.05 -filament_cost = 49.99 +filament_cost = 80.65 filament_density = 1.35 filament_spool_weight = 236 filament_colour = #804040 @@ -3062,7 +2998,7 @@ filament_type = EDGE [filament:Fillamentum CPE @MMU1] inherits = *PETMMU1* filament_vendor = Fillamentum -filament_cost = 34.99 +filament_cost = 56.45 filament_density = 1.25 filament_spool_weight = 230 filament_type = CPE @@ -3116,7 +3052,7 @@ filament_density = 1.27 inherits = *PETMMU1* renamed_from = "Prusa PET MMU1"; "Prusa PETG MMU1" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 @@ -3125,7 +3061,7 @@ inherits = *PETMMU1* filament_vendor = Prusa Polymers first_layer_temperature = 240 temperature = 250 -filament_cost = 29.99 +filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 filament_type = PETG @@ -3147,7 +3083,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el [filament:Fiberthree F3 PA Pure Pro @MMU1] inherits = *common* filament_vendor = Fiberthree -filament_cost = 165.98 +filament_cost = 200.84 filament_density = 1.2 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -3172,7 +3108,7 @@ compatible_printers_condition = printer_model=="MK2SMM" [filament:Fiberthree F3 PA-CF Pro @MMU1] inherits = *common* filament_vendor = Fiberthree -filament_cost = 171.98 +filament_cost = 208.1 filament_density = 1.25 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -3197,7 +3133,7 @@ compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MK2S [filament:Fiberthree F3 PA-GF Pro @MMU1] inherits = Fiberthree F3 PA-CF Pro @MMU1 filament_vendor = Fiberthree -filament_cost = 169.98 +filament_cost = 205.68 filament_density = 1.27 fan_always_on = 1 max_fan_speed = 15 @@ -3206,7 +3142,7 @@ min_fan_speed = 15 [filament:SemiFlex or Flexfill 98A @MMU1] inherits = *FLEX* filament_vendor = Generic -filament_cost = 82 +filament_cost = 82.26 filament_density = 1.22 filament_max_volumetric_speed = 1.35 filament_retract_length = nil @@ -3287,7 +3223,7 @@ compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0. [filament:Fiberthree F3 PA Pure Pro @MINI] inherits = *common* filament_vendor = Fiberthree -filament_cost = 165.98 +filament_cost = 200.84 filament_density = 1.2 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -3312,7 +3248,7 @@ compatible_printers_condition = printer_model=="MINI" [filament:Fiberthree F3 PA-CF Pro @MINI] inherits = *common* filament_vendor = Fiberthree -filament_cost = 171.98 +filament_cost = 208.1 filament_density = 1.25 bed_temperature = 70 first_layer_bed_temperature = 75 @@ -3337,7 +3273,7 @@ compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI [filament:Fiberthree F3 PA-GF Pro @MINI] inherits = Fiberthree F3 PA-CF Pro @MINI filament_vendor = Fiberthree -filament_cost = 169.98 +filament_cost = 205.68 filament_density = 1.27 fan_always_on = 1 max_fan_speed = 15 @@ -3363,7 +3299,7 @@ filament_density = 1.037 inherits = Generic ABS; *ABSMINI* filament_vendor = Esun filament_cost = 27.82 -filament_density = 1.08 +filament_density = 1.01 filament_spool_weight = 265 fan_always_on = 0 cooling = 1 @@ -3422,14 +3358,14 @@ first_layer_temperature = 240 temperature = 250 filament_density = 1.27 filament_spool_weight = 201 -filament_cost = 29.99 +filament_cost = 36.29 compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 [filament:Kimya PETG Carbon @MINI] inherits = *PETMINI* filament_vendor = Kimya extrusion_multiplier = 1.05 -filament_cost = 150 +filament_cost = 150.02 filament_density = 1.317 filament_colour = #804040 filament_max_volumetric_speed = 6 @@ -3446,11 +3382,13 @@ first_layer_temperature = 240 temperature = 250 filament_density = 1.27 filament_spool_weight = 201 -filament_cost = 29.99 +filament_cost = 36.29 [filament:Generic PETG @0.6 nozzle MINI] inherits = Generic PETG; *PETMINI06* renamed_from = "Generic PET 0.6 nozzle MINI"; "Generic PETG 0.6 nozzle MINI" +filament_cost = 27.82 +filament_density = 1.27 [filament:Devil Design PETG @0.6 nozzle MINI] inherits = Generic PETG; *PETMINI06* @@ -3466,6 +3404,8 @@ filament_spool_weight = 250 [filament:Plasty Mladec PETG @0.6 nozzle MINI] inherits = Generic PETG; *PETMINI06* filament_vendor = Plasty Mladec +filament_cost = 27.82 +filament_density = 1.27 filament_spool_weight = 230 [filament:Verbatim PETG @0.6 nozzle MINI] @@ -3493,7 +3433,7 @@ slowdown_below_layer_time = 15 disable_fan_first_layers = 4 filament_type = ASA filament_colour = #FFF2EC -filament_cost = 35.28 +filament_cost = 42.69 filament_density = 1.07 filament_spool_weight = 201 compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.8 @@ -3504,7 +3444,7 @@ filament_vendor = Fillamentum first_layer_temperature = 240 temperature = 240 filament_max_volumetric_speed = 1.35 -filament_cost = 33.99 +filament_cost = 82.26 filament_spool_weight = 230 [filament:Generic FLEX @MINI] @@ -3569,7 +3509,7 @@ min_fan_speed = 50 min_print_speed = 15 slowdown_below_layer_time = 10 cooling = 1 -filament_cost = 34.99 +filament_cost = 84.68 [filament:Fillamentum Flexfill 92A @MINI] inherits = *FLEXMINI* @@ -3602,7 +3542,7 @@ first_layer_temperature = 265 first_layer_bed_temperature = 90 temperature = 265 filament_type = CPE -filament_cost = 34.99 +filament_cost = 56.45 filament_density = 1.25 filament_spool_weight = 230 disable_fan_first_layers = 3 @@ -3667,7 +3607,7 @@ filament_density = 1.20 [filament:Prusament PC Blend @MINI] inherits = *ABSMINI* filament_vendor = Prusa Polymers -filament_cost = 49.99 +filament_cost = 60.49 filament_density = 1.22 filament_spool_weight = 201 fan_always_on = 0 @@ -3696,7 +3636,7 @@ compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0. [filament:Prusa ABS @MINI] inherits = *ABSMINI* filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.08 filament_spool_weight = 230 fan_always_on = 0 @@ -3748,7 +3688,7 @@ temperature = 270 inherits = *PETMINI* filament_vendor = ColorFabb filament_type = PETG -filament_cost = 38.99 +filament_cost = 62.90 filament_density = 1.27 filament_spool_weight = 236 first_layer_bed_temperature = 90 @@ -3760,7 +3700,7 @@ inherits = *PETMINI* filament_vendor = ColorFabb compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI" extrusion_multiplier = 1.05 -filament_cost = 49.99 +filament_cost = 80.65 filament_density = 1.35 filament_spool_weight = 236 filament_colour = #804040 @@ -3793,7 +3733,7 @@ filament_type = EDGE inherits = *PETMINI* renamed_from = "Prusa PET MINI"; "Prusa PETG MINI" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 @@ -3802,7 +3742,7 @@ compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0. inherits = *PETMINI06* renamed_from = "Prusa PET 0.6 nozzle MINI"; "Prusa PETG 0.6 nozzle MINI" filament_vendor = Made for Prusa -filament_cost = 22.99 +filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 @@ -5498,21 +5438,21 @@ inherits = Original Prusa i3 MK2S printer_model = MK2.5 remaining_times = 1 machine_max_jerk_e = 4.5 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.25 nozzle] inherits = Original Prusa i3 MK2S 0.25 nozzle printer_model = MK2.5 remaining_times = 1 machine_max_jerk_e = 4.5 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.6 nozzle] inherits = Original Prusa i3 MK2S 0.6 nozzle printer_model = MK2.5 remaining_times = 1 machine_max_jerk_e = 4.5 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5 0.8 nozzle] inherits = Original Prusa i3 MK2S 0.6 nozzle @@ -5524,7 +5464,7 @@ min_layer_height = 0.2 retract_length = 1 remaining_times = 1 machine_max_jerk_e = 4.5 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 default_print_profile = 0.40mm QUALITY @0.8 nozzle default_filament_profile = Prusament PLA @0.8 nozzle @@ -5555,7 +5495,7 @@ machine_min_travel_rate = 0 default_print_profile = 0.15mm OPTIMAL @MK2.5 default_filament_profile = Prusament PLA 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_PRUSA3D\nPRINTER_MODEL_MK2.5\n -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\n; select extruder\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; load to nozzle\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+10, max_print_height)}{endif} F720 ; Move print head up\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors [printer:Original Prusa i3 MK2.5 MMU2 Single 0.8 nozzle] @@ -5601,23 +5541,23 @@ single_extruder_multi_material = 1 # to be defined explicitely. nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n -end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM900 K0 ; reset LA\nM84 ; disable motors\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +end_gcode = ; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\n{if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nG1 X0 Y210 F3000 ; home X axis\nM900 K0 ; reset LA\nM84 ; disable motors\n [printer:Original Prusa i3 MK2.5S] inherits = Original Prusa i3 MK2.5 printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S 0.25 nozzle] inherits = Original Prusa i3 MK2.5 0.25 nozzle printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S 0.6 nozzle] inherits = Original Prusa i3 MK2.5 0.6 nozzle printer_model = MK2.5S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 [printer:Original Prusa i3 MK2.5S 0.8 nozzle] inherits = Original Prusa i3 MK2.5 0.8 nozzle @@ -5650,7 +5590,7 @@ machine_min_travel_rate = 0 default_print_profile = 0.15mm OPTIMAL @MK2.5 default_filament_profile = Prusament PLA 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_PRUSA3D\nPRINTER_MODEL_MK2.5\n -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+10, max_print_height)}{endif} F720 ; Move print head up\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM104 S0 ; turn off temperature\nM900 K0 ; reset LA\nM84 ; disable motors [printer:Original Prusa i3 MK2.5S MMU2S Single 0.8 nozzle] @@ -5661,7 +5601,7 @@ min_layer_height = 0.2 nozzle_diameter = 0.8 printer_variant = 0.8 retract_length = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n default_print_profile = 0.40mm QUALITY @0.8 nozzle default_filament_profile = Prusament PLA @0.8 nozzle @@ -5683,7 +5623,7 @@ nozzle_diameter = 0.25 printer_variant = 0.25 retract_lift = 0.15 default_print_profile = 0.10mm DETAIL 0.25 nozzle -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n [printer:Original Prusa i3 MK2.5S MMU2S] inherits = Original Prusa i3 MK2.5; *mm2s* @@ -5716,8 +5656,8 @@ single_extruder_multi_material = 1 # to be defined explicitely. nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n -end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM900 K0 ; reset LA\nM84 ; disable motors\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +end_gcode = ; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\n{if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM104 S0 ; turn off temperature\nG1 X0 Y210 F3000 ; home X axis\nM900 K0 ; reset LA\nM84 ; disable motors\n [printer:Original Prusa i3 MK2.5S MMU2S 0.6 nozzle] inherits = Original Prusa i3 MK2.5S MMU2S @@ -5745,7 +5685,7 @@ default_print_profile = 0.20mm NORMAL @0.6 nozzle ## printer_variant = 0.8 ## retract_length = 1 ## default_print_profile = 0.40mm QUALITY @0.8 nozzle -## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n ## [printer:Original Prusa i3 MK2.5 MMU2 0.8 nozzle] ## inherits = Original Prusa i3 MK2.5 MMU2 @@ -5755,7 +5695,7 @@ default_print_profile = 0.20mm NORMAL @0.6 nozzle ## printer_variant = 0.8 ## retract_length = 1 ## default_print_profile = 0.40mm QUALITY @0.8 nozzle -## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.1 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n +## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\nG92 E0.0\n # XXXXXXXXXXXXXXXXX # XXX--- MK3 ---XXX @@ -5785,7 +5725,7 @@ remaining_times = 1 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_PRUSA3D\nPRINTER_MODEL_MK3\n retract_lift_below = 209 max_print_height = 210 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} printer_model = MK3 default_print_profile = 0.15mm QUALITY @MK3 @@ -5796,7 +5736,7 @@ max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 retract_lift = 0.15 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3 [printer:Original Prusa i3 MK3 0.6 nozzle] @@ -5805,7 +5745,7 @@ nozzle_diameter = 0.6 max_layer_height = 0.40 min_layer_height = 0.15 printer_variant = 0.6 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 [printer:Original Prusa i3 MK3 0.8 nozzle] @@ -5815,7 +5755,7 @@ max_layer_height = 0.6 min_layer_height = 0.2 printer_variant = 0.8 retract_length = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif} default_print_profile = 0.40mm QUALITY @0.8 nozzle default_filament_profile = Prusament PLA @0.8 nozzle @@ -5823,13 +5763,13 @@ default_filament_profile = Prusament PLA @0.8 nozzle inherits = Original Prusa i3 MK3 renamed_from = "Original Prusa i3 MK3S" printer_model = MK3S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} [printer:Original Prusa i3 MK3S & MK3S+ 0.25 nozzle] inherits = Original Prusa i3 MK3 0.25 nozzle renamed_from = "Original Prusa i3 MK3S 0.25 nozzle" printer_model = MK3S -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E8.0 F700.0 ; intro line\nG1 X100.0 E12.5 F700.0 ; intro line\nG92 E0.0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} [printer:Original Prusa i3 MK3S & MK3S+ 0.6 nozzle] inherits = Original Prusa i3 MK3 0.6 nozzle @@ -5868,7 +5808,7 @@ default_filament_profile = Prusament PLA @MMU2 inherits = *mm2* single_extruder_multi_material = 0 default_filament_profile = Prusament PLA -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+10, max_print_height)}{endif} F720 ; Move print head up\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors [printer:Original Prusa i3 MK3 MMU2 Single 0.6 nozzle] @@ -5878,7 +5818,7 @@ nozzle_diameter = 0.6 max_layer_height = 0.40 min_layer_height = 0.15 printer_variant = 0.6 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 [printer:Original Prusa i3 MK3 MMU2 Single 0.8 nozzle] @@ -5889,7 +5829,7 @@ max_layer_height = 0.6 min_layer_height = 0.2 printer_variant = 0.8 retract_length = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.40mm QUALITY @0.8 nozzle default_filament_profile = Prusament PLA @0.8 nozzle @@ -5901,7 +5841,7 @@ max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 retract_lift = 0.15 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 E8.0 F1000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3 [printer:Original Prusa i3 MK3 MMU2] @@ -5912,15 +5852,15 @@ inherits = *mm2* machine_max_acceleration_e = 8000,8000 nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} -end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +end_gcode = ; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\n{if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nG1 X0 Y210 F3000 ; home X axis\nM84 ; disable motors\n [printer:Original Prusa i3 MK3S & MK3S+ MMU2S Single] inherits = *mm2s* renamed_from = "Original Prusa i3 MK3S MMU2S Single" single_extruder_multi_material = 0 default_filament_profile = Prusament PLA -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+10, max_print_height)}{endif} F720 ; Move print head up\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM702 C\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM84 ; disable motors [printer:Original Prusa i3 MK3S & MK3S+ MMU2S Single 0.6 nozzle] @@ -5931,7 +5871,7 @@ nozzle_diameter = 0.6 max_layer_height = 0.40 min_layer_height = 0.15 printer_variant = 0.6 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 [printer:Original Prusa i3 MK3S & MK3S+ MMU2S Single 0.8 nozzle] @@ -5942,7 +5882,7 @@ max_layer_height = 0.6 min_layer_height = 0.2 printer_variant = 0.8 retract_length = 1 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.40mm QUALITY @0.8 nozzle default_filament_profile = Prusament PLA @0.8 nozzle @@ -5955,7 +5895,7 @@ max_layer_height = 0.15 min_layer_height = 0.05 printer_variant = 0.25 retract_lift = 0.15 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nTx\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nTc\n; purge line\nG1 X55.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F1400.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E value below. Excessive value can damage the printer.\n{if print_settings_id=~/.*@0.25 nozzle MK3.*/}M907 E430 ; set extruder motor current{endif} default_print_profile = 0.10mm DETAIL @0.25 nozzle MK3 [printer:Original Prusa i3 MK3S & MK3S+ MMU2S] @@ -5964,8 +5904,8 @@ renamed_from = "Original Prusa i3 MK3S MMU2S" machine_max_acceleration_e = 8000,8000 nozzle_diameter = 0.4,0.4,0.4,0.4,0.4 extruder_colour = #FF8000;#DB5182;#00FFFF;#FF4F4F;#9FFF9F -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} -end_gcode = {if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors\n +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +end_gcode = ; Lift print head a bit\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\n{if has_wipe_tower}\nG1 E-15.0000 F3000\n{else}\nG1 X0 Y210 F7200\nG1 E2 F5000\nG1 E2 F5500\nG1 E2 F6000\nG1 E-15.0000 F5800\nG1 E-20.0000 F5500\nG1 E10.0000 F3000\nG1 E-10.0000 F3100\nG1 E10.0000 F3150\nG1 E-10.0000 F3250\nG1 E10.0000 F3300\n{endif}\n\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n\n; Unload filament\nM702 C\n\nG4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|SOLUBLE|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nG1 X0 Y210 F3000 ; home X axis\nM84 ; disable motors\n ## 0.6mm nozzle MMU2/S printer profiles @@ -5976,7 +5916,7 @@ nozzle_diameter = 0.6,0.6,0.6,0.6,0.6 max_layer_height = 0.40 min_layer_height = 0.15 printer_variant = 0.6 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 [printer:Original Prusa i3 MK3 MMU2 0.6 nozzle] @@ -5985,7 +5925,7 @@ nozzle_diameter = 0.6,0.6,0.6,0.6,0.6 max_layer_height = 0.40 min_layer_height = 0.15 printer_variant = 0.6 -start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 ## 0.8mm nozzle MMU2/S printer profiles @@ -5998,7 +5938,7 @@ default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 ## max_layer_height = 0.6 ## min_layer_height = 0.2 ## printer_variant = 0.8 -## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E32.0 F1073.0\nG1 X5.0 E32.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 ## default_print_profile = 0.40mm QUALITY @0.8 nozzle ## [printer:Original Prusa i3 MK3S & MK3S+ MMU2S 0.8 nozzle] @@ -6007,7 +5947,7 @@ default_print_profile = 0.30mm QUALITY @0.6 nozzle MK3 ## max_layer_height = 0.6 ## min_layer_height = 0.2 ## printer_variant = 0.8 -## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.2 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 +## start_gcode = M862.3 P \"[printer_model]\" ; printer model check\nM115 U3.9.3 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\n\n; Send the filament type to the MMU2.0 unit.\n; E stands for extruder number, F stands for filament type (0: default; 1:flex; 2: PVA)\nM403 E0 F{"" + ((filament_type[0]=="FLEX") ? 1 : ((filament_type[0]=="PVA") ? 2 : 0))}\nM403 E1 F{"" + ((filament_type[1]=="FLEX") ? 1 : ((filament_type[1]=="PVA") ? 2 : 0))}\nM403 E2 F{"" + ((filament_type[2]=="FLEX") ? 1 : ((filament_type[2]=="PVA") ? 2 : 0))}\nM403 E3 F{"" + ((filament_type[3]=="FLEX") ? 1 : ((filament_type[3]=="PVA") ? 2 : 0))}\nM403 E4 F{"" + ((filament_type[4]=="FLEX") ? 1 : ((filament_type[4]=="PVA") ? 2 : 0))}\n\n{if not has_single_extruder_multi_material_priming}\n;go outside print area\nG1 Y-3.0 F1000.0\nG1 Z0.4 F1000.0\n; select extruder\nT[initial_tool]\n; initial load\nG1 X55.0 E29.0 F1073.0\nG1 X5.0 E29.0 F1800.0\nG1 X55.0 E8.0 F2000.0\nG1 Z0.3 F1000.0\nG92 E0.0\nG1 X240.0 E25.0 F2200.0\nG1 Y-2.0 F1000.0\nG1 X55.0 E25 F1400.0\nG1 Z0.20 F1000.0\nG1 X5.0 E4.0 F1000.0\nG92 E0.0\n{endif}\n\nM221 S{if layer_height<0.075}100{else}95{endif}\nG92 E0.0 ## default_print_profile = 0.40mm QUALITY @0.8 nozzle ## MINI @@ -6053,7 +5993,7 @@ retract_before_wipe = 70% retract_before_travel = 1.5 retract_lift_above = 0 retract_lift_below = 179 -retract_layer_change = 0 +retract_layer_change = 1 silent_mode = 0 remaining_times = 1 start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S170 ; set extruder temp for bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 R170 ; wait for bed leveling temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all without mesh bed level\nG29 ; mesh bed leveling \nM104 S[first_layer_temperature] ; set extruder temp\nG92 E0.0\nG1 Y-2.0 X179 F2400\nG1 Z3 F720\nM109 S[first_layer_temperature] ; wait for extruder temp\n\n; intro line\nG1 X170 F1000\nG1 Z0.2 F720\nG1 X110.0 E8.0 F900\nG1 X40.0 E10.0 F700\nG92 E0.0\n\nM221 S95 ; set flow diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index 40182a14ba..850d69b083 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -32,22 +32,22 @@ varying vec3 delta_box_max; varying float world_normal_z; varying vec3 eye_normal; -vec3 slope_color() -{ - return (world_normal_z > slope.normal_z - EPSILON) ? GREEN : RED; -} - void main() { if (any(lessThan(clipping_planes_dots, ZERO))) discard; - vec3 color = slope.actived ? slope_color() : uniform_color.rgb; + vec3 color = uniform_color.rgb; + float alpha = uniform_color.a; + if (slope.actived && world_normal_z < slope.normal_z - EPSILON) { + color = vec3(0.7, 0.7, 1.0); + alpha = 1.0; + } // if the fragment is outside the print volume -> use darker color color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; #ifdef ENABLE_ENVIRONMENT_MAP if (use_environment_tex) - gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, uniform_color.a); + gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha); else #endif - gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 293cbcd79a..e25399911b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,8 +9,6 @@ add_subdirectory(boost) add_subdirectory(clipper) add_subdirectory(miniz) add_subdirectory(glu-libtess) -add_subdirectory(polypartition) -add_subdirectory(poly2tri) add_subdirectory(qhull) add_subdirectory(Shiny) add_subdirectory(semver) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index a68c5cd0f1..ed2d702728 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -402,7 +402,8 @@ int CLI::run(int argc, char **argv) for (Model &model : m_models) { size_t num_objects = model.objects.size(); for (size_t i = 0; i < num_objects; ++ i) { - model.objects.front()->split(nullptr); + ModelObjectPtrs new_objects; + model.objects.front()->split(&new_objects); model.delete_object(size_t(0)); } } diff --git a/src/admesh/connect.cpp b/src/admesh/connect.cpp index c266c724c4..e5491b1aae 100644 --- a/src/admesh/connect.cpp +++ b/src/admesh/connect.cpp @@ -532,7 +532,7 @@ void stl_remove_unconnected_facets(stl_file *stl) assert(false); } - if (facet_number < -- stl->stats.number_of_facets) { + if (facet_number < int(-- stl->stats.number_of_facets)) { // Removing a face, which was not the last one. // Copy the face and neighborship from the last face to facet_number. stl->facet_start[facet_number] = stl->facet_start[stl->stats.number_of_facets]; diff --git a/src/admesh/normals.cpp b/src/admesh/normals.cpp index 16bb3daab5..3b677641f9 100644 --- a/src/admesh/normals.cpp +++ b/src/admesh/normals.cpp @@ -133,16 +133,16 @@ void stl_fix_normal_directions(stl_file *stl) // Initialize list that keeps track of already fixed facets. std::vector norm_sw(stl->stats.number_of_facets, 0); // Initialize list that keeps track of reversed facets. - std::vector reversed_ids(stl->stats.number_of_facets, 0); + std::vector reversed_ids; + reversed_ids.reserve(stl->stats.number_of_facets); int facet_num = 0; - int reversed_count = 0; // If normal vector is not within tolerance and backwards: // Arbitrarily starts at face 0. If this one is wrong, we're screwed. Thankfully, the chances // of it being wrong randomly are low if most of the triangles are right: if (check_normal_vector(stl, 0, 0)) { reverse_facet(stl, 0); - reversed_ids[reversed_count ++] = 0; + reversed_ids.emplace_back(0); } // Say that we've fixed this facet: @@ -159,13 +159,13 @@ void stl_fix_normal_directions(stl_file *stl) if (stl->neighbors_start[facet_num].neighbor[j] != -1) { if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] == 1) { // trying to modify a facet already marked as fixed, revert all changes made until now and exit (fixes: #716, #574, #413, #269, #262, #259, #230, #228, #206) - for (int id = reversed_count - 1; id >= 0; -- id) + for (int id = int(reversed_ids.size()) - 1; id >= 0; -- id) reverse_facet(stl, reversed_ids[id]); force_exit = true; break; } reverse_facet(stl, stl->neighbors_start[facet_num].neighbor[j]); - reversed_ids[reversed_count ++] = stl->neighbors_start[facet_num].neighbor[j]; + reversed_ids.emplace_back(stl->neighbors_start[facet_num].neighbor[j]); } } // If this edge of the facet is connected: @@ -188,6 +188,7 @@ void stl_fix_normal_directions(stl_file *stl) // Get next facet to fix from top of list. if (head->next != tail) { facet_num = head->next->facet_num; + assert(facet_num < stl->stats.number_of_facets); if (norm_sw[facet_num] != 1) { // If facet is in list mutiple times norm_sw[facet_num] = 1; // Record this one as being fixed. ++ checked; @@ -197,7 +198,7 @@ void stl_fix_normal_directions(stl_file *stl) // pool.destroy(temp); } else { // If we ran out of facets to fix: All of the facets in this part have been fixed. ++ stl->stats.number_of_parts; - if (checked >= stl->stats.number_of_facets) + if (checked >= int(stl->stats.number_of_facets)) // All of the facets have been checked. Bail out. break; // There is another part here. Find it and continue. @@ -207,7 +208,7 @@ void stl_fix_normal_directions(stl_file *stl) facet_num = i; if (check_normal_vector(stl, i, 0)) { reverse_facet(stl, i); - reversed_ids[reversed_count++] = i; + reversed_ids.emplace_back(i); } norm_sw[facet_num] = 1; ++ checked; diff --git a/src/admesh/util.cpp b/src/admesh/util.cpp index 029e44a28e..644fa1834c 100644 --- a/src/admesh/util.cpp +++ b/src/admesh/util.cpp @@ -70,7 +70,7 @@ void stl_translate(stl_file *stl, float x, float y, float z) { stl_vertex new_min(x, y, z); stl_vertex shift = new_min - stl->stats.min; - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j] += shift; stl->stats.min = new_min; @@ -81,7 +81,7 @@ void stl_translate(stl_file *stl, float x, float y, float z) void stl_translate_relative(stl_file *stl, float x, float y, float z) { stl_vertex shift(x, y, z); - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j] += shift; stl->stats.min += shift; @@ -100,7 +100,7 @@ void stl_scale_versor(stl_file *stl, const stl_vertex &versor) if (stl->stats.volume > 0.0) stl->stats.volume *= versor(0) * versor(1) * versor(2); // Scale the mesh. - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j].array() *= s; } @@ -330,10 +330,10 @@ void stl_repair( increment = stl->stats.bounding_diameter / 10000.0; } - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { int last_edges_fixed = 0; for (int i = 0; i < iterations; ++ i) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations); stl_check_facets_nearby(stl, tolerance); @@ -351,7 +351,7 @@ void stl_repair( printf("All facets connected. No nearby check necessary.\n"); if (remove_unconnected_flag || fixall_flag || fill_holes_flag) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Removing unconnected facets...\n"); stl_remove_unconnected_facets(stl); @@ -360,7 +360,7 @@ void stl_repair( } if (fill_holes_flag || fixall_flag) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Filling holes...\n"); stl_fill_holes(stl); diff --git a/src/build-utils/CMakeLists.txt b/src/build-utils/CMakeLists.txt index d47e5b97ff..464fd9c8f4 100644 --- a/src/build-utils/CMakeLists.txt +++ b/src/build-utils/CMakeLists.txt @@ -1,6 +1,11 @@ option(SLIC3R_ENC_CHECK "Verify encoding of source files" 1) +if (IS_CROSS_COMPILE) + # Force disable due to cross compilation. This fact is already printed on cli for users + set(SLIC3R_ENC_CHECK OFF CACHE BOOL "" FORCE) +endif () + if (SLIC3R_ENC_CHECK) add_executable(encoding-check encoding-check.cpp) diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index be4cb4a6a8..3c0057b22b 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -3895,10 +3895,10 @@ double DistanceFromLineSqrd( const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) { //The equation of a line in general form (Ax + By + C = 0) - //given 2 points (x,y) & (x,y) is ... - //(y - y)x + (x - x)y + (y - y)x - (x - x)y = 0 - //A = (y - y); B = (x - x); C = (y - y)x - (x - x)y - //perpendicular distance of point (x,y) = (Ax + By + C)/Sqrt(A + B) + //given 2 points (x¹,y¹) & (x²,y²) is ... + //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 + //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) //see http://en.wikipedia.org/wiki/Perpendicular_distance double A = double(ln1.Y - ln2.Y); double B = double(ln2.X - ln1.X); diff --git a/src/libnest2d/include/libnest2d/nester.hpp b/src/libnest2d/include/libnest2d/nester.hpp index 59477b4f12..20da9b9a1e 100644 --- a/src/libnest2d/include/libnest2d/nester.hpp +++ b/src/libnest2d/include/libnest2d/nester.hpp @@ -836,7 +836,7 @@ public: inline ItemIteratorOnly execute(It from, It to) { auto infl = static_cast(std::ceil(min_obj_distance_/2.0)); - if(infl > 0) std::for_each(from, to, [this, infl](Item& item) { + if(infl > 0) std::for_each(from, to, [infl](Item& item) { item.inflate(infl); }); diff --git a/src/libslic3r/AABBTreeIndirect.hpp b/src/libslic3r/AABBTreeIndirect.hpp index 87d1ee9dba..b11c570f66 100644 --- a/src/libslic3r/AABBTreeIndirect.hpp +++ b/src/libslic3r/AABBTreeIndirect.hpp @@ -653,8 +653,8 @@ inline bool intersect_ray_all_hits( std::vector &hits) { auto ray_intersector = detail::RayIntersectorHits { - vertices, faces, tree, - origin, dir, VectorType(dir.cwiseInverse()) + { vertices, faces, {tree}, + origin, dir, VectorType(dir.cwiseInverse()) } }; if (! tree.empty()) { ray_intersector.hits.reserve(8); diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 7c94033822..fd1ddf0550 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -123,6 +123,9 @@ void AppConfig::set_defaults() if (get("default_action_on_select_preset").empty()) set("default_action_on_select_preset", "none"); // , "transfer", "discard" or "save" + + if (get("color_mapinulation_panel").empty()) + set("color_mapinulation_panel", "0"); } #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN else { @@ -136,6 +139,11 @@ void AppConfig::set_defaults() if (get("seq_top_layer_only").empty()) set("seq_top_layer_only", "1"); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (get("seq_top_gcode_indices").empty()) + set("seq_top_gcode_indices", "1"); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (get("use_perspective_camera").empty()) set("use_perspective_camera", "1"); @@ -266,14 +274,14 @@ void AppConfig::save() else c << "# " << Slic3r::header_gcodeviewer_generated() << std::endl; // Make sure the "no" category is written first. - for (const std::pair &kvp : m_storage[""]) + for (const auto& kvp : m_storage[""]) c << kvp.first << " = " << kvp.second << std::endl; // Write the other categories. - for (const auto category : m_storage) { + for (const auto& category : m_storage) { if (category.first.empty()) continue; c << std::endl << "[" << category.first << "]" << std::endl; - for (const std::pair &kvp : category.second) + for (const auto& kvp : category.second) c << kvp.first << " = " << kvp.second << std::endl; } // Write vendor sections @@ -395,7 +403,7 @@ std::vector AppConfig::get_mouse_device_names() const static constexpr const char *prefix = "mouse_device:"; static const size_t prefix_len = strlen(prefix); std::vector out; - for (const std::pair>& key_value_pair : m_storage) + for (const auto& key_value_pair : m_storage) if (boost::starts_with(key_value_pair.first, prefix) && key_value_pair.first.size() > prefix_len) out.emplace_back(key_value_pair.first.substr(prefix_len)); return out; diff --git a/src/libslic3r/BridgeDetector.cpp b/src/libslic3r/BridgeDetector.cpp index bf8907c3fe..ff33e81d53 100644 --- a/src/libslic3r/BridgeDetector.cpp +++ b/src/libslic3r/BridgeDetector.cpp @@ -207,6 +207,62 @@ std::vector BridgeDetector::bridge_direction_candidates() const return angles; } +/* +static void get_trapezoids(const ExPolygon &expoly, Polygons* polygons) const +{ + ExPolygons expp; + expp.push_back(expoly); + boost::polygon::get_trapezoids(*polygons, expp); +} + +void ExPolygon::get_trapezoids(ExPolygon clone, Polygons* polygons, double angle) const +{ + clone.rotate(PI/2 - angle, Point(0,0)); + clone.get_trapezoids(polygons); + for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon) + polygon->rotate(-(PI/2 - angle), Point(0,0)); +} +*/ + +// This algorithm may return more trapezoids than necessary +// (i.e. it may break a single trapezoid in several because +// other parts of the object have x coordinates in the middle) +static void get_trapezoids2(const ExPolygon &expoly, Polygons* polygons) +{ + Polygons src_polygons = to_polygons(expoly); + // get all points of this ExPolygon + const Points pp = to_points(src_polygons); + + // build our bounding box + BoundingBox bb(pp); + + // get all x coordinates + std::vector xx; + xx.reserve(pp.size()); + for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p) + xx.push_back(p->x()); + std::sort(xx.begin(), xx.end()); + + // find trapezoids by looping from first to next-to-last coordinate + for (std::vector::const_iterator x = xx.begin(); x != xx.end()-1; ++x) { + coord_t next_x = *(x + 1); + if (*x != next_x) + // intersect with rectangle + // append results to return value + polygons_append(*polygons, intersection({ { { *x, bb.min.y() }, { next_x, bb.min.y() }, { next_x, bb.max.y() }, { *x, bb.max.y() } } }, src_polygons)); + } +} + +static void get_trapezoids2(const ExPolygon &expoly, Polygons* polygons, double angle) +{ + ExPolygon clone = expoly; + clone.rotate(PI/2 - angle, Point(0,0)); + get_trapezoids2(clone, polygons); + for (Polygon &polygon : *polygons) + polygon.rotate(-(PI/2 - angle), Point(0,0)); +} + +// Coverage is currently only used by the unit tests. It is extremely slow and unreliable! Polygons BridgeDetector::coverage(double angle) const { if (angle == -1) @@ -228,7 +284,7 @@ Polygons BridgeDetector::coverage(double angle) const for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) { // Compute trapezoids according to a vertical orientation Polygons trapezoids; - expoly.get_trapezoids2(&trapezoids, PI/2.0); + get_trapezoids2(expoly, &trapezoids, PI/2.0); for (const Polygon &trapezoid : trapezoids) { // not nice, we need a more robust non-numeric check size_t n_supported = 0; diff --git a/src/libslic3r/BridgeDetector.hpp b/src/libslic3r/BridgeDetector.hpp index f876f83c76..e97dd45c40 100644 --- a/src/libslic3r/BridgeDetector.hpp +++ b/src/libslic3r/BridgeDetector.hpp @@ -32,6 +32,7 @@ public: BridgeDetector(const ExPolygons &_expolygons, const ExPolygons &_lower_slices, coord_t _extrusion_width); // If bridge_direction_override != 0, then the angle is used instead of auto-detect. bool detect_angle(double bridge_direction_override = 0.); + // Coverage is currently only used by the unit tests. It is extremely slow and unreliable! Polygons coverage(double angle = -1) const; void unsupported_edges(double angle, Polylines* unsupported) const; Polylines unsupported_edges(double angle = -1) const; diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp new file mode 100644 index 0000000000..d5ec0d9285 --- /dev/null +++ b/src/libslic3r/Brim.cpp @@ -0,0 +1,532 @@ +#include "clipper/clipper_z.hpp" + +#include "ClipperUtils.hpp" +#include "EdgeGrid.hpp" +#include "Layer.hpp" +#include "Print.hpp" +#include "ShortestPath.hpp" +#include "libslic3r.h" + +#include +#include +#include +#include + +#ifndef NDEBUG + // #define BRIM_DEBUG_TO_SVG +#endif + +namespace Slic3r { + +static void append_and_translate(ExPolygons &dst, const ExPolygons &src, const PrintInstance &instance) { + size_t dst_idx = dst.size(); + expolygons_append(dst, src); + for (; dst_idx < dst.size(); ++dst_idx) + dst[dst_idx].translate(instance.shift.x(), instance.shift.y()); +} + +static void append_and_translate(Polygons &dst, const Polygons &src, const PrintInstance &instance) { + size_t dst_idx = dst.size(); + polygons_append(dst, src); + for (; dst_idx < dst.size(); ++dst_idx) + dst[dst_idx].translate(instance.shift.x(), instance.shift.y()); +} + +static float max_brim_width(const ConstPrintObjectPtrsAdaptor &objects) +{ + assert(!objects.empty()); + return float(std::accumulate(objects.begin(), objects.end(), 0., + [](double partial_result, const PrintObject *object) { + return std::max(partial_result, object->config().brim_type == btNoBrim ? 0. : object->config().brim_width.value); + })); +} + +static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print) +{ + Polygons islands; + ConstPrintObjectPtrs island_to_object; + for (const PrintObject *object : print.objects()) { + Polygons islands_object; + islands_object.reserve(object->layers().front()->lslices.size()); + for (const ExPolygon &ex_poly : object->layers().front()->lslices) + islands_object.emplace_back(ex_poly.contour); + + islands.reserve(islands.size() + object->instances().size() * islands_object.size()); + for (const PrintInstance &instance : object->instances()) + for (Polygon &poly : islands_object) { + islands.emplace_back(poly); + islands.back().translate(instance.shift); + island_to_object.emplace_back(object); + } + } + assert(islands.size() == island_to_object.size()); + + ClipperLib_Z::Paths islands_clip; + islands_clip.reserve(islands.size()); + for (const Polygon &poly : islands) { + islands_clip.emplace_back(); + ClipperLib_Z::Path &island_clip = islands_clip.back(); + island_clip.reserve(poly.points.size()); + int island_idx = int(&poly - &islands.front()); + // The Z coordinate carries index of the island used to get the pointer to the object. + for (const Point &pt : poly.points) + island_clip.emplace_back(pt.x(), pt.y(), island_idx + 1); + } + + // Init Clipper + ClipperLib_Z::Clipper clipper; + // Assign the maximum Z from four points. This values is valid index of the island + clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot, + const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) { + pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z)); + }); + // Add islands + clipper.AddPaths(islands_clip, ClipperLib_Z::ptSubject, true); + // Execute union operation to construct polytree + ClipperLib_Z::PolyTree islands_polytree; + clipper.Execute(ClipperLib_Z::ctUnion, islands_polytree, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd); + + std::unordered_set processed_objects_idx; + ConstPrintObjectPtrs top_level_objects_with_brim; + for (int i = 0; i < islands_polytree.ChildCount(); ++i) { + for (const ClipperLib_Z::IntPoint &point : islands_polytree.Childs[i]->Contour) { + if (point.Z != 0 && processed_objects_idx.find(island_to_object[point.Z - 1]->id().id) == processed_objects_idx.end()) { + top_level_objects_with_brim.emplace_back(island_to_object[point.Z - 1]); + processed_objects_idx.insert(island_to_object[point.Z - 1]->id().id); + } + } + } + return top_level_objects_with_brim; +} + +static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_level_objects_with_brim) +{ + Polygons islands; + for (const PrintObject *object : top_level_objects_with_brim) { + //FIXME how about the brim type? + float brim_offset = float(scale_(object->config().brim_offset.value)); + Polygons islands_object; + for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + Polygons contour_offset = offset(ex_poly.contour, brim_offset); + for (Polygon &poly : contour_offset) + poly.douglas_peucker(SCALED_RESOLUTION); + + polygons_append(islands_object, std::move(contour_offset)); + } + + for (const PrintInstance &instance : object->instances()) + append_and_translate(islands, islands_object, instance); + } + return islands; +} + +static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset) +{ + std::unordered_set top_level_objects_idx; + top_level_objects_idx.reserve(top_level_objects_with_brim.size()); + for (const PrintObject *object : top_level_objects_with_brim) + top_level_objects_idx.insert(object->id().id); + + ExPolygons brim_area; + Polygons no_brim_area; + for (const PrintObject *object : print.objects()) { + const BrimType brim_type = object->config().brim_type.value; + const float brim_offset = scale_(object->config().brim_offset.value); + const float brim_width = scale_(object->config().brim_width.value); + const bool is_top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); + + ExPolygons brim_area_object; + Polygons no_brim_area_object; + for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) && is_top_outer_brim) + append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset), offset_ex(ex_poly.contour, brim_offset))); + + if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim) + append(no_brim_area_object, offset(ex_poly.holes, -no_brim_offset)); + + if (brim_type != BrimType::btNoBrim) + append(no_brim_area_object, offset(ex_poly.contour, brim_offset)); + + no_brim_area_object.emplace_back(ex_poly.contour); + } + + for (const PrintInstance &instance : object->instances()) { + append_and_translate(brim_area, brim_area_object, instance); + append_and_translate(no_brim_area, no_brim_area_object, instance); + } + } + + return diff_ex(to_polygons(std::move(brim_area)), no_brim_area); +} + +static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset) +{ + std::unordered_set top_level_objects_idx; + top_level_objects_idx.reserve(top_level_objects_with_brim.size()); + for (const PrintObject *object : top_level_objects_with_brim) + top_level_objects_idx.insert(object->id().id); + + ExPolygons brim_area; + ExPolygons no_brim_area; + Polygons holes; + for (const PrintObject *object : print.objects()) { + const BrimType brim_type = object->config().brim_type.value; + const float brim_offset = scale_(object->config().brim_offset.value); + const float brim_width = scale_(object->config().brim_width.value); + const bool top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); + + ExPolygons brim_area_object; + ExPolygons no_brim_area_object; + Polygons holes_object; + for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) { + if (top_outer_brim) + no_brim_area_object.emplace_back(ex_poly); + else + append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset), offset_ex(ex_poly.contour, brim_offset))); + } + + if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner) + append(brim_area_object, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset))); + + if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim) + append(no_brim_area_object, offset_ex(ex_poly.contour, no_brim_offset)); + + if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim) + append(no_brim_area_object, offset_ex(ex_poly.holes, -no_brim_offset)); + + append(holes_object, ex_poly.holes); + } + append(no_brim_area_object, offset_ex(object->layers().front()->lslices, brim_offset)); + + for (const PrintInstance &instance : object->instances()) { + append_and_translate(brim_area, brim_area_object, instance); + append_and_translate(no_brim_area, no_brim_area_object, instance); + append_and_translate(holes, holes_object, instance); + } + } + + return diff_ex(intersection_ex(to_polygons(std::move(brim_area)), holes), no_brim_area); +} + +// Flip orientation of open polylines to minimize travel distance. +static void optimize_polylines_by_reversing(Polylines *polylines) +{ + for (size_t poly_idx = 1; poly_idx < polylines->size(); ++poly_idx) { + const Polyline &prev = (*polylines)[poly_idx - 1]; + Polyline & next = (*polylines)[poly_idx]; + + if (!next.is_closed()) { + double dist_to_start = (next.first_point() - prev.last_point()).cast().norm(); + double dist_to_end = (next.last_point() - prev.last_point()).cast().norm(); + + if (dist_to_end < dist_to_start) + next.reverse(); + } + } +} + +static Polylines connect_brim_lines(Polylines &&polylines, const Polygons &brim_area, float max_connection_length) +{ + if (polylines.empty()) + return Polylines(); + + BoundingBox bbox = get_extents(polylines); + bbox.merge(get_extents(brim_area)); + + EdgeGrid::Grid grid(bbox.inflated(SCALED_EPSILON)); + grid.create(brim_area, polylines, coord_t(scale_(10.))); + + struct Visitor + { + explicit Visitor(const EdgeGrid::Grid &grid) : grid(grid) {} + + bool operator()(coord_t iy, coord_t ix) + { + // Called with a row and colum of the grid cell, which is intersected by a line. + auto cell_data_range = grid.cell_data_range(iy, ix); + this->intersect = false; + for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++it_contour_and_segment) { + // End points of the line segment and their vector. + auto segment = grid.segment(*it_contour_and_segment); + if (Geometry::segments_intersect(segment.first, segment.second, brim_line.a, brim_line.b)) { + this->intersect = true; + return false; + } + } + // Continue traversing the grid along the edge. + return true; + } + + const EdgeGrid::Grid &grid; + Line brim_line; + bool intersect; + + } visitor(grid); + + // Connect successive polylines if they are open, their ends are closer than max_connection_length. + // Remove empty polylines. + { + // Skip initial empty lines. + size_t poly_idx = 0; + for (; poly_idx < polylines.size() && polylines[poly_idx].empty(); ++ poly_idx) ; + size_t end = ++ poly_idx; + double max_connection_length2 = Slic3r::sqr(max_connection_length); + for (; poly_idx < polylines.size(); ++poly_idx) { + Polyline &next = polylines[poly_idx]; + if (! next.empty()) { + Polyline &prev = polylines[end - 1]; + bool connect = false; + if (! prev.is_closed() && ! next.is_closed()) { + double dist2 = (prev.last_point() - next.first_point()).cast().squaredNorm(); + if (dist2 <= max_connection_length2) { + visitor.brim_line.a = prev.last_point(); + visitor.brim_line.b = next.first_point(); + // Shrink the connection line to avoid collisions with the brim centerlines. + visitor.brim_line.extend(-SCALED_EPSILON); + grid.visit_cells_intersecting_line(visitor.brim_line.a, visitor.brim_line.b, visitor); + connect = ! visitor.intersect; + } + } + if (connect) { + append(prev.points, std::move(next.points)); + } else { + if (end < poly_idx) + polylines[end] = std::move(next); + ++ end; + } + } + } + if (end < polylines.size()) + polylines.erase(polylines.begin() + end, polylines.end()); + } + + return std::move(polylines); +} + +static void make_inner_brim(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, ExtrusionEntityCollection &brim) +{ + Flow flow = print.brim_flow(); + ExPolygons islands_ex = inner_brim_area(print, top_level_objects_with_brim, flow.scaled_spacing()); + Polygons loops; + islands_ex = offset_ex(islands_ex, -0.5f * float(flow.scaled_spacing()), jtSquare); + for (size_t i = 0; !islands_ex.empty(); ++i) { + for (ExPolygon &poly_ex : islands_ex) + poly_ex.douglas_peucker(SCALED_RESOLUTION); + polygons_append(loops, to_polygons(islands_ex)); + islands_ex = offset_ex(islands_ex, -float(flow.scaled_spacing()), jtSquare); + } + + loops = union_pt_chained_outside_in(loops, false); + std::reverse(loops.begin(), loops.end()); + extrusion_entities_append_loops(brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), + float(flow.width), float(print.skirt_first_layer_height())); +} + +// Produce brim lines around those objects, that have the brim enabled. +// Collect islands_area to be merged into the final 1st layer convex hull. +ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area) +{ + Flow flow = print.brim_flow(); + ConstPrintObjectPtrs top_level_objects_with_brim = get_top_level_objects_with_brim(print); + Polygons islands = top_level_outer_brim_islands(top_level_objects_with_brim); + ExPolygons islands_area_ex = top_level_outer_brim_area(print, top_level_objects_with_brim, flow.scaled_spacing()); + islands_area = to_polygons(islands_area_ex); + + Polygons loops; + size_t num_loops = size_t(floor(max_brim_width(print.objects()) / flow.spacing())); + for (size_t i = 0; i < num_loops; ++i) { + try_cancel(); + islands = offset(islands, float(flow.scaled_spacing()), jtSquare); + for (Polygon &poly : islands) + poly.douglas_peucker(SCALED_RESOLUTION); + polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing()))); + } + loops = union_pt_chained_outside_in(loops, false); + + std::vector loops_pl_by_levels; + { + Polylines loops_pl = to_polylines(loops); + loops_pl_by_levels.assign(loops_pl.size(), Polylines()); + tbb::parallel_for(tbb::blocked_range(0, loops_pl.size()), + [&loops_pl_by_levels, &loops_pl, &islands_area](const tbb::blocked_range &range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + loops_pl_by_levels[i] = chain_polylines(intersection_pl({ std::move(loops_pl[i]) }, islands_area)); + } + }); + } + + // output + ExtrusionEntityCollection brim; + + // Reduce down to the ordered list of polylines. + Polylines all_loops; + for (Polylines &polylines : loops_pl_by_levels) + append(all_loops, std::move(polylines)); + loops_pl_by_levels.clear(); + + // Flip orientation of open polylines to minimize travel distance. + optimize_polylines_by_reversing(&all_loops); + +#ifdef BRIM_DEBUG_TO_SVG + static int irun = 0; + ++ irun; + + { + SVG svg(debug_out_path("brim-%d.svg", irun).c_str(), get_extents(all_loops)); + svg.draw(union_ex(islands), "blue"); + svg.draw(islands_area_ex, "green"); + svg.draw(all_loops, "black", coord_t(scale_(0.1))); + } +#endif // BRIM_DEBUG_TO_SVG + + all_loops = connect_brim_lines(std::move(all_loops), offset(islands_area_ex, float(SCALED_EPSILON)), flow.scaled_spacing() * 2.f); + +#ifdef BRIM_DEBUG_TO_SVG + { + SVG svg(debug_out_path("brim-connected-%d.svg", irun).c_str(), get_extents(all_loops)); + svg.draw(union_ex(islands), "blue"); + svg.draw(islands_area_ex, "green"); + svg.draw(all_loops, "black", coord_t(scale_(0.1))); + } +#endif // BRIM_DEBUG_TO_SVG + + const bool could_brim_intersects_skirt = std::any_of(print.objects().begin(), print.objects().end(), [&print](PrintObject *object) { + const BrimType &bt = object->config().brim_type; + return (bt == btOuterOnly || bt == btOuterAndInner) && print.config().skirt_distance.value < object->config().brim_width; + }); + // If there is a possibility that brim intersects skirt, go through loops and split those extrusions + // The result is either the original Polygon or a list of Polylines + if (! print.skirt().empty() && could_brim_intersects_skirt) + { + // Find the bounding polygons of the skirt + const Polygons skirt_inners = offset(dynamic_cast(print.skirt().entities.back())->polygon(), + -float(scale_(print.skirt_flow().spacing()))/2.f, + ClipperLib::jtRound, + float(scale_(0.1))); + const Polygons skirt_outers = offset(dynamic_cast(print.skirt().entities.front())->polygon(), + float(scale_(print.skirt_flow().spacing()))/2.f, + ClipperLib::jtRound, + float(scale_(0.1))); + + // First calculate the trimming region. + ClipperLib_Z::Paths trimming; + { + ClipperLib_Z::Paths input_subject; + ClipperLib_Z::Paths input_clip; + for (const Polygon &poly : skirt_outers) { + input_subject.emplace_back(); + ClipperLib_Z::Path &out = input_subject.back(); + out.reserve(poly.points.size()); + for (const Point &pt : poly.points) + out.emplace_back(pt.x(), pt.y(), 0); + } + for (const Polygon &poly : skirt_inners) { + input_clip.emplace_back(); + ClipperLib_Z::Path &out = input_clip.back(); + out.reserve(poly.points.size()); + for (const Point &pt : poly.points) + out.emplace_back(pt.x(), pt.y(), 0); + } + // init Clipper + ClipperLib_Z::Clipper clipper; + // add polygons + clipper.AddPaths(input_subject, ClipperLib_Z::ptSubject, true); + clipper.AddPaths(input_clip, ClipperLib_Z::ptClip, true); + // perform operation + clipper.Execute(ClipperLib_Z::ctDifference, trimming, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd); + } + + // Second, trim the extrusion loops with the trimming regions. + ClipperLib_Z::Paths loops_trimmed; + { + // Produce ClipperLib_Z::Paths from polylines (not necessarily closed). + ClipperLib_Z::Paths input_clip; + for (const Polyline &loop_pl : all_loops) { + input_clip.emplace_back(); + ClipperLib_Z::Path& out = input_clip.back(); + out.reserve(loop_pl.points.size()); + int64_t loop_idx = &loop_pl - &all_loops.front(); + for (const Point& pt : loop_pl.points) + // The Z coordinate carries index of the source loop. + out.emplace_back(pt.x(), pt.y(), loop_idx + 1); + } + // init Clipper + ClipperLib_Z::Clipper clipper; + clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot, const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) { + // Assign a valid input loop identifier. Such an identifier is strictly positive, the next line is safe even in case one side of a segment + // hat the Z coordinate not set to the contour coordinate. + pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z)); + }); + // add polygons + clipper.AddPaths(input_clip, ClipperLib_Z::ptSubject, false); + clipper.AddPaths(trimming, ClipperLib_Z::ptClip, true); + // perform operation + ClipperLib_Z::PolyTree loops_trimmed_tree; + clipper.Execute(ClipperLib_Z::ctDifference, loops_trimmed_tree, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd); + ClipperLib_Z::PolyTreeToPaths(loops_trimmed_tree, loops_trimmed); + } + + // Third, produce the extrusions, sorted by the source loop indices. + { + std::vector> loops_trimmed_order; + loops_trimmed_order.reserve(loops_trimmed.size()); + for (const ClipperLib_Z::Path &path : loops_trimmed) { + size_t input_idx = 0; + for (const ClipperLib_Z::IntPoint &pt : path) + if (pt.Z > 0) { + input_idx = (size_t)pt.Z; + break; + } + assert(input_idx != 0); + loops_trimmed_order.emplace_back(&path, input_idx); + } + std::stable_sort(loops_trimmed_order.begin(), loops_trimmed_order.end(), + [](const std::pair &l, const std::pair &r) { + return l.second < r.second; + }); + + Point last_pt(0, 0); + for (size_t i = 0; i < loops_trimmed_order.size();) { + // Find all pieces that the initial loop was split into. + size_t j = i + 1; + for (; j < loops_trimmed_order.size() && loops_trimmed_order[i].second == loops_trimmed_order[j].second; ++ j) ; + const ClipperLib_Z::Path &first_path = *loops_trimmed_order[i].first; + if (i + 1 == j && first_path.size() > 3 && first_path.front().X == first_path.back().X && first_path.front().Y == first_path.back().Y) { + auto *loop = new ExtrusionLoop(); + brim.entities.emplace_back(loop); + loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(print.skirt_first_layer_height())); + Points &points = loop->paths.front().polyline.points; + points.reserve(first_path.size()); + for (const ClipperLib_Z::IntPoint &pt : first_path) + points.emplace_back(coord_t(pt.X), coord_t(pt.Y)); + i = j; + } else { + //FIXME The path chaining here may not be optimal. + ExtrusionEntityCollection this_loop_trimmed; + this_loop_trimmed.entities.reserve(j - i); + for (; i < j; ++ i) { + this_loop_trimmed.entities.emplace_back(new ExtrusionPath(erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(print.skirt_first_layer_height()))); + const ClipperLib_Z::Path &path = *loops_trimmed_order[i].first; + Points &points = static_cast(this_loop_trimmed.entities.back())->polyline.points; + points.reserve(path.size()); + for (const ClipperLib_Z::IntPoint &pt : path) + points.emplace_back(coord_t(pt.X), coord_t(pt.Y)); + } + chain_and_reorder_extrusion_entities(this_loop_trimmed.entities, &last_pt); + brim.entities.reserve(brim.entities.size() + this_loop_trimmed.entities.size()); + append(brim.entities, std::move(this_loop_trimmed.entities)); + this_loop_trimmed.entities.clear(); + } + last_pt = brim.last_point(); + } + } + } else { + extrusion_entities_append_loops_and_paths(brim.entities, std::move(all_loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(print.skirt_first_layer_height())); + } + + make_inner_brim(print, top_level_objects_with_brim, brim); + return brim; +} + +} // namespace Slic3r diff --git a/src/libslic3r/Brim.hpp b/src/libslic3r/Brim.hpp new file mode 100644 index 0000000000..18bff2960c --- /dev/null +++ b/src/libslic3r/Brim.hpp @@ -0,0 +1,14 @@ +#ifndef slic3r_Brim_hpp_ +#define slic3r_Brim_hpp_ + +namespace Slic3r { + +class Print; + +// Produce brim lines around those objects, that have the brim enabled. +// Collect islands_area to be merged into the final 1st layer convex hull. +ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area); + +} // Slic3r + +#endif // slic3r_Brim_hpp_ diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 7b7067d9f2..1267e216c1 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -21,6 +21,8 @@ add_library(libslic3r STATIC BoundingBox.hpp BridgeDetector.cpp BridgeDetector.hpp + Brim.cpp + Brim.hpp ClipperUtils.cpp ClipperUtils.hpp Config.cpp @@ -307,8 +309,6 @@ target_link_libraries(libslic3r nowide ${EXPAT_LIBRARIES} glu-libtess - polypartition - poly2tri qhull semver TBB::tbb diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index ea6c78f7ce..6755a63781 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -616,11 +616,11 @@ void ConfigBase::load(const boost::property_tree::ptree &tree) } // Load the config keys from the tail of a G-code file. -void ConfigBase::load_from_gcode_file(const std::string &file) +void ConfigBase::load_from_gcode_file(const std::string& file, bool check_header) { // Read a 64k block from the end of the G-code. boost::nowide::ifstream ifs(file); - { + if (check_header) { const char slic3r_gcode_header[] = "; generated by Slic3r "; const char prusaslicer_gcode_header[] = "; generated by PrusaSlicer "; std::string firstline; diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 12c19eaefe..218e8cd0cf 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1344,7 +1344,7 @@ public: static bool has(T value) { - for (const std::pair &kvp : ConfigOptionEnum::get_enum_values()) + for (const auto &kvp : ConfigOptionEnum::get_enum_values()) if (kvp.second == value) return true; return false; @@ -1358,11 +1358,11 @@ public: // Initialize the map. const t_config_enum_values &enum_keys_map = ConfigOptionEnum::get_enum_values(); int cnt = 0; - for (const std::pair &kvp : enum_keys_map) + for (const auto& kvp : enum_keys_map) cnt = std::max(cnt, kvp.second); cnt += 1; names.assign(cnt, ""); - for (const std::pair &kvp : enum_keys_map) + for (const auto& kvp : enum_keys_map) names[kvp.second] = kvp.first; } return names; @@ -1695,6 +1695,7 @@ public: // Static configuration definition. Any value stored into this ConfigBase shall have its definition here. virtual const ConfigDef* def() const = 0; // Find ando/or create a ConfigOption instance for a given name. + using ConfigOptionResolver::optptr; virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0; // Collect names of all configuration values maintained by this configuration store. virtual t_config_option_keys keys() const = 0; @@ -1790,7 +1791,7 @@ public: void setenv_() const; void load(const std::string &file); void load_from_ini(const std::string &file); - void load_from_gcode_file(const std::string &file); + void load_from_gcode_file(const std::string& file, bool check_header = true); // Returns number of key/value pairs extracted. size_t load_from_gcode_string(const char* str); void load(const boost::property_tree::ptree &tree); @@ -1946,8 +1947,9 @@ public: int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option(opt_key)->get_at(idx); } int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast(this->option(opt_key))->get_at(idx); } + // In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*. template - ENUM opt_enum(const t_config_option_key &opt_key) const { return (ENUM)dynamic_cast(this->option(opt_key))->value; } + ENUM opt_enum(const t_config_option_key &opt_key) const { return this->option>(opt_key)->value; } bool opt_bool(const t_config_option_key &opt_key) const { return this->option(opt_key)->value != 0; } bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option(opt_key)->get_at(idx) != 0; } diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index 7bab590f7f..b9e9ec3dd8 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -25,90 +25,89 @@ namespace Slic3r { -EdgeGrid::Grid::Grid() : - m_rows(0), m_cols(0) -{ -} - -EdgeGrid::Grid::~Grid() -{ - m_contours.clear(); - m_cell_data.clear(); - m_cells.clear(); -} - void EdgeGrid::Grid::create(const Polygons &polygons, coord_t resolution) { - // Count the contours. - size_t ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j].points.empty()) - ++ ncontours; - // Collect the contours. - m_contours.assign(ncontours, nullptr); - ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j].points.empty()) - m_contours[ncontours ++] = &polygons[j].points; + m_contours.clear(); + m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Polygon &p) { return ! p.empty(); })); + for (const Polygon &polygon : polygons) + if (! polygon.empty()) + m_contours.emplace_back(polygon.points, false); create_from_m_contours(resolution); } void EdgeGrid::Grid::create(const std::vector &polygons, coord_t resolution) { - // Count the contours. - size_t ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j]->points.empty()) - ++ ncontours; - // Collect the contours. - m_contours.assign(ncontours, nullptr); - ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j]->points.empty()) - m_contours[ncontours ++] = &polygons[j]->points; + m_contours.clear(); + m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Polygon *p) { return ! p->empty(); })); + for (const Polygon *polygon : polygons) + if (! polygon->empty()) + m_contours.emplace_back(polygon->points, false); create_from_m_contours(resolution); } -void EdgeGrid::Grid::create(const std::vector &polygons, coord_t resolution) +void EdgeGrid::Grid::create(const std::vector &polygons, coord_t resolution, bool open_polylines) { - // Count the contours. - size_t ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j].empty()) - ++ ncontours; - // Collect the contours. - m_contours.assign(ncontours, nullptr); - ncontours = 0; - for (size_t j = 0; j < polygons.size(); ++ j) - if (! polygons[j].empty()) - m_contours[ncontours ++] = &polygons[j]; + m_contours.clear(); + m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Points &p) { return p.size() > 1; })); + for (const Points &points : polygons) + if (points.size() > 1) { + const Point *begin = points.data(); + const Point *end = points.data() + points.size(); + bool open = open_polylines; + if (open_polylines) { + if (*begin == end[-1]) { + open = false; + -- end; + } + } else + assert(*begin != end[-1]); + m_contours.emplace_back(begin, end, open); + } + + create_from_m_contours(resolution); +} + +void EdgeGrid::Grid::create(const Polygons &polygons, const Polylines &polylines, coord_t resolution) +{ + // Collect the contours. + m_contours.clear(); + m_contours.reserve( + std::count_if(polygons.begin(), polygons.end(), [](const Polygon &p) { return p.size() > 1; }) + + std::count_if(polylines.begin(), polylines.end(), [](const Polyline &p) { return p.size() > 1; })); + + for (const Polyline &polyline : polylines) + if (polyline.size() > 1) { + const Point *begin = polyline.points.data(); + const Point *end = polyline.points.data() + polyline.size(); + bool open = true; + if (*begin == end[-1]) { + open = false; + -- end; + } + m_contours.emplace_back(begin, end, open); + } + + for (const Polygon &polygon : polygons) + if (polygon.size() > 1) + m_contours.emplace_back(polygon.points, false); create_from_m_contours(resolution); } void EdgeGrid::Grid::create(const ExPolygon &expoly, coord_t resolution) { - // Count the contours. - size_t ncontours = 0; - if (! expoly.contour.points.empty()) - ++ ncontours; - for (size_t j = 0; j < expoly.holes.size(); ++ j) - if (! expoly.holes[j].points.empty()) - ++ ncontours; - - // Collect the contours. - m_contours.assign(ncontours, nullptr); - ncontours = 0; - if (! expoly.contour.points.empty()) - m_contours[ncontours++] = &expoly.contour.points; - for (size_t j = 0; j < expoly.holes.size(); ++ j) - if (! expoly.holes[j].points.empty()) - m_contours[ncontours++] = &expoly.holes[j].points; + m_contours.clear(); + m_contours.reserve((expoly.contour.empty() ? 0 : 1) + std::count_if(expoly.holes.begin(), expoly.holes.end(), [](const Polygon &p) { return ! p.empty(); })); + if (! expoly.contour.empty()) + m_contours.emplace_back(expoly.contour.points, false); + for (const Polygon &hole : expoly.holes) + if (! hole.empty()) + m_contours.emplace_back(hole.points, false); create_from_m_contours(resolution); } @@ -117,25 +116,21 @@ void EdgeGrid::Grid::create(const ExPolygons &expolygons, coord_t resolution) { // Count the contours. size_t ncontours = 0; - for (size_t i = 0; i < expolygons.size(); ++ i) { - const ExPolygon &expoly = expolygons[i]; - if (! expoly.contour.points.empty()) + for (const ExPolygon &expoly : expolygons) { + if (! expoly.contour.empty()) ++ ncontours; - for (size_t j = 0; j < expoly.holes.size(); ++ j) - if (! expoly.holes[j].points.empty()) - ++ ncontours; + ncontours += std::count_if(expoly.holes.begin(), expoly.holes.end(), [](const Polygon &p) { return ! p.empty(); }); } // Collect the contours. - m_contours.assign(ncontours, nullptr); - ncontours = 0; - for (size_t i = 0; i < expolygons.size(); ++ i) { - const ExPolygon &expoly = expolygons[i]; - if (! expoly.contour.points.empty()) - m_contours[ncontours++] = &expoly.contour.points; - for (size_t j = 0; j < expoly.holes.size(); ++ j) - if (! expoly.holes[j].points.empty()) - m_contours[ncontours++] = &expoly.holes[j].points; + m_contours.clear(); + m_contours.reserve(ncontours); + for (const ExPolygon &expoly : expolygons) { + if (! expoly.contour.empty()) + m_contours.emplace_back(expoly.contour.points, false); + for (const Polygon &hole : expoly.holes) + if (! hole.empty()) + m_contours.emplace_back(hole.points, false); } create_from_m_contours(resolution); @@ -151,11 +146,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) { assert(resolution > 0); // 1) Measure the bounding box. - for (size_t i = 0; i < m_contours.size(); ++ i) { - const Slic3r::Points &pts = *m_contours[i]; - for (size_t j = 0; j < pts.size(); ++ j) - m_bbox.merge(pts[j]); + for (const Contour &contour : m_contours) { + assert(contour.num_segments() > 0); + assert(*contour.begin() != contour.end()[-1]); + for (const Slic3r::Point &pt : contour) + m_bbox.merge(pt); } + coord_t eps = 16; m_bbox.min(0) -= eps; m_bbox.min(1) -= eps; @@ -170,11 +167,11 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) // 3) First round of contour rasterization, count the edges per grid cell. for (size_t i = 0; i < m_contours.size(); ++ i) { - const Slic3r::Points &pts = *m_contours[i]; - for (size_t j = 0; j < pts.size(); ++ j) { + const Contour &contour = m_contours[i]; + for (size_t j = 0; j < contour.num_segments(); ++ j) { // End points of the line segment. - Slic3r::Point p1(pts[j]); - Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1]; + Slic3r::Point p1(contour.segment_start(j)); + Slic3r::Point p2(contour.segment_end(j)); p1(0) -= m_bbox.min(0); p1(1) -= m_bbox.min(1); p2(0) -= m_bbox.min(0); @@ -333,9 +330,9 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) assert(visitor.i == 0); for (; visitor.i < m_contours.size(); ++ visitor.i) { - const Slic3r::Points &pts = *m_contours[visitor.i]; - for (visitor.j = 0; visitor.j < pts.size(); ++ visitor.j) - this->visit_cells_intersecting_line(pts[visitor.j], pts[(visitor.j + 1 == pts.size()) ? 0 : visitor.j + 1], visitor); + const Contour &contour = m_contours[visitor.i]; + for (visitor.j = 0; visitor.j < contour.num_segments(); ++ visitor.j) + this->visit_cells_intersecting_line(contour.segment_start(visitor.j), contour.segment_end(visitor.j), visitor); } } @@ -701,11 +698,12 @@ void EdgeGrid::Grid::calculate_sdf() const Cell &cell = m_cells[r * m_cols + c]; // For each segment in the cell: for (size_t i = cell.begin; i != cell.end; ++ i) { - const Slic3r::Points &pts = *m_contours[m_cell_data[i].first]; + const Contour &contour = m_contours[m_cell_data[i].first]; + assert(contour.closed()); size_t ipt = m_cell_data[i].second; // End points of the line segment. - const Slic3r::Point &p1 = pts[ipt]; - const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1]; + const Slic3r::Point &p1 = contour.segment_start(ipt); + const Slic3r::Point &p2 = contour.segment_end(ipt); // Segment vector const Slic3r::Point v_seg = p2 - p1; // l2 of v_seg @@ -729,7 +727,7 @@ void EdgeGrid::Grid::calculate_sdf() double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); if (dabs < d_min) { // Previous point. - const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1]; + const Slic3r::Point &p0 = contour.segment_prev(ipt); Slic3r::Point v_seg_prev = p1 - p0; int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1)); if (t2_pt > 0) { @@ -1049,7 +1047,7 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const return f; } -EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt, coord_t search_radius) const +EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point_signed_distance(const Point &pt, coord_t search_radius) const { BoundingBox bbox; bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1)); @@ -1088,12 +1086,13 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt for (int c = bbox.min(0); c <= bbox.max(0); ++ c) { const Cell &cell = m_cells[r * m_cols + c]; for (size_t i = cell.begin; i < cell.end; ++ i) { - const size_t contour_idx = m_cell_data[i].first; - const Slic3r::Points &pts = *m_contours[contour_idx]; + const size_t contour_idx = m_cell_data[i].first; + const Contour &contour = m_contours[contour_idx]; + assert(contour.closed()); size_t ipt = m_cell_data[i].second; // End points of the line segment. - const Slic3r::Point &p1 = pts[ipt]; - const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1]; + const Slic3r::Point &p1 = contour.segment_start(ipt); + const Slic3r::Point &p2 = contour.segment_end(ipt); const Slic3r::Point v_seg = p2 - p1; const Slic3r::Point v_pt = pt - p1; // dot(p2-p1, pt-p1) @@ -1105,7 +1104,7 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); if (dabs < d_min) { // Previous point. - const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1]; + const Slic3r::Point &p0 = contour.segment_prev(ipt); Slic3r::Point v_seg_prev = p1 - p0; int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1)); if (t2_pt > 0) { @@ -1161,9 +1160,9 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt assert(result.t >= 0. && result.t <= 1.); #ifndef NDEBUG { - const Slic3r::Points &pts = *m_contours[result.contour_idx]; - const Slic3r::Point &p1 = pts[result.start_point_idx]; - const Slic3r::Point &p2 = pts[(result.start_point_idx + 1 == pts.size()) ? 0 : result.start_point_idx + 1]; + const Contour &contour = m_contours[result.contour_idx]; + const Slic3r::Point &p1 = contour.segment_start(result.start_point_idx); + const Slic3r::Point &p2 = contour.segment_end(result.start_point_idx); Vec2d vfoot; if (result.t == 0) vfoot = p1.cast() - pt.cast(); @@ -1217,11 +1216,12 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu for (int c = bbox.min(0); c <= bbox.max(0); ++ c) { const Cell &cell = m_cells[r * m_cols + c]; for (size_t i = cell.begin; i < cell.end; ++ i) { - const Slic3r::Points &pts = *m_contours[m_cell_data[i].first]; + const Contour &contour = m_contours[m_cell_data[i].first]; + assert(contour.closed()); size_t ipt = m_cell_data[i].second; // End points of the line segment. - const Slic3r::Point &p1 = pts[ipt]; - const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1]; + const Slic3r::Point &p1 = contour.segment_start(ipt); + const Slic3r::Point &p2 = contour.segment_end(ipt); Slic3r::Point v_seg = p2 - p1; Slic3r::Point v_pt = pt - p1; // dot(p2-p1, pt-p1) @@ -1233,7 +1233,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); if (dabs < d_min) { // Previous point. - const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1]; + const Slic3r::Point &p0 = contour.segment_prev(ipt); Slic3r::Point v_seg_prev = p1 - p0; int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1)); if (t2_pt > 0) { @@ -1423,26 +1423,26 @@ std::vector> const Cell &cell = m_cells[r * m_cols + c]; // For each pair of segments in the cell: for (size_t i = cell.begin; i != cell.end; ++ i) { - const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first]; + const Contour &icontour = m_contours[m_cell_data[i].first]; size_t ipt = m_cell_data[i].second; // End points of the line segment and their vector. - const Slic3r::Point &ip1 = ipts[ipt]; - const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1]; + const Slic3r::Point &ip1 = icontour.segment_start(ipt); + const Slic3r::Point &ip2 = icontour.segment_end(ipt); for (size_t j = i + 1; j != cell.end; ++ j) { - const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first]; - size_t jpt = m_cell_data[j].second; + const Contour &jcontour = m_contours[m_cell_data[j].first]; + size_t jpt = m_cell_data[j].second; // End points of the line segment and their vector. - const Slic3r::Point &jp1 = jpts[jpt]; - const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1]; - if (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) + const Slic3r::Point &jp1 = jcontour.segment_start(jpt); + const Slic3r::Point &jp2 = jcontour.segment_end(jpt); + if (&icontour == &jcontour && (&ip1 == &jp2 || &jp1 == &ip2)) // Segments of the same contour share a common vertex. continue; if (Geometry::segments_intersect(ip1, ip2, jp1, jp2)) { // The two segments intersect. Add them to the output. - int jfirst = (&jpts < &ipts) || (&jpts == &ipts && jpt < ipt); + int jfirst = (&jcontour < &icontour) || (&jcontour == &icontour && jpt < ipt); out.emplace_back(jfirst ? - std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt)) : - std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt))); + std::make_pair(std::make_pair(&icontour, ipt), std::make_pair(&jcontour, jpt)) : + std::make_pair(std::make_pair(&icontour, ipt), std::make_pair(&jcontour, jpt))); } } } @@ -1460,18 +1460,18 @@ bool EdgeGrid::Grid::has_intersecting_edges() const const Cell &cell = m_cells[r * m_cols + c]; // For each pair of segments in the cell: for (size_t i = cell.begin; i != cell.end; ++ i) { - const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first]; + const Contour &icontour = m_contours[m_cell_data[i].first]; size_t ipt = m_cell_data[i].second; // End points of the line segment and their vector. - const Slic3r::Point &ip1 = ipts[ipt]; - const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1]; + const Slic3r::Point &ip1 = icontour.segment_start(ipt); + const Slic3r::Point &ip2 = icontour.segment_end(ipt); for (size_t j = i + 1; j != cell.end; ++ j) { - const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first]; + const Contour &jcontour = m_contours[m_cell_data[j].first]; size_t jpt = m_cell_data[j].second; // End points of the line segment and their vector. - const Slic3r::Point &jp1 = jpts[jpt]; - const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1]; - if (! (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) && + const Slic3r::Point &jp1 = jcontour.segment_start(jpt); + const Slic3r::Point &jp2 = jcontour.segment_end(jpt); + if (! (&icontour == &jcontour && (&ip1 == &jp2 || &jp1 == &ip2)) && Geometry::segments_intersect(ip1, ip2, jp1, jp2)) return true; } @@ -1606,22 +1606,27 @@ void export_intersections_to_svg(const std::string &filename, const Polygons &po SVG svg(filename.c_str(), bbox); svg.draw(union_ex(polygons), "gray", 0.25f); svg.draw_outline(polygons, "black"); - std::set intersecting_contours; + std::set intersecting_contours; for (const std::pair &ie : intersections) { intersecting_contours.insert(ie.first.first); intersecting_contours.insert(ie.second.first); } // Highlight the contours with intersections. coord_t line_width = coord_t(scale_(0.01)); - for (const Points *ic : intersecting_contours) { - svg.draw_outline(Polygon(*ic), "green"); - svg.draw_outline(Polygon(*ic), "black", line_width); + for (const EdgeGrid::Contour *ic : intersecting_contours) { + if (ic->open()) + svg.draw(Polyline(Points(ic->begin(), ic->end())), "green"); + else { + Polygon polygon(Points(ic->begin(), ic->end())); + svg.draw_outline(polygon, "green"); + svg.draw_outline(polygon, "black", line_width); + } } // Paint the intersections. for (const std::pair &intersecting_edges : intersections) { auto edge = [](const EdgeGrid::Grid::ContourEdge &e) { - return Line(e.first->at(e.second), - e.first->at((e.second + 1 == e.first->size()) ? 0 : e.second + 1)); + return Line(e.first->segment_start(e.second), + e.first->segment_end(e.second)); }; svg.draw(edge(intersecting_edges.first), "red", line_width); svg.draw(edge(intersecting_edges.second), "red", line_width); diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp index 7b5e3905ce..651a6d7630 100644 --- a/src/libslic3r/EdgeGrid.hpp +++ b/src/libslic3r/EdgeGrid.hpp @@ -12,22 +12,89 @@ namespace Slic3r { namespace EdgeGrid { + +class Contour { +public: + Contour() = default; + Contour(const Slic3r::Point *begin, const Slic3r::Point *end, bool open) : m_begin(begin), m_end(end), m_open(open) {} + Contour(const Slic3r::Point *data, size_t size, bool open) : Contour(data, data + size, open) {} + Contour(const std::vector &pts, bool open) : Contour(pts.data(), pts.size(), open) {} + + const Slic3r::Point *begin() const { return m_begin; } + const Slic3r::Point *end() const { return m_end; } + bool open() const { return m_open; } + bool closed() const { return ! m_open; } + + // Start point of a segment idx. + const Slic3r::Point& segment_start(size_t idx) const { + assert(idx < this->num_segments()); + return m_begin[idx]; + } + + // End point of a segment idx. + const Slic3r::Point& segment_end(size_t idx) const { + assert(idx < this->num_segments()); + const Slic3r::Point *ptr = m_begin + idx + 1; + return ptr == m_end ? *m_begin : *ptr; + } + + // Start point of a segment preceding idx. + const Slic3r::Point& segment_prev(size_t idx) const { + assert(idx < this->num_segments()); + assert(idx > 0 || ! m_open); + return idx == 0 ? m_end[-1] : m_begin[idx - 1]; + } + + // Index of a segment preceding idx. + const size_t segment_idx_prev(size_t idx) const { + assert(idx < this->num_segments()); + assert(idx > 0 || ! m_open); + return (idx == 0 ? this->size() : idx) - 1; + } + + // Index of a segment preceding idx. + const size_t segment_idx_next(size_t idx) const { + assert(idx < this->num_segments()); + ++ idx; + return m_begin + idx == m_end ? 0 : idx; + } + + size_t num_segments() const { return this->size() - (m_open ? 1 : 0); } + +private: + size_t size() const { return m_end - m_begin; } + + const Slic3r::Point *m_begin { nullptr }; + const Slic3r::Point *m_end { nullptr }; + bool m_open { false }; +}; + class Grid { public: - Grid(); - ~Grid(); + Grid() = default; + Grid(const BoundingBox &bbox) : m_bbox(bbox) {} void set_bbox(const BoundingBox &bbox) { m_bbox = bbox; } + // Fill in the grid with open polylines or closed contours. + // If open flag is indicated, then polylines_or_polygons are considered to be open by default. + // Only if the first point of a polyline is equal to the last point of a polyline, + // then the polyline is considered to be closed and the last repeated point is removed when + // inserted into the EdgeGrid. + // Most of the Grid functions expect all the contours to be closed, you have been warned! + void create(const std::vector &polylines_or_polygons, coord_t resolution, bool open); + void create(const Polygons &polygons, const Polylines &polylines, coord_t resolution); + + // Fill in the grid with closed contours. void create(const Polygons &polygons, coord_t resolution); void create(const std::vector &polygons, coord_t resolution); - void create(const std::vector &polygons, coord_t resolution); + void create(const std::vector &polygons, coord_t resolution) { this->create(polygons, resolution, false); } void create(const ExPolygon &expoly, coord_t resolution); void create(const ExPolygons &expolygons, coord_t resolution); void create(const ExPolygonCollection &expolygons, coord_t resolution); - const std::vector& contours() const { return m_contours; } + const std::vector& contours() const { return m_contours; } #if 0 // Test, whether the edges inside the grid intersect with the polygons provided. @@ -44,12 +111,14 @@ public: // Fill in a rough m_signed_distance_field from the edge grid. // The rough SDF is used by signed_distance() for distances outside of the search_radius. + // Only call this function for closed contours! void calculate_sdf(); // Return an estimate of the signed distance based on m_signed_distance_field grid. float signed_distance_bilinear(const Point &pt) const; // Calculate a signed distance to the contours in search_radius from the point. + // Only call this function for closed contours! struct ClosestPointResult { size_t contour_idx = size_t(-1); size_t start_point_idx = size_t(-1); @@ -60,12 +129,14 @@ public: bool valid() const { return contour_idx != size_t(-1); } }; - ClosestPointResult closest_point(const Point &pt, coord_t search_radius) const; + ClosestPointResult closest_point_signed_distance(const Point &pt, coord_t search_radius) const; + // Only call this function for closed contours! bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = nullptr) const; // Calculate a signed distance to the contours in search_radius from the point. If no edge is found in search_radius, // return an interpolated value from m_signed_distance_field, if it exists. + // Only call this function for closed contours! bool signed_distance(const Point &pt, coord_t search_radius, coordf_t &result_min_dist) const; const BoundingBox& bbox() const { return m_bbox; } @@ -76,8 +147,8 @@ public: // For supports: Contours enclosing the rasterized edges. Polygons contours_simplified(coord_t offset, bool fill_holes) const; - typedef std::pair ContourPoint; - typedef std::pair ContourEdge; + typedef std::pair ContourPoint; + typedef std::pair ContourEdge; std::vector> intersecting_edges() const; bool has_intersecting_edges() const; @@ -255,16 +326,16 @@ public: std::pair segment(const std::pair &contour_and_segment_idx) const { - const Slic3r::Points &ipts = *m_contours[contour_and_segment_idx.first]; - size_t ipt = contour_and_segment_idx.second; - return std::pair(ipts[ipt], ipts[ipt + 1 == ipts.size() ? 0 : ipt + 1]); + const Contour &contour = m_contours[contour_and_segment_idx.first]; + size_t iseg = contour_and_segment_idx.second; + return std::pair(contour.segment_start(iseg), contour.segment_end(iseg)); } Line line(const std::pair &contour_and_segment_idx) const { - const Slic3r::Points &ipts = *m_contours[contour_and_segment_idx.first]; - size_t ipt = contour_and_segment_idx.second; - return Line(ipts[ipt], ipts[ipt + 1 == ipts.size() ? 0 : ipt + 1]); + const Contour &contour = m_contours[contour_and_segment_idx.first]; + size_t iseg = contour_and_segment_idx.second; + return Line(contour.segment_start(iseg), contour.segment_end(iseg)); } protected: @@ -295,13 +366,13 @@ protected: BoundingBox m_bbox; // Grid dimensions. coord_t m_resolution; - size_t m_rows; - size_t m_cols; + size_t m_rows = 0; + size_t m_cols = 0; // Referencing the source contours. // This format allows one to work with any Slic3r fixed point contour format // (Polygon, ExPolygon, ExPolygonCollection etc). - std::vector m_contours; + std::vector m_contours; // Referencing a contour and a line segment of m_contours. std::vector > m_cell_data; diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 1e50ade5ab..f28d88f7e9 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -104,7 +104,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx double param_hi; double param_end = resampled_point_parameters.back().curve_parameter; { - const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; + const EdgeGrid::Contour &contour = grid.contours()[it_contour_and_segment->first]; size_t ipt = it_contour_and_segment->second; ResampledPoint key(ipt, false, 0.); auto lower = [](const ResampledPoint& l, const ResampledPoint r) { return l.idx_src < r.idx_src || (l.idx_src == r.idx_src && int(l.interpolated) > int(r.interpolated)); }; @@ -112,7 +112,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); double t2 = cross2(dir, vptpt2) / denom; assert(t2 > - EPSILON && t2 < 1. + EPSILON); - if (++ ipt == ipts.size()) + if (contour.begin() + (++ ipt) == contour.end()) param_hi = t2 * dir2.norm(); else param_hi = it->curve_parameter + t2 * dir2.norm(); @@ -251,7 +251,7 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id #endif struct Visitor { Visitor(const EdgeGrid::Grid &grid, const size_t idx_contour, const std::vector &resampled_point_parameters, double dist_same_contour_accept, double dist_same_contour_reject) : - grid(grid), idx_contour(idx_contour), contour(*grid.contours()[idx_contour]), resampled_point_parameters(resampled_point_parameters), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} + grid(grid), idx_contour(idx_contour), contour(grid.contours()[idx_contour]), resampled_point_parameters(resampled_point_parameters), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} void init(const Points &contour, const Point &apoint) { this->idx_point = &apoint - contour.data(); @@ -283,15 +283,15 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id double param_lo = resampled_point_parameters[this->idx_point].curve_parameter; double param_hi; double param_end = resampled_point_parameters.back().curve_parameter; - const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; - const size_t ipt = it_contour_and_segment->second; + const EdgeGrid::Contour &contour = grid.contours()[it_contour_and_segment->first]; + const size_t ipt = it_contour_and_segment->second; { ResampledPoint key(ipt, false, 0.); auto lower = [](const ResampledPoint& l, const ResampledPoint r) { return l.idx_src < r.idx_src || (l.idx_src == r.idx_src && int(l.interpolated) > int(r.interpolated)); }; auto it = std::lower_bound(resampled_point_parameters.begin(), resampled_point_parameters.end(), key, lower); assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); param_hi = t * sqrt(l2); - if (ipt + 1 < ipts.size()) + if (contour.begin() + ipt + 1 < contour.end()) param_hi += it->curve_parameter; } if (param_lo > param_hi) @@ -307,9 +307,9 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id // Bulge is estimated by 0.6 of the circle circumference drawn around the bisector. // Test whether the contour is convex or concave. bool inside = - (t == 0.) ? this->inside_corner(ipts, ipt, this->point) : - (t == 1.) ? this->inside_corner(ipts, ipt + 1 == ipts.size() ? 0 : ipt + 1, this->point) : - this->left_of_segment(ipts, ipt, this->point); + (t == 0.) ? this->inside_corner(contour, ipt, this->point) : + (t == 1.) ? this->inside_corner(contour, contour.segment_idx_next(ipt), this->point) : + this->left_of_segment(contour, ipt, this->point); accept = inside && dist_along_contour > 0.6 * M_PI * dist; } } @@ -329,7 +329,7 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id const EdgeGrid::Grid &grid; const size_t idx_contour; - const Points &contour; + const EdgeGrid::Contour &contour; const std::vector &resampled_point_parameters; const double dist_same_contour_accept; const double dist_same_contour_reject; @@ -358,24 +358,28 @@ std::vector contour_distance2(const EdgeGrid::Grid &grid, const size_t id return Vec2d(- v.y(), v.x()); } - static bool inside_corner(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { - const Vec2d pt = pt_oposite.cast(); - size_t iprev = prev_idx_modulo(i, contour); - size_t inext = next_idx_modulo(i, contour); - Vec2d v1 = (contour[i] - contour[iprev]).cast(); - Vec2d v2 = (contour[inext] - contour[i]).cast(); - bool left_of_v1 = cross2(v1, pt - contour[iprev].cast()) > 0.; - bool left_of_v2 = cross2(v2, pt - contour[i ].cast()) > 0.; - return cross2(v1, v2) > 0 ? - left_of_v1 && left_of_v2 : // convex corner - left_of_v1 || left_of_v2; // concave corner - } - static bool left_of_segment(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) { - const Vec2d pt = pt_oposite.cast(); - size_t inext = next_idx_modulo(i, contour); - Vec2d v = (contour[inext] - contour[i]).cast(); - return cross2(v, pt - contour[i].cast()) > 0.; - } + static bool inside_corner(const EdgeGrid::Contour &contour, size_t i, const Point &pt_oposite) + { + const Vec2d pt = pt_oposite.cast(); + const Point &pt_prev = contour.segment_prev(i); + const Point &pt_this = contour.segment_start(i); + const Point &pt_next = contour.segment_end(i); + Vec2d v1 = (pt_this - pt_prev).cast(); + Vec2d v2 = (pt_next - pt_this).cast(); + bool left_of_v1 = cross2(v1, pt - pt_prev.cast()) > 0.; + bool left_of_v2 = cross2(v2, pt - pt_this.cast()) > 0.; + return cross2(v1, v2) > 0 ? left_of_v1 && left_of_v2 : // convex corner + left_of_v1 || left_of_v2; // concave corner + } + + static bool left_of_segment(const EdgeGrid::Contour &contour, size_t i, const Point &pt_oposite) + { + const Vec2d pt = pt_oposite.cast(); + const Point &pt_this = contour.segment_start(i); + const Point &pt_next = contour.segment_end(i); + Vec2d v = (pt_next - pt_this).cast(); + return cross2(v, pt - pt_this.cast()) > 0.; + } } visitor(grid, idx_contour, resampled_point_parameters, 0.5 * compensation * M_PI, search_radius); out.reserve(contour.size()); @@ -441,6 +445,7 @@ Points resample_polygon(const Points &contour, double dist, std::vector &compensation, float strength, size_t num_iterations) { std::vector out(compensation); @@ -455,6 +460,7 @@ static inline void smooth_compensation(std::vector &compensation, float s out.swap(compensation); } } +#endif static inline void smooth_compensation_banded(const Points &contour, float band, std::vector &compensation, float strength, size_t num_iterations) { diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index f698a35589..489023041f 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -6,8 +6,6 @@ #include "Line.hpp" #include "ClipperUtils.hpp" #include "SVG.hpp" -#include "polypartition.h" -#include "poly2tri/poly2tri.h" #include #include #include @@ -80,6 +78,13 @@ bool ExPolygon::is_valid() const return true; } +void ExPolygon::douglas_peucker(double tolerance) +{ + this->contour.douglas_peucker(tolerance); + for (Polygon &poly : this->holes) + poly.douglas_peucker(tolerance); +} + bool ExPolygon::contains(const Line &line) const { return this->contains(Polyline(line.a, line.b)); @@ -311,284 +316,6 @@ ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines) polylines->insert(polylines->end(), tp.begin(), tp.end()); } -/* -void ExPolygon::get_trapezoids(Polygons* polygons) const -{ - ExPolygons expp; - expp.push_back(*this); - boost::polygon::get_trapezoids(*polygons, expp); -} - -void ExPolygon::get_trapezoids(Polygons* polygons, double angle) const -{ - ExPolygon clone = *this; - clone.rotate(PI/2 - angle, Point(0,0)); - clone.get_trapezoids(polygons); - for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon) - polygon->rotate(-(PI/2 - angle), Point(0,0)); -} -*/ - -// This algorithm may return more trapezoids than necessary -// (i.e. it may break a single trapezoid in several because -// other parts of the object have x coordinates in the middle) -void ExPolygon::get_trapezoids2(Polygons* polygons) const -{ - // get all points of this ExPolygon - Points pp = *this; - - // build our bounding box - BoundingBox bb(pp); - - // get all x coordinates - std::vector xx; - xx.reserve(pp.size()); - for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p) - xx.push_back(p->x()); - std::sort(xx.begin(), xx.end()); - - // find trapezoids by looping from first to next-to-last coordinate - for (std::vector::const_iterator x = xx.begin(); x != xx.end()-1; ++x) { - coord_t next_x = *(x + 1); - if (*x != next_x) - // intersect with rectangle - // append results to return value - polygons_append(*polygons, intersection({ { { *x, bb.min.y() }, { next_x, bb.min.y() }, { next_x, bb.max.y() }, { *x, bb.max.y() } } }, to_polygons(*this))); - } -} - -void ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const -{ - ExPolygon clone = *this; - clone.rotate(PI/2 - angle, Point(0,0)); - clone.get_trapezoids2(polygons); - for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon) - polygon->rotate(-(PI/2 - angle), Point(0,0)); -} - -// While this triangulates successfully, it's NOT a constrained triangulation -// as it will create more vertices on the boundaries than the ones supplied. -void ExPolygon::triangulate(Polygons* polygons) const -{ - // first make trapezoids - Polygons trapezoids; - this->get_trapezoids2(&trapezoids); - - // then triangulate each trapezoid - for (Polygons::iterator polygon = trapezoids.begin(); polygon != trapezoids.end(); ++polygon) - polygon->triangulate_convex(polygons); -} - -/* -void ExPolygon::triangulate_pp(Polygons* polygons) const -{ - // convert polygons - std::list input; - - ExPolygons expp = union_ex(simplify_polygons(to_polygons(*this), true)); - - for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { - // contour - { - TPPLPoly p; - p.Init(int(ex->contour.points.size())); - //printf("%zu\n0\n", ex->contour.points.size()); - for (const Point &point : ex->contour.points) { - size_t i = &point - &ex->contour.points.front(); - p[i].x = point(0); - p[i].y = point(1); - //printf("%ld %ld\n", point->x(), point->y()); - } - p.SetHole(false); - input.push_back(p); - } - - // holes - for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) { - TPPLPoly p; - p.Init(hole->points.size()); - //printf("%zu\n1\n", hole->points.size()); - for (const Point &point : hole->points) { - size_t i = &point - &hole->points.front(); - p[i].x = point(0); - p[i].y = point(1); - //printf("%ld %ld\n", point->x(), point->y()); - } - p.SetHole(true); - input.push_back(p); - } - } - - // perform triangulation - std::list output; - int res = TPPLPartition().Triangulate_MONO(&input, &output); - if (res != 1) - throw Slic3r::RuntimeError("Triangulation failed"); - - // convert output polygons - for (std::list::iterator poly = output.begin(); poly != output.end(); ++poly) { - long num_points = poly->GetNumPoints(); - Polygon p; - p.points.resize(num_points); - for (long i = 0; i < num_points; ++i) { - p.points[i](0) = coord_t((*poly)[i].x); - p.points[i](1) = coord_t((*poly)[i].y); - } - polygons->push_back(p); - } -} -*/ - -std::list expoly_to_polypartition_input(const ExPolygon &ex) -{ - std::list input; - // contour - { - input.emplace_back(); - TPPLPoly &p = input.back(); - p.Init(int(ex.contour.points.size())); - for (const Point &point : ex.contour.points) { - size_t i = &point - &ex.contour.points.front(); - p[i].x = point(0); - p[i].y = point(1); - } - p.SetHole(false); - } - // holes - for (const Polygon &hole : ex.holes) { - input.emplace_back(); - TPPLPoly &p = input.back(); - p.Init(hole.points.size()); - for (const Point &point : hole.points) { - size_t i = &point - &hole.points.front(); - p[i].x = point(0); - p[i].y = point(1); - } - p.SetHole(true); - } - return input; -} - -std::list expoly_to_polypartition_input(const ExPolygons &expps) -{ - std::list input; - for (const ExPolygon &ex : expps) { - // contour - { - input.emplace_back(); - TPPLPoly &p = input.back(); - p.Init(int(ex.contour.points.size())); - for (const Point &point : ex.contour.points) { - size_t i = &point - &ex.contour.points.front(); - p[i].x = point(0); - p[i].y = point(1); - } - p.SetHole(false); - } - // holes - for (const Polygon &hole : ex.holes) { - input.emplace_back(); - TPPLPoly &p = input.back(); - p.Init(hole.points.size()); - for (const Point &point : hole.points) { - size_t i = &point - &hole.points.front(); - p[i].x = point(0); - p[i].y = point(1); - } - p.SetHole(true); - } - } - return input; -} - -std::vector polypartition_output_to_triangles(const std::list &output) -{ - size_t num_triangles = 0; - for (const TPPLPoly &poly : output) - if (poly.GetNumPoints() >= 3) - num_triangles += (size_t)poly.GetNumPoints() - 2; - std::vector triangles; - triangles.reserve(triangles.size() + num_triangles * 3); - for (const TPPLPoly &poly : output) { - long num_points = poly.GetNumPoints(); - if (num_points >= 3) { - const TPPLPoint *pt0 = &poly[0]; - const TPPLPoint *pt1 = nullptr; - const TPPLPoint *pt2 = &poly[1]; - for (long i = 2; i < num_points; ++ i) { - pt1 = pt2; - pt2 = &poly[i]; - triangles.emplace_back(coord_t(pt0->x), coord_t(pt0->y)); - triangles.emplace_back(coord_t(pt1->x), coord_t(pt1->y)); - triangles.emplace_back(coord_t(pt2->x), coord_t(pt2->y)); - } - } - } - return triangles; -} - -void ExPolygon::triangulate_pp(Points *triangles) const -{ - ExPolygons expp = union_ex(simplify_polygons(to_polygons(*this), true)); - std::list input = expoly_to_polypartition_input(expp); - // perform triangulation - std::list output; - int res = TPPLPartition().Triangulate_MONO(&input, &output); -// int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) { - if (res != 1) - throw Slic3r::RuntimeError("Triangulation failed"); - *triangles = polypartition_output_to_triangles(output); -} - -// Uses the Poly2tri library maintained by Jan Niklas Hasse @jhasse // https://github.com/jhasse/poly2tri -// See https://github.com/jhasse/poly2tri/blob/master/README.md for the limitations of the library! -// No duplicate points are allowed, no very close points, holes must not touch outer contour etc. -void ExPolygon::triangulate_p2t(Polygons* polygons) const -{ - ExPolygons expp = simplify_polygons_ex(*this, true); - - for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { - // TODO: prevent duplicate points - - // contour - std::vector ContourPoints; - for (const Point &pt : ex->contour.points) - // We should delete each p2t::Point object - ContourPoints.push_back(new p2t::Point(pt(0), pt(1))); - p2t::CDT cdt(ContourPoints); - - // holes - for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) { - std::vector points; - for (const Point &pt : hole->points) - // will be destructed in SweepContext::~SweepContext - points.push_back(new p2t::Point(pt(0), pt(1))); - cdt.AddHole(points); - } - - // perform triangulation - try { - cdt.Triangulate(); - std::vector triangles = cdt.GetTriangles(); - - for (std::vector::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) { - Polygon p; - for (int i = 0; i <= 2; ++i) { - p2t::Point* point = (*triangle)->GetPoint(i); - p.points.push_back(Point(point->x, point->y)); - } - polygons->push_back(p); - } - } catch (const Slic3r::RuntimeError & /* err */) { - assert(false); - // just ignore, don't triangulate - } - - for (p2t::Point *ptr : ContourPoints) - delete ptr; - } -} - Lines ExPolygon::lines() const { Lines lines = this->contour.lines(); diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index b4651abc23..46b3a3a1b9 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -6,9 +6,6 @@ #include "Polyline.hpp" #include -// polygon class of the polypartition library -class TPPLPoly; - namespace Slic3r { class ExPolygon; @@ -49,6 +46,7 @@ public: double area() const; bool empty() const { return contour.points.empty(); } bool is_valid() const; + void douglas_peucker(double tolerance); // Contains the line / polyline / polylines etc COMPLETELY. bool contains(const Line &line) const; @@ -69,14 +67,6 @@ public: void simplify(double tolerance, ExPolygons* expolygons) const; void medial_axis(double max_width, double min_width, ThickPolylines* polylines) const; void medial_axis(double max_width, double min_width, Polylines* polylines) const; -// void get_trapezoids(Polygons* polygons) const; -// void get_trapezoids(Polygons* polygons, double angle) const; - void get_trapezoids2(Polygons* polygons) const; - void get_trapezoids2(Polygons* polygons, double angle) const; - void triangulate(Polygons* polygons) const; - // Triangulate into triples of points. - void triangulate_pp(Points *triangles) const; - void triangulate_p2t(Polygons* polygons) const; Lines lines() const; // Number of contours (outer contour with holes). @@ -249,6 +239,24 @@ inline Polygons to_polygons(ExPolygons &&src) return polygons; } +inline ExPolygons to_expolygons(const Polygons &polys) +{ + ExPolygons ex_polys; + ex_polys.assign(polys.size(), ExPolygon()); + for (size_t idx = 0; idx < polys.size(); ++idx) + ex_polys[idx].contour = polys[idx]; + return ex_polys; +} + +inline ExPolygons to_expolygons(Polygons &&polys) +{ + ExPolygons ex_polys; + ex_polys.assign(polys.size(), ExPolygon()); + for (size_t idx = 0; idx < polys.size(); ++idx) + ex_polys[idx].contour = std::move(polys[idx]); + return ex_polys; +} + inline void polygons_append(Polygons &dst, const ExPolygon &src) { dst.reserve(dst.size() + src.holes.size() + 1); @@ -330,10 +338,6 @@ extern std::vector get_extents_vector(const ExPolygons &polygons); extern bool remove_sticks(ExPolygon &poly); extern void keep_largest_contour_only(ExPolygons &polygons); -extern std::list expoly_to_polypartition_input(const ExPolygons &expp); -extern std::list expoly_to_polypartition_input(const ExPolygon &ex); -extern std::vector polypartition_output_to_triangles(const std::list &output); - inline double area(const ExPolygons &polys) { double s = 0.; diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 6b0153b2ea..2c43cd4af8 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace Slic3r { @@ -102,6 +103,7 @@ public: virtual double min_mm3_per_mm() const = 0; virtual Polyline as_polyline() const = 0; virtual void collect_polylines(Polylines &dst) const = 0; + virtual void collect_points(Points &dst) const = 0; virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; } virtual double length() const = 0; virtual double total_volume() const = 0; @@ -167,6 +169,7 @@ public: double min_mm3_per_mm() const override { return this->mm3_per_mm; } Polyline as_polyline() const override { return this->polyline; } void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); } + void collect_points(Points &dst) const override { append(dst, this->polyline.points); } double total_volume() const override { return mm3_per_mm * unscale(length()); } private: @@ -217,6 +220,12 @@ public: double min_mm3_per_mm() const override; Polyline as_polyline() const override; void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); } + void collect_points(Points &dst) const override { + size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); }); + dst.reserve(dst.size() + n); + for (const ExtrusionPath &p : this->paths) + append(dst, p.polyline.points); + } double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; } }; @@ -268,6 +277,12 @@ public: double min_mm3_per_mm() const override; Polyline as_polyline() const override { return this->polygon().split_at_first_point(); } void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); } + void collect_points(Points &dst) const override { + size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); }); + dst.reserve(dst.size() + n); + for (const ExtrusionPath &p : this->paths) + append(dst, p.polyline.points); + } double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; } //static inline std::string role_to_string(ExtrusionLoopRole role); @@ -343,6 +358,25 @@ inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons loops.clear(); } +inline void extrusion_entities_append_loops_and_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height) +{ + dst.reserve(dst.size() + polylines.size()); + for (Polyline &polyline : polylines) { + if (polyline.is_valid()) { + if (polyline.is_closed()) { + ExtrusionPath extrusion_path(role, mm3_per_mm, width, height); + extrusion_path.polyline = std::move(polyline); + dst.emplace_back(new ExtrusionLoop(std::move(extrusion_path))); + } else { + ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height); + extrusion_path->polyline = std::move(polyline); + dst.emplace_back(extrusion_path); + } + } + } + polylines.clear(); +} + } #endif diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp index 5e40ab32ec..6e62a45fd6 100644 --- a/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/src/libslic3r/ExtrusionEntityCollection.hpp @@ -117,6 +117,11 @@ public: extrusion_entity->collect_polylines(dst); } + void collect_points(Points &dst) const override { + for (ExtrusionEntity* extrusion_entity : this->entities) + extrusion_entity->collect_points(dst); + } + double length() const override { throw Slic3r::RuntimeError("Calling length() on a ExtrusionEntityCollection"); return 0.; diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 18e03e0058..ee493ca9cb 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -25,7 +25,7 @@ struct SurfaceFillParams // in unscaled coordinates coordf_t spacing = 0.; // infill / perimeter overlap, in unscaled coordinates - coordf_t overlap = 0.; +// coordf_t overlap = 0.; // Angle as provided by the region config, in radians. float angle = 0.f; // Non-negative for a bridge. @@ -34,7 +34,7 @@ struct SurfaceFillParams // FillParams float density = 0.f; // Don't adjust spacing to fill the space evenly. - bool dont_adjust = false; +// bool dont_adjust = false; // Length of the infill anchor along the perimeter line. // 1000mm is roughly the maximum length line that fits into a 32bit coord_t. float anchor_length = 1000.f; @@ -64,10 +64,10 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(extruder); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, pattern); RETURN_COMPARE_NON_EQUAL(spacing); - RETURN_COMPARE_NON_EQUAL(overlap); +// RETURN_COMPARE_NON_EQUAL(overlap); RETURN_COMPARE_NON_EQUAL(angle); RETURN_COMPARE_NON_EQUAL(density); - RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust); +// RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust); RETURN_COMPARE_NON_EQUAL(anchor_length); RETURN_COMPARE_NON_EQUAL(anchor_length_max); RETURN_COMPARE_NON_EQUAL(flow.width); @@ -83,10 +83,10 @@ struct SurfaceFillParams this->pattern == rhs.pattern && this->pattern == rhs.pattern && this->spacing == rhs.spacing && - this->overlap == rhs.overlap && +// this->overlap == rhs.overlap && this->angle == rhs.angle && this->density == rhs.density && - this->dont_adjust == rhs.dont_adjust && +// this->dont_adjust == rhs.dont_adjust && this->anchor_length == rhs.anchor_length && this->anchor_length_max == rhs.anchor_length_max && this->flow == rhs.flow && @@ -130,7 +130,7 @@ std::vector group_fills(const Layer &layer) params.density = 100.f; params.pattern = (surface.is_external() && ! is_bridge) ? (surface.is_top() ? region_config.top_fill_pattern.value : region_config.bottom_fill_pattern.value) : - ipRectilinear; + region_config.top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear; } else if (params.density <= 0) continue; @@ -158,6 +158,7 @@ std::vector group_fills(const Layer &layer) params.spacing = params.flow.spacing(); // Don't limit anchor length for solid or bridging infill. params.anchor_length = 1000.f; + params.anchor_length_max = 1000.f; } else { // it's internal infill, so we can calculate a generic flow spacing // for all layers, for avoiding the ugly effect of @@ -173,13 +174,13 @@ std::vector group_fills(const Layer &layer) ).spacing(); // Anchor a sparse infill to inner perimeters with the following anchor length: params.anchor_length = float(region_config.infill_anchor); - if (region_config.infill_anchor.percent) - params.anchor_length = float(params.anchor_length * 0.01 * params.spacing); - params.anchor_length_max = float(region_config.infill_anchor_max); - if (region_config.infill_anchor_max.percent) - params.anchor_length_max = float(params.anchor_length_max * 0.01 * params.spacing); - } - params.anchor_length = std::min(params.anchor_length, params.anchor_length_max); + if (region_config.infill_anchor.percent) + params.anchor_length = float(params.anchor_length * 0.01 * params.spacing); + params.anchor_length_max = float(region_config.infill_anchor_max); + if (region_config.infill_anchor_max.percent) + params.anchor_length_max = float(params.anchor_length_max * 0.01 * params.spacing); + params.anchor_length = std::min(params.anchor_length, params.anchor_length_max); + } auto it_params = set_surface_params.find(params); if (it_params == set_surface_params.end()) @@ -284,7 +285,7 @@ std::vector group_fills(const Layer &layer) if (internal_solid_fill == nullptr) { // Produce another solid fill. params.extruder = layerm.region()->extruder(frSolidInfill); - params.pattern = ipRectilinear; + params.pattern = layerm.region()->config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear; params.density = 100.f; params.extrusion_role = erInternalInfill; params.angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value)); @@ -384,7 +385,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: // apply half spacing using this flow's own spacing and generate infill FillParams params; params.density = float(0.01 * surface_fill.params.density); - params.dont_adjust = surface_fill.params.dont_adjust; // false + params.dont_adjust = false; // surface_fill.params.dont_adjust; params.anchor_length = surface_fill.params.anchor_length; params.anchor_length_max = surface_fill.params.anchor_length_max; @@ -532,6 +533,7 @@ void Layer::make_ironing() } } if (ironing_params.extruder != -1) { + //TODO just_infill is currently not used. ironing_params.just_infill = false; ironing_params.line_spacing = config.ironing_spacing; ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate; @@ -562,17 +564,54 @@ void Layer::make_ironing() ExPolygons ironing_areas; double nozzle_dmr = this->object()->print()->config().nozzle_diameter.values[ironing_params.extruder - 1]; if (ironing_params.just_infill) { + //TODO just_infill is currently not used. // Just infill. } else { // Infill and perimeter. // Merge top surfaces with the same ironing parameters. Polygons polys; - for (size_t k = i; k < j; ++ k) - for (const Surface &surface : by_extruder[k].layerm->slices.surfaces) - if (surface.surface_type == stTop) + Polygons infills; + for (size_t k = i; k < j; ++ k) { + const IroningParams &ironing_params = by_extruder[k]; + const PrintRegionConfig ®ion_config = ironing_params.layerm->region()->config(); + bool iron_everything = region_config.ironing_type == IroningType::AllSolid; + bool iron_completely = iron_everything; + if (iron_everything) { + // Check whether there is any non-solid hole in the regions. + bool internal_infill_solid = region_config.fill_density.value > 95.; + for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces) + if ((! internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid) { + // Some fill region is not quite solid. Don't iron over the whole surface. + iron_completely = false; + break; + } + } + if (iron_completely) { + // Iron everything. This is likely only good for solid transparent objects. + for (const Surface &surface : ironing_params.layerm->slices.surfaces) polygons_append(polys, surface.expolygon); + } else { + for (const Surface &surface : ironing_params.layerm->slices.surfaces) + if (surface.surface_type == stTop || (iron_everything && surface.surface_type == stBottom)) + // stBottomBridge is not being ironed on purpose, as it would likely destroy the bridges. + polygons_append(polys, surface.expolygon); + } + if (iron_everything && ! iron_completely) { + // Add solid fill surfaces. This may not be ideal, as one will not iron perimeters touching these + // solid fill surfaces, but it is likely better than nothing. + for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces) + if (surface.surface_type == stInternalSolid) + polygons_append(infills, surface.expolygon); + } + } // Trim the top surfaces with half the nozzle diameter. ironing_areas = intersection_ex(polys, offset(this->lslices, - float(scale_(0.5 * nozzle_dmr)))); + if (! infills.empty()) { + // For IroningType::AllSolid only: + // Add solid infill areas for layers, that contain some non-ironable infil (sparse infill, bridge infill). + append(infills, to_polygons(std::move(ironing_areas))); + ironing_areas = union_ex(infills, true); + } } // Create the filler object. diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index af53907c79..b4afd25917 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -678,6 +678,7 @@ static inline bool line_rounded_thick_segment_collision( return intersects; } +#ifndef NDEBUG static inline bool inside_interval(double low, double high, double p) { return p >= low && p <= high; @@ -702,6 +703,7 @@ static inline bool cyclic_interval_inside_interval(double outer_low, double oute } return interval_inside_interval(outer_low, outer_high, inner_low, inner_high, double(SCALED_EPSILON)); } +#endif // NDEBUG // #define INFILL_DEBUG_OUTPUT @@ -1129,7 +1131,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector chain_monotonic_regions( #endif /* NDEBUG */ // How many times to repeat the ant simulation (number of ant generations). - constexpr int num_rounds = 25; + constexpr int const num_rounds = 25; // After how many rounds without an improvement to exit? - constexpr int num_rounds_no_change_exit = 8; + constexpr int const num_rounds_no_change_exit = 8; // With how many ants each of the run will be performed? - const int num_ants = std::min(int(regions.size()), 10); + const int num_ants = std::min(int(regions.size()), 10); // Base (initial) pheromone level. This value will be adjusted based on the length of the first greedy path found. - float pheromone_initial_deposit = 0.5f; + float pheromone_initial_deposit = 0.5f; // Evaporation rate of pheromones. - constexpr float pheromone_evaporation = 0.1f; + constexpr float const pheromone_evaporation = 0.1f; // Evaporation rate to diversify paths taken by individual ants. - constexpr float pheromone_diversification = 0.1f; + constexpr float const pheromone_diversification = 0.1f; // Probability at which to take the next best path. Otherwise take the the path based on the cost distribution. - constexpr float probability_take_best = 0.9f; + constexpr float const probability_take_best = 0.9f; // Exponents of the cost function. - constexpr float pheromone_alpha = 1.f; // pheromone exponent - constexpr float pheromone_beta = 2.f; // attractiveness weighted towards edge length + constexpr float const pheromone_alpha = 1.f; // pheromone exponent + constexpr float const pheromone_beta = 2.f; // attractiveness weighted towards edge length AntPathMatrix path_matrix(regions, poly_with_offset, segs, pheromone_initial_deposit); @@ -2332,7 +2332,12 @@ static std::vector chain_monotonic_regions( } // Probability (unnormalized) of traversing a link between two monotonic regions. - auto path_probability = [pheromone_alpha, pheromone_beta](AntPath &path) { + auto path_probability = [ +#ifndef __APPLE__ + // clang complains when capturing constexpr constants. + pheromone_alpha, pheromone_beta +#endif // __APPLE__ + ](AntPath &path) { return pow(path.pheromone, pheromone_alpha) * pow(path.visibility, pheromone_beta); }; diff --git a/src/libslic3r/Fill/FillRectilinear.hpp b/src/libslic3r/Fill/FillRectilinear.hpp index 0686fa166a..692fba2bd1 100644 --- a/src/libslic3r/Fill/FillRectilinear.hpp +++ b/src/libslic3r/Fill/FillRectilinear.hpp @@ -12,7 +12,7 @@ class Surface; class FillRectilinear : public Fill { public: - Fill* clone() const override { return new FillRectilinear(*this); }; + Fill* clone() const override { return new FillRectilinear(*this); } ~FillRectilinear() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; @@ -32,18 +32,18 @@ protected: class FillAlignedRectilinear : public FillRectilinear { public: - Fill* clone() const override { return new FillAlignedRectilinear(*this); }; + Fill* clone() const override { return new FillAlignedRectilinear(*this); } ~FillAlignedRectilinear() override = default; protected: // Always generate infill at the same angle. - virtual float _layer_angle(size_t idx) const { return 0.f; } + virtual float _layer_angle(size_t idx) const override { return 0.f; } }; class FillMonotonic : public FillRectilinear { public: - Fill* clone() const override { return new FillMonotonic(*this); }; + Fill* clone() const override { return new FillMonotonic(*this); } ~FillMonotonic() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; bool no_sort() const override { return true; } @@ -52,7 +52,7 @@ public: class FillGrid : public FillRectilinear { public: - Fill* clone() const override { return new FillGrid(*this); }; + Fill* clone() const override { return new FillGrid(*this); } ~FillGrid() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; @@ -64,7 +64,7 @@ protected: class FillTriangles : public FillRectilinear { public: - Fill* clone() const override { return new FillTriangles(*this); }; + Fill* clone() const override { return new FillTriangles(*this); } ~FillTriangles() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; @@ -76,7 +76,7 @@ protected: class FillStars : public FillRectilinear { public: - Fill* clone() const override { return new FillStars(*this); }; + Fill* clone() const override { return new FillStars(*this); } ~FillStars() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; @@ -88,7 +88,7 @@ protected: class FillCubic : public FillRectilinear { public: - Fill* clone() const override { return new FillCubic(*this); }; + Fill* clone() const override { return new FillCubic(*this); } ~FillCubic() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; @@ -98,6 +98,6 @@ protected: }; -}; // namespace Slic3r +} // namespace Slic3r #endif // slic3r_FillRectilinear_hpp_ diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 7a066f2559..e10b26f383 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -19,9 +19,8 @@ #include #include #include -#include -#include #include +#include #include #include @@ -116,6 +115,7 @@ static constexpr const char* SOURCE_OFFSET_X_KEY = "source_offset_x"; static constexpr const char* SOURCE_OFFSET_Y_KEY = "source_offset_y"; static constexpr const char* SOURCE_OFFSET_Z_KEY = "source_offset_z"; static constexpr const char* SOURCE_IN_INCHES = "source_in_inches"; +static constexpr const char* SOURCE_IN_METERS = "source_in_meters"; const unsigned int VALID_OBJECT_TYPES_COUNT = 1; const char* VALID_OBJECT_TYPES[] = @@ -123,7 +123,6 @@ const char* VALID_OBJECT_TYPES[] = "model" }; -const unsigned int INVALID_OBJECT_TYPES_COUNT = 4; const char* INVALID_OBJECT_TYPES[] = { "solidsupport", @@ -257,9 +256,8 @@ namespace Slic3r { public: void log_errors() { - for (const std::string& error : m_errors) { - printf("%s\n", error.c_str()); - } + for (const std::string& error : m_errors) + BOOST_LOG_TRIVIAL(error) << error; } }; @@ -392,6 +390,10 @@ namespace Slic3r { bool m_check_version; XML_Parser m_xml_parser; + // Error code returned by the application side of the parser. In that case the expat may not reliably deliver the error state + // after returning from XML_Parse() function, thus we keep the error state here. + bool m_parse_error { false }; + std::string m_parse_error_message; Model* m_model; float m_unit_factor; CurrentObject m_curr_object; @@ -417,7 +419,16 @@ namespace Slic3r { private: void _destroy_xml_parser(); - void _stop_xml_parser(); + void _stop_xml_parser(const std::string& msg = std::string()); + + bool parse_error() const { return m_parse_error; } + const char* parse_error_message() const { + return m_parse_error ? + // The error was signalled by the user code, not the expat parser. + (m_parse_error_message.empty() ? "Invalid 3MF format" : m_parse_error_message.c_str()) : + // The error was signalled by the expat parser. + XML_ErrorString(XML_GetErrorCode(m_xml_parser)); + } bool _load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config); bool _extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); @@ -556,10 +567,14 @@ namespace Slic3r { } } - void _3MF_Importer::_stop_xml_parser() + void _3MF_Importer::_stop_xml_parser(const std::string &msg) { - if (m_xml_parser != nullptr) - XML_StopParser(m_xml_parser, false); + assert(! m_parse_error); + assert(m_parse_error_message.empty()); + assert(m_xml_parser != nullptr); + m_parse_error = true; + m_parse_error_message = msg; + XML_StopParser(m_xml_parser, false); } bool _3MF_Importer::_load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config) @@ -659,7 +674,7 @@ namespace Slic3r { // select the geometry associated with the original model object const Geometry* geometry = nullptr; for (const IdToModelObjectMap::value_type& object : m_objects) { - if (static_cast(object.second) == i) { + if (object.second == int(i)) { IdToGeometryMap::const_iterator obj_geometry = m_geometries.find(object.first); if (obj_geometry == m_geometries.end()) { add_error("Unable to find object geometry"); @@ -695,6 +710,10 @@ namespace Slic3r { #endif // ENABLE_RELOAD_FROM_DISK_FOR_3MF for (const IdToModelObjectMap::value_type& object : m_objects) { + if (object.second >= int(m_model->objects.size())) { + add_error("Unable to find object"); + return false; + } ModelObject* model_object = m_model->objects[object.second]; IdToGeometryMap::const_iterator obj_geometry = m_geometries.find(object.first); if (obj_geometry == m_geometries.end()) { @@ -802,12 +821,13 @@ namespace Slic3r { struct CallbackData { XML_Parser& parser; + _3MF_Importer& importer; const mz_zip_archive_file_stat& stat; - CallbackData(XML_Parser& parser, const mz_zip_archive_file_stat& stat) : parser(parser), stat(stat) {} + CallbackData(XML_Parser& parser, _3MF_Importer& importer, const mz_zip_archive_file_stat& stat) : parser(parser), importer(importer), stat(stat) {} }; - CallbackData data(m_xml_parser, stat); + CallbackData data(m_xml_parser, *this, stat); mz_bool res = 0; @@ -815,9 +835,9 @@ namespace Slic3r { { res = mz_zip_reader_extract_file_to_callback(&archive, stat.m_filename, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t { CallbackData* data = (CallbackData*)pOpaque; - if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0)) { + if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->importer.parse_error()) { char error_buf[1024]; - ::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", XML_ErrorString(XML_GetErrorCode(data->parser)), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser)); + ::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", data->importer.parse_error_message(), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser)); throw Slic3r::FileIOError(error_buf); } @@ -1221,7 +1241,8 @@ namespace Slic3r { CustomGCode::Type type; std::string extra; - if (tree.find("type") == tree.not_found()) { + pt::ptree attr_tree = tree.find("")->second; + if (attr_tree.find("type") == attr_tree.not_found()) { // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer // read old data ... std::string gcode = tree.get (".gcode"); @@ -1374,6 +1395,10 @@ namespace Slic3r { { // deletes all non-built or non-instanced objects for (const IdToModelObjectMap::value_type& object : m_objects) { + if (object.second >= int(m_model->objects.size())) { + add_error("Unable to find object"); + return false; + } ModelObject *model_object = m_model->objects[object.second]; if (model_object != nullptr && model_object->instances.size() == 0) m_model->delete_object(model_object); @@ -1834,6 +1859,10 @@ namespace Slic3r { stl_facet& facet = stl.facet_start[i]; for (unsigned int v = 0; v < 3; ++v) { unsigned int tri_id = geometry.triangles[src_start_id + ii + v] * 3; + if (tri_id + 2 >= geometry.vertices.size()) { + add_error("Malformed triangle mesh"); + return false; + } facet.vertex[v] = Vec3f(geometry.vertices[tri_id + 0], geometry.vertices[tri_id + 1], geometry.vertices[tri_id + 2]); } } @@ -1850,10 +1879,6 @@ namespace Slic3r { triangle_mesh.transform(object.instances.front()->get_transformation().get_matrix()); object.instances.front()->set_transformation(Slic3r::Geometry::Transformation()); } - else { - std::cout << "non-single instance !!!\n"; - int a = 0; - } } #endif // ENABLE_RELOAD_FROM_DISK_FOR_3MF @@ -1897,6 +1922,8 @@ namespace Slic3r { volume->source.mesh_offset(2) = ::atof(metadata.value.c_str()); else if (metadata.key == SOURCE_IN_INCHES) volume->source.is_converted_from_inches = metadata.value == "1"; + else if (metadata.key == SOURCE_IN_METERS) + volume->source.is_converted_from_meters = metadata.value == "1"; else volume->config.set_deserialize(metadata.key, metadata.value); } @@ -2414,7 +2441,7 @@ namespace Slic3r { if (!volume->mesh().has_shared_vertices()) throw Slic3r::FileIOError("store_3mf() requires shared vertices"); - volumes_offsets.insert({ volume, Offsets(vertices_count) }).first; + volumes_offsets.insert({ volume, Offsets(vertices_count) }); const indexed_triangle_set &its = volume->mesh().its; if (its.vertices.empty()) { @@ -2806,6 +2833,8 @@ namespace Slic3r { } if (volume->source.is_converted_from_inches) stream << prefix << SOURCE_IN_INCHES << "\" " << VALUE_ATTR << "=\"1\"/>\n"; + if (volume->source.is_converted_from_meters) + stream << prefix << SOURCE_IN_METERS << "\" " << VALUE_ATTR << "=\"1\"/>\n"; } // stores volume's config data diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index 07095d10b9..1c9b6b27d5 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -24,6 +24,7 @@ namespace pt = boost::property_tree; #include #include +#include #include #include "miniz_extension.hpp" @@ -63,23 +64,31 @@ namespace Slic3r struct AMFParserContext { AMFParserContext(XML_Parser parser, DynamicPrintConfig* config, Model* model) : - m_version(0), m_parser(parser), m_model(*model), - m_object(nullptr), - m_volume(nullptr), - m_material(nullptr), - m_instance(nullptr), m_config(config) { m_path.reserve(12); } - void stop() + void stop(const std::string &msg = std::string()) { + assert(! m_error); + assert(m_error_message.empty()); + m_error = true; + m_error_message = msg; XML_StopParser(m_parser, 0); } + bool error() const { return m_error; } + const char* error_message() const { + return m_error ? + // The error was signalled by the user code, not the expat parser. + (m_error_message.empty() ? "Invalid AMF format" : m_error_message.c_str()) : + // The error was signalled by the expat parser. + XML_ErrorString(XML_GetErrorCode(m_parser)); + } + void startElement(const char *name, const char **atts); void endElement(const char *name); void endDocument(); @@ -217,33 +226,37 @@ struct AMFParserContext }; // Version of the amf file - unsigned int m_version; + unsigned int m_version { 0 }; // Current Expat XML parser instance. XML_Parser m_parser; + // Error code returned by the application side of the parser. In that case the expat may not reliably deliver the error state + // after returning from XML_Parse() function, thus we keep the error state here. + bool m_error { false }; + std::string m_error_message; // Model to receive objects extracted from an AMF file. Model &m_model; // Current parsing path in the XML file. std::vector m_path; // Current object allocated for an amf/object XML subtree. - ModelObject *m_object; + ModelObject *m_object { nullptr }; // Map from obect name to object idx & instances. std::map m_object_instances_map; // Vertices parsed for the current m_object. std::vector m_object_vertices; // Current volume allocated for an amf/object/mesh/volume subtree. - ModelVolume *m_volume; + ModelVolume *m_volume { nullptr }; // Faces collected for the current m_volume. std::vector m_volume_facets; // Transformation matrix of a volume mesh from its coordinate system to Object's coordinate system. Transform3d m_volume_transform; // Current material allocated for an amf/metadata subtree. - ModelMaterial *m_material; + ModelMaterial *m_material { nullptr }; // Current instance allocated for an amf/constellation/instance subtree. - Instance *m_instance; + Instance *m_instance { nullptr }; // Generic string buffer for vertices, face indices, metadata etc. std::string m_value[5]; // Pointer to config to update if config data are stored inside the amf file - DynamicPrintConfig *m_config; + DynamicPrintConfig *m_config { nullptr }; private: AMFParserContext& operator=(AMFParserContext&); @@ -591,9 +604,9 @@ void AMFParserContext::endElement(const char * /* name */) // Faces of the current volume: case NODE_TYPE_TRIANGLE: assert(m_object && m_volume); - m_volume_facets.push_back(atoi(m_value[0].c_str())); - m_volume_facets.push_back(atoi(m_value[1].c_str())); - m_volume_facets.push_back(atoi(m_value[2].c_str())); + m_volume_facets.emplace_back(atoi(m_value[0].c_str())); + m_volume_facets.emplace_back(atoi(m_value[1].c_str())); + m_volume_facets.emplace_back(atoi(m_value[2].c_str())); m_value[0].clear(); m_value[1].clear(); m_value[2].clear(); @@ -616,6 +629,10 @@ void AMFParserContext::endElement(const char * /* name */) for (unsigned int v = 0; v < 3; ++v) { unsigned int tri_id = m_volume_facets[i++] * 3; + if (tri_id < 0 || tri_id + 2 >= m_object_vertices.size()) { + this->stop("Malformed triangle mesh"); + return; + } facet.vertex[v] = Vec3f(m_object_vertices[tri_id + 0], m_object_vertices[tri_id + 1], m_object_vertices[tri_id + 2]); } } @@ -781,6 +798,9 @@ void AMFParserContext::endElement(const char * /* name */) else if (strcmp(opt_key, "source_in_inches") == 0) { m_volume->source.is_converted_from_inches = m_value[1] == "1"; } + else if (strcmp(opt_key, "source_in_meters") == 0) { + m_volume->source.is_converted_from_meters = m_value[1] == "1"; + } } } else if (m_path.size() == 3) { if (m_path[1] == NODE_TYPE_MATERIAL) { @@ -811,7 +831,7 @@ void AMFParserContext::endDocument() { for (const auto &object : m_object_instances_map) { if (object.second.idx == -1) { - printf("Undefined object %s referenced in constellation\n", object.first.c_str()); + BOOST_LOG_TRIVIAL(error) << "Undefined object " << object.first.c_str() << " referenced in constellation"; continue; } for (const Instance &instance : object.second.instances) @@ -834,13 +854,13 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model) XML_Parser parser = XML_ParserCreate(nullptr); // encoding if (!parser) { - printf("Couldn't allocate memory for parser\n"); + BOOST_LOG_TRIVIAL(error) << "Couldn't allocate memory for parser"; return false; } FILE *pFile = boost::nowide::fopen(path, "rt"); if (pFile == nullptr) { - printf("Cannot open file %s\n", path); + BOOST_LOG_TRIVIAL(error) << "Cannot open file " << path; return false; } @@ -854,14 +874,12 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model) for (;;) { int len = (int)fread(buff, 1, 8192, pFile); if (ferror(pFile)) { - printf("AMF parser: Read error\n"); + BOOST_LOG_TRIVIAL(error) << "AMF parser: Read error"; break; } int done = feof(pFile); - if (XML_Parse(parser, buff, len, done) == XML_STATUS_ERROR) { - printf("AMF parser: Parse error at line %d:\n%s\n", - (int)XML_GetCurrentLineNumber(parser), - XML_ErrorString(XML_GetErrorCode(parser))); + if (XML_Parse(parser, buff, len, done) == XML_STATUS_ERROR || ctx.error()) { + BOOST_LOG_TRIVIAL(error) << "AMF parser: Parse error at line " << int(XML_GetCurrentLineNumber(parser)) << ": " << ctx.error_message(); break; } if (done) { @@ -892,14 +910,14 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi { if (stat.m_uncomp_size == 0) { - printf("Found invalid size\n"); + BOOST_LOG_TRIVIAL(error) << "Found invalid size"; close_zip_reader(&archive); return false; } XML_Parser parser = XML_ParserCreate(nullptr); // encoding if (!parser) { - printf("Couldn't allocate memory for parser\n"); + BOOST_LOG_TRIVIAL(error) << "Couldn't allocate memory for parser"; close_zip_reader(&archive); return false; } @@ -912,12 +930,13 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi struct CallbackData { XML_Parser& parser; + AMFParserContext& ctx; const mz_zip_archive_file_stat& stat; - CallbackData(XML_Parser& parser, const mz_zip_archive_file_stat& stat) : parser(parser), stat(stat) {} + CallbackData(XML_Parser& parser, AMFParserContext& ctx, const mz_zip_archive_file_stat& stat) : parser(parser), ctx(ctx), stat(stat) {} }; - CallbackData data(parser, stat); + CallbackData data(parser, ctx, stat); mz_bool res = 0; @@ -925,10 +944,10 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi { res = mz_zip_reader_extract_file_to_callback(&archive, stat.m_filename, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t { CallbackData* data = (CallbackData*)pOpaque; - if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0)) + if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->ctx.error()) { char error_buf[1024]; - ::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", XML_ErrorString(XML_GetErrorCode(data->parser)), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser)); + ::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", data->ctx.error_message(), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser)); throw Slic3r::FileIOError(error_buf); } @@ -937,14 +956,14 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi } catch (std::exception& e) { - printf("%s\n", e.what()); + BOOST_LOG_TRIVIAL(error) << "Error reading AMF file: " << e.what(); close_zip_reader(&archive); return false; } if (res == 0) { - printf("Error while extracting model data from zip archive"); + BOOST_LOG_TRIVIAL(error) << "Error while extracting model data from zip archive"; close_zip_reader(&archive); return false; } @@ -973,7 +992,7 @@ bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model if (!open_zip_reader(&archive, path)) { - printf("Unable to init zip reader\n"); + BOOST_LOG_TRIVIAL(error) << "Unable to init zip reader"; return false; } @@ -992,7 +1011,7 @@ bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model if (!extract_model_from_archive(archive, stat, config, model, check_version)) { close_zip_reader(&archive); - printf("Archive does not contain a valid model"); + BOOST_LOG_TRIVIAL(error) << "Archive does not contain a valid model"; return false; } } @@ -1216,6 +1235,8 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config, } if (volume->source.is_converted_from_inches) stream << " 1\n"; + if (volume->source.is_converted_from_meters) + stream << " 1\n"; stream << std::setprecision(std::numeric_limits::max_digits10); const indexed_triangle_set &its = volume->mesh().its; for (size_t i = 0; i < its.indices.size(); ++i) { @@ -1231,7 +1252,7 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config, if (!object->instances.empty()) { for (ModelInstance *instance : object->instances) { char buf[512]; - sprintf(buf, + ::sprintf(buf, " \n" " %lf\n" " %lf\n" diff --git a/src/libslic3r/Format/PRUS.cpp b/src/libslic3r/Format/PRUS.cpp index e2c38d9576..abf30a53bf 100644 --- a/src/libslic3r/Format/PRUS.cpp +++ b/src/libslic3r/Format/PRUS.cpp @@ -2,8 +2,6 @@ #include #include -#include -#include #include "miniz_extension.hpp" diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 87bfe30654..f3bffe3316 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -170,7 +170,11 @@ namespace Slic3r { // subdivide the retraction in segments if (!wipe_path.empty()) { // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Start) + "\n"; +#else gcode += ";" + GCodeProcessor::Wipe_Start_Tag + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE for (const Line& line : wipe_path.lines()) { double segment_length = line.length(); /* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one @@ -186,7 +190,11 @@ namespace Slic3r { ); } // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_End) + "\n"; +#else gcode += ";" + GCodeProcessor::Wipe_End_Tag + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gcodegen.set_last_pos(wipe_path.points.back()); } @@ -478,7 +486,7 @@ std::vector GCode::collect_layers_to_print(const PrintObjec //FIXME should we use the printing extruders instead? double gap_over_supports = object.config().support_material_contact_distance; // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports. - assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers); + assert(!object.has_support() || gap_over_supports != 0. || object.config().support_material_synchronize_layers); if (gap_over_supports != 0.) { gap_over_supports = std::max(0., gap_over_supports); // Not a soluble support, @@ -610,6 +618,59 @@ namespace DoExport { print_statistics.estimated_silent_print_time = processor.is_stealth_time_estimator_enabled() ? get_time_dhms(result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].time) : "N/A"; } + +#if ENABLE_VALIDATE_CUSTOM_GCODE + // if any reserved keyword is found, returns a std::vector containing the first MAX_COUNT keywords found + // into pairs containing: + // first: source + // second: keyword + // to be shown in the warning notification + // The returned vector is empty if no keyword has been found + static std::vector> validate_custom_gcode(const Print& print) { + static const unsigned int MAX_TAGS_COUNT = 5; + std::vector> ret; + + auto check = [&ret](const std::string& source, const std::string& gcode) { + std::vector tags; + if (GCodeProcessor::contains_reserved_tags(gcode, MAX_TAGS_COUNT, tags)) { + if (!tags.empty()) { + size_t i = 0; + while (ret.size() < MAX_TAGS_COUNT && i < tags.size()) { + ret.push_back({ source, tags[i] }); + ++i; + } + } + } + }; + + const GCodeConfig& config = print.config(); + check(_(L("Start G-code")), config.start_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("End G-code")), config.end_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Before layer change G-code")), config.before_layer_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("After layer change G-code")), config.layer_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Tool change G-code")), config.toolchange_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Between objects G-code (for sequential printing)")), config.between_objects_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Color Change G-code")), config.color_change_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Pause Print G-code")), config.pause_print_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) check(_(L("Template Custom G-code")), config.template_custom_gcode.value); + if (ret.size() < MAX_TAGS_COUNT) { + for (const std::string& value : config.start_filament_gcode.values) { + check(_(L("Filament Start G-code")), value); + if (ret.size() == MAX_TAGS_COUNT) + break; + } + } + if (ret.size() < MAX_TAGS_COUNT) { + for (const std::string& value : config.end_filament_gcode.values) { + check(_(L("Filament End G-code")), value); + if (ret.size() == MAX_TAGS_COUNT) + break; + } + } + + return ret; + } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE } // namespace DoExport void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) @@ -622,6 +683,22 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re print->set_started(psGCodeExport); +#if ENABLE_VALIDATE_CUSTOM_GCODE + // check if any custom gcode contains keywords used by the gcode processor to + // produce time estimation and gcode toolpaths + std::vector> validation_res = DoExport::validate_custom_gcode(*print); + if (!validation_res.empty()) { + std::string reports; + for (const auto& [source, keyword] : validation_res) { + reports += source + ": \"" + keyword + "\"\n"; + } + print->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, + _(L("Found reserved keyword(s) into custom g-code:")) + "\n" + + reports + + _(L("This may cause problems in g-code visualization and printing time estimation."))); + } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + BOOST_LOG_TRIVIAL(info) << "Exporting G-code..." << log_memory_info(); // Remove the old g-code if it exists. @@ -851,7 +928,7 @@ namespace DoExport { double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? wipe_tower_data.used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter double filament_weight = extruded_volume * extruder.filament_density() * 0.001; double filament_cost = filament_weight * extruder.filament_cost() * 0.001; - auto append = [&extruder, &extruders](std::pair &dst, const char *tmpl, double value) { + auto append = [&extruder](std::pair &dst, const char *tmpl, double value) { while (dst.second < extruder.id()) { // Fill in the non-printing extruders with zeros. dst.first += (dst.second > 0) ? ", 0" : "0"; @@ -891,6 +968,7 @@ namespace DoExport { } } +#if 0 // Sort the PrintObjects by their increasing Z, likely useful for avoiding colisions on Deltas during sequential prints. static inline std::vector sort_object_instances_by_max_z(const Print &print) { @@ -903,6 +981,7 @@ static inline std::vector sort_object_instances_by_max_z(c instances.emplace_back(&object->instances()[i]); return instances; } +#endif // Produce a vector of PrintObjects in the order of their respective ModelObjects in print.model(). std::vector sort_object_instances_by_model_order(const Print& print) @@ -937,14 +1016,9 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu m_last_height = 0.f; m_last_layer_z = 0.f; m_max_layer_z = 0.f; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE m_last_width = 0.f; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm = 0.; -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - m_last_width = 0.f; -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING // How many times will be change_layer() called? @@ -1037,7 +1111,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tags for time estimators if (print.config().remaining_times.value) +#if ENABLE_VALIDATE_CUSTOM_GCODE + _write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::First_Line_M73_Placeholder).c_str()); +#else _writeln(file, GCodeProcessor::First_Line_M73_Placeholder_Tag); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE // Prepare the helper object for replacing placeholders in custom G-code and output filename. m_placeholder_parser = print.placeholder_parser(); @@ -1143,7 +1221,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); // adds tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + _write_format(file, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); +#else _write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE // Write the custom start G-code _writeln(file, start_gcode); @@ -1222,7 +1304,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu for (const LayerToPrint <p : layers_to_print) { std::vector lrs; lrs.emplace_back(std::move(ltp)); - this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), nullptr, *print_object_instance_sequential_active - object.instances().data()); + this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), <p == &layers_to_print.back(), + nullptr, *print_object_instance_sequential_active - object.instances().data()); print.throw_if_canceled(); } #ifdef HAS_PRESSURE_EQUALIZER @@ -1286,7 +1369,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu const LayerTools &layer_tools = tool_ordering.tools_for_layer(layer.first); if (m_wipe_tower && layer_tools.has_wipe_tower) m_wipe_tower->next_layer(); - this->process_layer(file, print, layer.second, layer_tools, &print_object_instances_ordering, size_t(-1)); + this->process_layer(file, print, layer.second, layer_tools, &layer == &layers_to_print.back(), &print_object_instances_ordering, size_t(-1)); print.throw_if_canceled(); } #ifdef HAS_PRESSURE_EQUALIZER @@ -1303,7 +1386,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write(file, m_writer.set_fan(false)); // adds tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + _write_format(file, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); +#else _write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE // Process filament-specific gcode in extruder order. { @@ -1330,7 +1417,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tags for time estimators if (print.config().remaining_times.value) +#if ENABLE_VALIDATE_CUSTOM_GCODE + _write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str()); +#else _writeln(file, GCodeProcessor::Last_Line_M73_Placeholder_Tag); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE print.throw_if_canceled(); @@ -1346,7 +1437,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write_format(file, "; total filament cost = %.2lf\n", print.m_print_statistics.total_cost); if (print.m_print_statistics.total_toolchanges > 0) _write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges); +#if ENABLE_VALIDATE_CUSTOM_GCODE + _write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str()); +#else _writeln(file, GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE // Append full config. _write(file, "\n"); @@ -1633,7 +1728,11 @@ namespace ProcessLayer assert(m600_extruder_before_layer >= 0); // Color Change or Tool Change as Color Change. // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; +#else gcode += ";" + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE if (!single_extruder_printer && m600_extruder_before_layer >= 0 && first_extruder_id != (unsigned)m600_extruder_before_layer // && !MMU1 @@ -1648,21 +1747,27 @@ namespace ProcessLayer gcode += "\n"; } } - else - { + else { if (gcode_type == CustomGCode::PausePrint) // Pause print { // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Pause_Print) + "\n"; +#else gcode += ";" + GCodeProcessor::Pause_Print_Tag + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE //! FIXME_in_fw show message during print pause if (!pause_print_msg.empty()) gcode += "M117 " + pause_print_msg + "\n"; gcode += config.pause_print_gcode; } - else - { + else { // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Custom_Code) + "\n"; +#else gcode += ";" + GCodeProcessor::Custom_Code_Tag + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE if (gcode_type == CustomGCode::Template) // Template Cistom Gcode gcode += config.template_custom_gcode; else // custom Gcode @@ -1755,6 +1860,7 @@ void GCode::process_layer( // Set of object & print layers of the same PrintObject and with the same print_z. const std::vector &layers, const LayerTools &layer_tools, + const bool last_layer, // Pairs of PrintObject index and its instance index. const std::vector *ordering, // If set to size_t(-1), then print all copies of all objects. @@ -1790,7 +1896,7 @@ void GCode::process_layer( // Just a reminder: A spiral vase mode is allowed for a single object, single material print only. m_enable_loop_clipping = true; if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr) { - bool enable = (layer.id() > 0 || print.config().brim_width.value == 0.) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt()); + bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt()); if (enable) { for (const LayerRegion *layer_region : layer.regions()) if (size_t(layer_region->region()->config().bottom_solid_layers.value) > layer.id() || @@ -1808,14 +1914,22 @@ void GCode::process_layer( std::string gcode; // add tag for processor +#if ENABLE_VALIDATE_CUSTOM_GCODE + gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n"; +#else gcode += ";" + GCodeProcessor::Layer_Change_Tag + "\n"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE // export layer z char buf[64]; sprintf(buf, ";Z:%g\n", print_z); gcode += buf; // export layer height float height = first_layer ? static_cast(print_z) : static_cast(print_z) - m_last_layer_z; +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), height); +#else sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), height); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gcode += buf; // update caches m_last_layer_z = static_cast(print_z); @@ -2138,11 +2252,13 @@ void GCode::process_layer( // we apply spiral vase at this stage because it requires a full layer. // Just a reminder: A spiral vase mode is allowed for a single object per layer, single material print only. if (m_spiral_vase) - gcode = m_spiral_vase->process_layer(gcode); + gcode = m_spiral_vase->process_layer(std::move(gcode)); // Apply cooling logic; this may alter speeds. if (m_cooling_buffer) - gcode = m_cooling_buffer->process_layer(gcode, layer.id()); + gcode = m_cooling_buffer->process_layer(std::move(gcode), layer.id(), + // Flush the cooling buffer at each object layer or possibly at the last layer, even if it contains just supports (This should not happen). + object_layer || last_layer); #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; @@ -2154,7 +2270,7 @@ void GCode::process_layer( _write(file, gcode); BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << - log_memory_info(); + log_memory_info(); } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2457,10 +2573,11 @@ std::string GCode::extrude_infill(const Print &print, const std::vectorextrude_path(*path, label, speed); else { const ExtrusionMultiPath *multipath = dynamic_cast(ee); - assert(multipath != nullptr); if (multipath) gcode += this->extrude_multi_path(*multipath, label, speed); + else { + const ExtrusionEntityCollection *eec = dynamic_cast(ee); + assert(eec); + if (eec) + gcode += this->extrude_support(*eec); + } } } } @@ -2634,17 +2756,23 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (path.role() != m_last_processor_extrusion_role) { m_last_processor_extrusion_role = path.role(); +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str()); +#else sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str()); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gcode += buf; } -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE if (last_was_wipe_tower || m_last_width != path.width) { m_last_width = path.width; +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width).c_str(), m_last_width); +#else sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gcode += buf; } -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { @@ -2652,19 +2780,15 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; } - -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - if (last_was_wipe_tower || m_last_width != path.width) { - m_last_width = path.width; - sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); - gcode += buf; - } -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) { m_last_height = path.height; +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height); +#else sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gcode += buf; } @@ -2735,10 +2859,10 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string Point last_post_before_retract = this->last_pos(); gcode += this->retract(); // When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters. - // Because of it, it is necessary to call avoid crossing perimeters for the path between previous last_post and last_post after calling retraction() + // Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction() + // FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations. if (last_post_before_retract != this->last_pos() && m_config.avoid_crossing_perimeters) { - Polyline retract_travel = m_avoid_crossing_perimeters.travel_to(*this, last_post_before_retract); - append(retract_travel.points, travel.points); + Polyline retract_travel = m_avoid_crossing_perimeters.travel_to(*this, point); travel = std::move(retract_travel); } } else diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 458eae80a9..51621ed40b 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -33,7 +33,7 @@ class GCode; namespace { struct Item; } struct PrintInstance; -using PrintObjectPtrs = std::vector; +class ConstPrintObjectPtrsAdaptor; class OozePrevention { public: @@ -131,14 +131,9 @@ public: m_volumetric_speed(0), m_last_pos_defined(false), m_last_extrusion_role(erNone), -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE m_last_width(0.0f), -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm(0.0), -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - m_last_width(0.0f), -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING m_brim_done(false), m_second_layer_things_done(false), @@ -201,6 +196,7 @@ private: // Set of object & print layers of the same PrintObject and with the same print_z. const std::vector &layers, const LayerTools &layer_tools, + const bool last_layer, // Pairs of PrintObject index and its instance index. const std::vector *ordering, // If set to size_t(-1), then print all copies of all objects. @@ -332,14 +328,9 @@ private: float m_last_height{ 0.0f }; float m_last_layer_z{ 0.0f }; float m_max_layer_z{ 0.0f }; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE float m_last_width{ 0.0f }; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING double m_last_mm3_per_mm; -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - float m_last_width{ 0.0f }; -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING Point m_last_pos; diff --git a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp index f1d8953724..e00284fe1e 100644 --- a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp +++ b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp @@ -283,8 +283,10 @@ static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &bo AllIntersectionsVisitor visitor(edge_grid, intersections, Line(start, end)); edge_grid.visit_cells_intersecting_line(start, end, visitor); Vec2d dir = (end - start).cast(); - for (Intersection &intersection : intersections) - intersection.distance = boundary.boundaries_params[intersection.border_idx][intersection.line_idx]; + for (Intersection &intersection : intersections) { + float dist_from_line_begin = (intersection.point - boundary.boundaries[intersection.border_idx][intersection.line_idx]).cast().norm(); + intersection.distance = boundary.boundaries_params[intersection.border_idx][intersection.line_idx] + dist_from_line_begin; + } std::sort(intersections.begin(), intersections.end(), [dir](const auto &l, const auto &r) { return (r.point - l.point).template cast().dot(dir) > 0.; }); } @@ -568,7 +570,7 @@ static void precompute_polygon_distances(const Polygon &polygon, std::vector() - polygon[point_idx - 1].cast()).norm(); - polygon_distances_out.back() = polygon_distances_out[polygon.size() - 1] + (polygon.last_point().cast() - polygon.first_point().cast()).norm(); + polygon_distances_out.back() = polygon_distances_out[polygon.size() - 1] + (polygon.points.back().cast() - polygon.points.front().cast()).norm(); } static void precompute_expolygon_distances(const ExPolygon &ex_polygon, std::vector> &expolygon_distances_out) @@ -596,7 +598,7 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, { struct Visitor { Visitor(const EdgeGrid::Grid &grid, const size_t contour_idx, const std::vector &polygon_distances, double dist_same_contour_accept, double dist_same_contour_reject) : - grid(grid), idx_contour(contour_idx), contour(*grid.contours()[contour_idx]), boundary_parameters(polygon_distances), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} + grid(grid), idx_contour(contour_idx), contour(grid.contours()[contour_idx]), boundary_parameters(polygon_distances), dist_same_contour_accept(dist_same_contour_accept), dist_same_contour_reject(dist_same_contour_reject) {} void init(const Points &contour, const Point &apoint) { @@ -630,12 +632,12 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, // Complex case: The closest segment originates from the same contour as the starting point. // Reject the closest point if its distance along the contour is reasonable compared to the current contour bisector // (this->pt, foot). - const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; - double param_lo = boundary_parameters[this->idx_point]; - double param_hi = t * sqrt(l2); - double param_end = boundary_parameters.back(); + const EdgeGrid::Contour &contour = grid.contours()[it_contour_and_segment->first]; + double param_lo = boundary_parameters[this->idx_point]; + double param_hi = t * sqrt(l2); + double param_end = boundary_parameters.back(); const size_t ipt = it_contour_and_segment->second; - if (ipt + 1 < ipts.size()) + if (contour.begin() + ipt + 1 < contour.end()) param_hi += boundary_parameters[ipt > 0 ? ipt - 1 : 0]; if (param_lo > param_hi) std::swap(param_lo, param_hi); @@ -649,9 +651,9 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, // longer than the bisector. That is, the path shall not bulge away from the bisector too much. // Bulge is estimated by 0.6 of the circle circumference drawn around the bisector. // Test whether the contour is convex or concave. - bool inside = (t == 0.) ? this->inside_corner(ipts, ipt, this->point) : - (t == 1.) ? this->inside_corner(ipts, ipt + 1 == ipts.size() ? 0 : ipt + 1, this->point) : - this->left_of_segment(ipts, ipt, this->point); + bool inside = (t == 0.) ? this->inside_corner(contour, ipt, this->point) : + (t == 1.) ? this->inside_corner(contour, contour.segment_idx_next(ipt), this->point) : + this->left_of_segment(contour, ipt, this->point); accept = inside && dist_along_contour > 0.6 * M_PI * dist; } } @@ -668,7 +670,7 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, const EdgeGrid::Grid &grid; const size_t idx_contour; - const Points &contour; + const EdgeGrid::Contour &contour; const std::vector &boundary_parameters; const double dist_same_contour_accept; @@ -691,25 +693,27 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, return Vec2d(-v1.y() - v2.y(), v1.x() + v2.x()); } - static bool inside_corner(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) + static bool inside_corner(const EdgeGrid::Contour &contour, size_t i, const Point &pt_oposite) { const Vec2d pt = pt_oposite.cast(); - size_t iprev = prev_idx_modulo(i, contour); - size_t inext = next_idx_modulo(i, contour); - Vec2d v1 = (contour[i] - contour[iprev]).cast(); - Vec2d v2 = (contour[inext] - contour[i]).cast(); - bool left_of_v1 = cross2(v1, pt - contour[iprev].cast()) > 0.; - bool left_of_v2 = cross2(v2, pt - contour[i].cast()) > 0.; + const Point &pt_prev = contour.segment_prev(i); + const Point &pt_this = contour.segment_start(i); + const Point &pt_next = contour.segment_end(i); + Vec2d v1 = (pt_this - pt_prev).cast(); + Vec2d v2 = (pt_next - pt_this).cast(); + bool left_of_v1 = cross2(v1, pt - pt_prev.cast()) > 0.; + bool left_of_v2 = cross2(v2, pt - pt_this.cast()) > 0.; return cross2(v1, v2) > 0 ? left_of_v1 && left_of_v2 : // convex corner left_of_v1 || left_of_v2; // concave corner } - static bool left_of_segment(const Slic3r::Points &contour, size_t i, const Point &pt_oposite) + static bool left_of_segment(const EdgeGrid::Contour &contour, size_t i, const Point &pt_oposite) { - const Vec2d pt = pt_oposite.cast(); - size_t inext = next_idx_modulo(i, contour); - Vec2d v = (contour[inext] - contour[i]).cast(); - return cross2(v, pt - contour[i].cast()) > 0.; + const Vec2d pt = pt_oposite.cast(); + const Point &pt_this = contour.segment_start(i); + const Point &pt_next = contour.segment_end(i); + Vec2d v = (pt_next - pt_this).cast(); + return cross2(v, pt - pt_this.cast()) > 0.; } } visitor(grid, contour_idx, poly_distances, 0.5 * compensation * M_PI, search_radius); @@ -727,10 +731,11 @@ static std::vector contour_distance(const EdgeGrid::Grid &grid, // Polygon offset which ensures that if a polygon breaks up into several separate parts, the original polygon will be used in these places. // ExPolygons are handled one by one so returned ExPolygons could intersect. -static ExPolygons inner_offset(const ExPolygons &ex_polygons, double offset, double min_contour_width = scale_(0.001)) +static ExPolygons inner_offset(const ExPolygons &ex_polygons, double offset) { - double search_radius = 2. * (offset + min_contour_width); - ExPolygons ex_poly_result = ex_polygons; + double min_contour_width = 2. * offset + SCALED_EPSILON; + double search_radius = 2. * (offset + min_contour_width); + ExPolygons ex_poly_result = ex_polygons; resample_expolygons(ex_poly_result, offset / 2); for (ExPolygon &ex_poly : ex_poly_result) { diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 07ab197f27..7f48aae808 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -279,11 +279,24 @@ finished: return new_feedrate; } -std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id) +std::string CoolingBuffer::process_layer(std::string &&gcode, size_t layer_id, bool flush) { - std::vector per_extruder_adjustments = this->parse_layer_gcode(gcode, m_current_pos); - float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments); - return this->apply_layer_cooldown(gcode, layer_id, layer_time_stretched, per_extruder_adjustments); + // Cache the input G-code. + if (m_gcode.empty()) + m_gcode = std::move(gcode); + else + m_gcode += gcode; + + std::string out; + if (flush) { + // This is either an object layer or the very last print layer. Calculate cool down over the collected support layers + // and one object layer. + std::vector per_extruder_adjustments = this->parse_layer_gcode(m_gcode, m_current_pos); + float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments); + out = this->apply_layer_cooldown(m_gcode, layer_id, layer_time_stretched, per_extruder_adjustments); + m_gcode.clear(); + } + return out; } // Parse the layer G-code for the moves, which could be adjusted. @@ -683,6 +696,13 @@ std::string CoolingBuffer::apply_layer_cooldown( int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed); int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0; int disable_fan_first_layers = EXTRUDER_CONFIG(disable_fan_first_layers); + // Is the fan speed ramp enabled? + int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); + if (disable_fan_first_layers <= 0 && full_fan_speed_layer > 0) { + // When ramping up fan speed from disable_fan_first_layers to full_fan_speed_layer, force disable_fan_first_layers above zero, + // so there will be a zero fan speed at least at the 1st layer. + disable_fan_first_layers = 1; + } if (int(layer_id) >= disable_fan_first_layers) { int max_fan_speed = EXTRUDER_CONFIG(max_fan_speed); float slowdown_below_layer_time = float(EXTRUDER_CONFIG(slowdown_below_layer_time)); @@ -699,11 +719,6 @@ std::string CoolingBuffer::apply_layer_cooldown( } } bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed); - // Is the fan speed ramp enabled? - int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); - // When ramping up fan speed from disable_fan_first_layers to full_fan_speed_layer, force disable_fan_first_layers above zero, - // so there will be a zero fan speed at least at the 1st layer. - disable_fan_first_layers = std::max(disable_fan_first_layers, 1); if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) { // Ramp up the fan speed from disable_fan_first_layers to full_fan_speed_layer. float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers); diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp index b0c35ecc5c..0932d62d37 100644 --- a/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/src/libslic3r/GCode/CoolingBuffer.hpp @@ -25,7 +25,7 @@ public: CoolingBuffer(GCode &gcodegen); void reset(); void set_current_extruder(unsigned int extruder_id) { m_current_extruder = extruder_id; } - std::string process_layer(const std::string &gcode, size_t layer_id); + std::string process_layer(std::string &&gcode, size_t layer_id, bool flush); GCode* gcodegen() { return &m_gcodegen; } private: @@ -37,6 +37,7 @@ private: std::string apply_layer_cooldown(const std::string &gcode, size_t layer_id, float layer_time, std::vector &per_extruder_adjustments); GCode& m_gcodegen; + // G-code snippet cached for the support layers preceding an object layer. std::string m_gcode; // Internal data. // X,Y,Z,E,F diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 52861afba0..c4b2a35183 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -19,15 +19,31 @@ static const float INCHES_TO_MM = 25.4f; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; - static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { +#if ENABLE_VALIDATE_CUSTOM_GCODE +const std::vector GCodeProcessor::Reserved_Tags = { + "TYPE:", + "WIPE_START", + "WIPE_END", + "HEIGHT:", + "WIDTH:", + "LAYER_CHANGE", + "COLOR_CHANGE", + "PAUSE_PRINT", + "CUSTOM_GCODE", + "_GP_FIRST_LINE_M73_PLACEHOLDER", + "_GP_LAST_LINE_M73_PLACEHOLDER", + "_GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER" +}; +#else const std::string GCodeProcessor::Extrusion_Role_Tag = "TYPE:"; const std::string GCodeProcessor::Wipe_Start_Tag = "WIPE_START"; const std::string GCodeProcessor::Wipe_End_Tag = "WIPE_END"; const std::string GCodeProcessor::Height_Tag = "HEIGHT:"; +const std::string GCodeProcessor::Width_Tag = "WIDTH:"; const std::string GCodeProcessor::Layer_Change_Tag = "LAYER_CHANGE"; const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; @@ -36,17 +52,12 @@ const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_GCODE"; const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _GP_FIRST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE const float GCodeProcessor::Wipe_Width = 0.05f; const float GCodeProcessor::Wipe_Height = 0.05f; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE -const std::string GCodeProcessor::Width_Tag = "WIDTH:"; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE -const std::string GCodeProcessor::Width_Tag = "WIDTH:"; -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "MM3_PER_MM:"; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING @@ -324,7 +335,11 @@ void GCodeProcessor::TimeProcessor::reset() machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].enabled = true; } +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER +void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector& moves) +#else void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER { boost::nowide::ifstream in(filename); if (!in.good()) @@ -362,11 +377,33 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) // replace placeholder lines with the proper final value auto process_placeholders = [&](const std::string& gcode_line) { +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + unsigned int extra_lines_count = 0; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + // remove trailing '\n' std::string line = gcode_line.substr(0, gcode_line.length() - 1); std::string ret; - +#if ENABLE_VALIDATE_CUSTOM_GCODE + if (line.length() > 1) { + line = line.substr(1); + if (export_remaining_time_enabled && + (line == reserved_tag(ETags::First_Line_M73_Placeholder) || line == reserved_tag(ETags::Last_Line_M73_Placeholder))) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + if (machine.enabled) { + ret += format_line_M73(machine.line_m73_mask.c_str(), + (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100, + (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + ++extra_lines_count; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + } + } + } + else if (line == reserved_tag(ETags::Estimated_Printing_Time_Placeholder)) { +#else if (export_remaining_time_enabled && (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag)) { for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; @@ -378,20 +415,28 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) } } else if (line == Estimated_Printing_Time_Placeholder_Tag) { - for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { - const TimeMachine& machine = machines[i]; - PrintEstimatedTimeStatistics::ETimeMode mode = static_cast(i); - if (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal || machine.enabled) { - char buf[128]; - sprintf(buf, "; estimated printing time (%s mode) = %s\n", - (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent", - get_time_dhms(machine.time).c_str()); - ret += buf; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + PrintEstimatedTimeStatistics::ETimeMode mode = static_cast(i); + if (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal || machine.enabled) { + char buf[128]; + sprintf(buf, "; estimated printing time (%s mode) = %s\n", + (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent", + get_time_dhms(machine.time).c_str()); + ret += buf; + } } } +#if ENABLE_VALIDATE_CUSTOM_GCODE } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + return std::tuple(!ret.empty(), ret.empty() ? gcode_line : ret, (extra_lines_count == 0) ? extra_lines_count : extra_lines_count - 1); +#else return std::make_pair(!ret.empty(), ret.empty() ? gcode_line : ret); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER }; // check for temporary lines @@ -412,8 +457,12 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) auto g1_times_cache_it = Slic3r::reserve_vector::const_iterator>(machines.size()); for (const auto& machine : machines) g1_times_cache_it.emplace_back(machine.g1_times_cache.begin()); + // add lines M73 to exported gcode auto process_line_G1 = [&]() { +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + unsigned int exported_lines_count = 0; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER if (export_remaining_time_enabled) { for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; @@ -430,11 +479,17 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) export_line += format_line_M73(machine.line_m73_mask.c_str(), to_export.first, to_export.second); last_exported[i] = to_export; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + ++exported_lines_count; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER } } } } } +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + return exported_lines_count; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER }; // helper function to write to disk @@ -449,15 +504,30 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) export_line.clear(); }; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + unsigned int line_id = 0; + std::vector> offsets; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + while (std::getline(in, gcode_line)) { if (!in.good()) { fclose(out); throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n")); } +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + ++line_id; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + gcode_line += "\n"; // replace placeholder lines +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + auto [processed, result, lines_added_count] = process_placeholders(gcode_line); + if (processed && lines_added_count > 0) + offsets.push_back({ line_id, lines_added_count }); +#else auto [processed, result] = process_placeholders(gcode_line); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER gcode_line = result; if (!processed) { // remove temporary lines @@ -468,8 +538,15 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) parser.parse_line(gcode_line, [&](GCodeReader& reader, const GCodeReader::GCodeLine& line) { if (line.cmd_is("G1")) { +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + unsigned int extra_lines_count = process_line_G1(); + ++g1_lines_counter; + if (extra_lines_count > 0) + offsets.push_back({ line_id, extra_lines_count }); +#else process_line_G1(); ++g1_lines_counter; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER } }); } @@ -485,6 +562,19 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) fclose(out); in.close(); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + // updates moves' gcode ids which have been modified by the insertion of the M73 lines + unsigned int curr_offset_id = 0; + unsigned int total_offset = 0; + for (MoveVertex& move : moves) { + while (curr_offset_id < static_cast(offsets.size()) && offsets[curr_offset_id].first <= move.gcode_id) { + total_offset += offsets[curr_offset_id].second; + ++curr_offset_id; + } + move.gcode_id += total_offset; + } +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (rename_file(out_path, filename)) throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' + "Is " + out_path + " locked?" + '\n'); @@ -503,6 +593,64 @@ const std::vector> GCodeProces unsigned int GCodeProcessor::s_result_id = 0; +#if ENABLE_VALIDATE_CUSTOM_GCODE +static inline bool starts_with(const std::string_view comment, const std::string_view tag) +{ + size_t tag_len = tag.size(); + return comment.size() >= tag_len && comment.substr(0, tag_len) == tag; +} + +bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string& found_tag) +{ + bool ret = false; + + GCodeReader parser; + parser.parse_buffer(gcode, [&ret, &found_tag](GCodeReader& parser, const GCodeReader::GCodeLine& line) { + std::string comment = line.raw(); + if (comment.length() > 2 && comment.front() == ';') { + comment = comment.substr(1); + for (const std::string& s : Reserved_Tags) { + if (starts_with(comment, s)) { + ret = true; + found_tag = comment; + parser.quit_parsing(); + return; + } + } + } + }); + + return ret; +} + +bool GCodeProcessor::contains_reserved_tags(const std::string& gcode, unsigned int max_count, std::vector& found_tag) +{ + max_count = std::max(max_count, 1U); + + bool ret = false; + + GCodeReader parser; + parser.parse_buffer(gcode, [&ret, &found_tag, max_count](GCodeReader& parser, const GCodeReader::GCodeLine& line) { + std::string comment = line.raw(); + if (comment.length() > 2 && comment.front() == ';') { + comment = comment.substr(1); + for (const std::string& s : Reserved_Tags) { + if (starts_with(comment, s)) { + ret = true; + found_tag.push_back(comment); + if (found_tag.size() == max_count) { + parser.quit_parsing(); + return; + } + } + } + } + }); + + return ret; +} +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + GCodeProcessor::GCodeProcessor() { reset(); @@ -750,13 +898,14 @@ void GCodeProcessor::reset() m_cached_position.reset(); m_wiping = false; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_line_id = 0; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER m_feedrate = 0.0f; m_width = 0.0f; m_height = 0.0f; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE m_forced_width = 0.0f; m_forced_height = 0.0f; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE m_mm3_per_mm = 0.0f; m_fan_speed = 0.0f; @@ -808,7 +957,11 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr if (cmd.length() == 0) { const std::string_view comment = line.comment(); if (comment.length() > 1 && detect_producer(comment)) +#if ENABLE_VALIDATE_CUSTOM_GCODE + m_parser.quit_parsing(); +#else m_parser.quit_parsing_file(); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE } }); @@ -817,7 +970,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr if (m_producer == EProducer::PrusaSlicer || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) { DynamicPrintConfig config; config.apply(FullPrintConfig::defaults()); - config.load_from_gcode_file(filename); + config.load_from_gcode_file(filename, false); apply_config(config); } } @@ -859,7 +1012,11 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr // post-process to add M73 lines into the gcode if (apply_postprocess) +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_time_processor.post_process(filename, m_result.moves); +#else m_time_processor.post_process(filename); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER #if ENABLE_GCODE_VIEWER_DATA_CHECKING std::cout << "\n"; @@ -935,6 +1092,10 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { /* std::cout << line.raw() << std::endl; */ +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + ++m_line_id; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + // update start position m_start_position = m_end_position; @@ -1004,11 +1165,13 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) } } +#if !ENABLE_VALIDATE_CUSTOM_GCODE static inline bool starts_with(const std::string_view comment, const std::string_view tag) { size_t tag_len = tag.size(); return comment.size() >= tag_len && comment.substr(0, tag_len) == tag; } +#endif // !ENABLE_VALIDATE_CUSTOM_GCODE #if __has_include() template @@ -1061,6 +1224,25 @@ void GCodeProcessor::process_tags(const std::string_view comment) if (m_producers_enabled && process_producers_tags(comment)) return; +#if ENABLE_VALIDATE_CUSTOM_GCODE + // extrusion role tag + if (starts_with(comment, reserved_tag(ETags::Role))) { + m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length())); + return; + } + + // wipe start tag + if (starts_with(comment, reserved_tag(ETags::Wipe_Start))) { + m_wiping = true; + return; + } + + // wipe end tag + if (starts_with(comment, reserved_tag(ETags::Wipe_End))) { + m_wiping = false; + return; + } +#else // extrusion role tag if (starts_with(comment, Extrusion_Role_Tag)) { m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(Extrusion_Role_Tag.length())); @@ -1078,9 +1260,23 @@ void GCodeProcessor::process_tags(const std::string_view comment) m_wiping = false; return; } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE if (!m_producers_enabled || m_producer == EProducer::PrusaSlicer) { +#if ENABLE_VALIDATE_CUSTOM_GCODE + // height tag + if (starts_with(comment, reserved_tag(ETags::Height))) { + if (!parse_number(comment.substr(reserved_tag(ETags::Height).size()), m_forced_height)) + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; + return; + } + // width tag + if (starts_with(comment, reserved_tag(ETags::Width))) { + if (!parse_number(comment.substr(reserved_tag(ETags::Width).size()), m_forced_width)) + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; + return; + } +#else // height tag if (starts_with(comment, Height_Tag)) { if (!parse_number(comment.substr(Height_Tag.size()), m_forced_height)) @@ -1093,26 +1289,56 @@ void GCodeProcessor::process_tags(const std::string_view comment) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; return; } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + } + +#if ENABLE_VALIDATE_CUSTOM_GCODE + // color change tag + if (starts_with(comment, reserved_tag(ETags::Color_Change))) { + unsigned char extruder_id = 0; + if (starts_with(comment.substr(reserved_tag(ETags::Color_Change).size()), ",T")) { + int eid; + if (!parse_number(comment.substr(reserved_tag(ETags::Color_Change).size() + 2), eid) || eid < 0 || eid > 255) { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ")."; + return; + } + extruder_id = static_cast(eid); + } + + m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview + ++m_cp_color.counter; + if (m_cp_color.counter == UCHAR_MAX) + m_cp_color.counter = 0; + + if (m_extruder_id == extruder_id) { + m_cp_color.current = m_extruder_colors[extruder_id]; + store_move_vertex(EMoveType::Color_change); + } + + process_custom_gcode_time(CustomGCode::ColorChange); + + return; + } + + // pause print tag + if (comment == reserved_tag(ETags::Pause_Print)) { + store_move_vertex(EMoveType::Pause_Print); + process_custom_gcode_time(CustomGCode::PausePrint); + return; + } + + // custom code tag + if (comment == reserved_tag(ETags::Custom_Code)) { + store_move_vertex(EMoveType::Custom_GCode); + return; + } + + // layer change tag + if (comment == reserved_tag(ETags::Layer_Change)) { + ++m_layer_id; + return; } #else - if ((!m_producers_enabled || m_producer == EProducer::PrusaSlicer) && - starts_with(comment, Height_Tag)) { - // height tag - if (!parse_number(comment.substr(Height_Tag.size()), m_height)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; - return; - } - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - // width tag - if (starts_with(comment, Width_Tag)) { - if (! parse_number(comment.substr(Width_Tag.size()), m_width_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; - return; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - // color change tag if (starts_with(comment, Color_Change_Tag)) { unsigned char extruder_id = 0; @@ -1153,6 +1379,13 @@ void GCodeProcessor::process_tags(const std::string_view comment) return; } + // layer change tag + if (comment == Layer_Change_Tag) { + ++m_layer_id; + return; + } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + #if ENABLE_GCODE_VIEWER_DATA_CHECKING // mm3_per_mm print tag if (starts_with(comment, Mm3_Per_Mm_Tag)) { @@ -1161,12 +1394,6 @@ void GCodeProcessor::process_tags(const std::string_view comment) return; } #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - // layer change tag - if (comment == Layer_Change_Tag) { - ++m_layer_id; - return; - } } bool GCodeProcessor::process_producers_tags(const std::string_view comment) @@ -1343,7 +1570,6 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment) } // geometry -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE // ; tool std::string tag = " tool"; pos = comment.find(tag); @@ -1369,35 +1595,6 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment) // ; layer tag = " layer"; -#else -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - // ; tool - std::string tag = " tool"; - pos = comment.find(tag); - if (pos == 0) { - const std::string_view data = comment.substr(pos + tag.length()); - std::string h_tag = "H"; - size_t h_start = data.find(h_tag); - size_t h_end = data.find_first_of(' ', h_start); - std::string w_tag = "W"; - size_t w_start = data.find(w_tag); - size_t w_end = data.find_first_of(' ', w_start); - if (h_start != data.npos) { - if (! parse_number(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end), m_height_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; - } - if (w_start != data.npos) { - if (! parse_number(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end), m_width_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; - } - - return true; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - // ; layer - std::string tag = " layer"; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE pos = comment.find(tag); if (pos == 0) { // skip lines "; layer end" @@ -1488,7 +1685,6 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment) } // geometry -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE // width tag = "WIDTH:"; pos = comment.find(tag); @@ -1506,27 +1702,6 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; return true; } -#else -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - // width - tag = "WIDTH:"; - pos = comment.find(tag); - if (pos != comment.npos) { - if (! parse_number(comment.substr(pos + tag.length()), m_width_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; - return true; - } - - // height - tag = "HEIGHT:"; - pos = comment.find(tag); - if (pos != comment.npos) { - if (! parse_number(comment.substr(pos + tag.length()), m_height_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; - return true; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE // layer pos = comment.find("LAYER:"); @@ -1755,7 +1930,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE if (m_forced_height > 0.0f) m_height = m_forced_height; else { @@ -1768,25 +1942,10 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_height_compare.update(m_height, m_extrusion_role); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -#else - if ((m_producers_enabled && m_producer != EProducer::PrusaSlicer) || m_height == 0.0f) { - if (m_end_position[Z] > m_extruded_last_z + EPSILON) { - m_height = m_end_position[Z] - m_extruded_last_z; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.update(m_height, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - m_extruded_last_z = m_end_position[Z]; - } - } -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE if (m_forced_width > 0.0f) m_width = m_forced_width; else if (m_extrusion_role == erExternalPerimeter) -#else - if (m_extrusion_role == erExternalPerimeter) -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE // cross section: rectangle m_width = delta_pos[E] * static_cast(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height); else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone) @@ -2340,6 +2499,10 @@ void GCodeProcessor::process_T(const std::string_view command) if (command.length() > 1) { int eid = 0; if (! parse_number(command.substr(1), eid) || eid < 0 || eid > 255) { + // Specific to the MMU2 V2 (see https://www.help.prusa3d.com/en/article/prusa-specific-g-codes_112173): + if (m_flavor == gcfMarlin && (command == "Tx" || command == "Tc" || command == "T?")) + return; + // T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) see https://github.com/prusa3d/PrusaSlicer/issues/5677 if ((m_flavor != gcfRepRapFirmware && m_flavor != gcfRepRapSprinter) || eid != -1) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ")."; @@ -2372,6 +2535,9 @@ void GCodeProcessor::process_T(const std::string_view command) void GCodeProcessor::store_move_vertex(EMoveType type) { MoveVertex vertex = { +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_line_id, +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER type, m_extrusion_role, m_extruder_id, diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 5068d0fd62..05f9a2ce33 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -69,7 +69,34 @@ namespace Slic3r { class GCodeProcessor { +#if ENABLE_VALIDATE_CUSTOM_GCODE + static const std::vector Reserved_Tags; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE public: +#if ENABLE_VALIDATE_CUSTOM_GCODE + enum class ETags : unsigned char + { + Role, + Wipe_Start, + Wipe_End, + Height, + Width, + Layer_Change, + Color_Change, + Pause_Print, + Custom_Code, + First_Line_M73_Placeholder, + Last_Line_M73_Placeholder, + Estimated_Printing_Time_Placeholder + }; + + static const std::string& reserved_tag(ETags tag) { return Reserved_Tags[static_cast(tag)]; } + // checks the given gcode for reserved tags and returns true when finding the 1st (which is returned into found_tag) + static bool contains_reserved_tag(const std::string& gcode, std::string& found_tag); + // checks the given gcode for reserved tags and returns true when finding any + // (the first max_count found tags are returned into found_tag) + static bool contains_reserved_tags(const std::string& gcode, unsigned int max_count, std::vector& found_tag); +#else static const std::string Extrusion_Role_Tag; static const std::string Wipe_Start_Tag; static const std::string Wipe_End_Tag; @@ -81,17 +108,13 @@ namespace Slic3r { static const std::string First_Line_M73_Placeholder_Tag; static const std::string Last_Line_M73_Placeholder_Tag; static const std::string Estimated_Printing_Time_Placeholder_Tag; + static const std::string Width_Tag; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE static const float Wipe_Width; static const float Wipe_Height; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - static const std::string Width_Tag; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - static const std::string Width_Tag; -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE static const std::string Mm3_Per_Mm_Tag; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING @@ -173,6 +196,27 @@ namespace Slic3r { float time() const; }; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + struct MoveVertex + { + unsigned int gcode_id{ 0 }; + EMoveType type{ EMoveType::Noop }; + ExtrusionRole extrusion_role{ erNone }; + unsigned char extruder_id{ 0 }; + unsigned char cp_color_id{ 0 }; + Vec3f position{ Vec3f::Zero() }; // mm + float delta_extruder{ 0.0f }; // mm + float feedrate{ 0.0f }; // mm/s + float width{ 0.0f }; // mm + float height{ 0.0f }; // mm + float mm3_per_mm{ 0.0f }; + float fan_speed{ 0.0f }; // percentage + float time{ 0.0f }; // s + + float volumetric_rate() const { return feedrate * mm3_per_mm; } + }; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + private: struct TimeMachine { @@ -253,10 +297,16 @@ namespace Slic3r { void reset(); // post process the file with the given filename to add remaining time lines M73 +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + // and updates moves' gcode ids accordingly + void post_process(const std::string& filename, std::vector& moves); +#else void post_process(const std::string& filename); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER }; public: +#if !ENABLE_GCODE_LINES_ID_IN_H_SLIDER struct MoveVertex { EMoveType type{ EMoveType::Noop }; @@ -274,6 +324,7 @@ namespace Slic3r { float volumetric_rate() const { return feedrate * mm3_per_mm; } }; +#endif // !ENABLE_GCODE_LINES_ID_IN_H_SLIDER struct Result { @@ -404,13 +455,14 @@ namespace Slic3r { CachedPosition m_cached_position; bool m_wiping; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + unsigned int m_line_id; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER float m_feedrate; // mm/s float m_width; // mm float m_height; // mm -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE float m_forced_width; // mm float m_forced_height; // mm -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE float m_mm3_per_mm; float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 1acc160f0f..44b1fcff1e 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -15,7 +15,7 @@ static constexpr float ENFORCER_BLOCKER_PENALTY = 100; // In case there are custom enforcers/blockers, the loop polygon shall always have // sides smaller than this (so it isn't limited to original resolution). -static constexpr float MINIMAL_POLYGON_SIDE = scale_(0.2f); +static constexpr float MINIMAL_POLYGON_SIDE = scaled(0.2f); // When spAligned is active and there is a support enforcer, // add this penalty to its center. @@ -664,7 +664,7 @@ static std::vector find_enforcer_centers(const Polygon& polygon, if (polygon.size() < 2 || enforcers_idxs.empty()) return out; - auto get_center_idx = [&polygon, &lengths](size_t start_idx, size_t end_idx) -> size_t { + auto get_center_idx = [&lengths](size_t start_idx, size_t end_idx) -> size_t { assert(end_idx >= start_idx); if (start_idx == end_idx) return start_idx; @@ -750,35 +750,36 @@ void SeamPlacer::apply_custom_seam(const Polygon& polygon, size_t po_idx, } } -//////////////////////// -// std::ostringstream os; -// os << std::setw(3) << std::setfill('0') << layer_id; -// int a = scale_(30.); -// SVG svg("custom_seam" + os.str() + ".svg", BoundingBox(Point(-a, -a), Point(a, a))); -// //if (! m_enforcers[po_idx].empty()) -// // svg.draw(m_enforcers[po_idx][layer_id].polys, "blue"); -// //if (! m_blockers[po_idx].empty()) -// // svg.draw(m_blockers[po_idx][layer_id].polys, "red"); +#if 0 + std::ostringstream os; + os << std::setw(3) << std::setfill('0') << layer_id; + int a = scale_(30.); + SVG svg("custom_seam" + os.str() + ".svg", BoundingBox(Point(-a, -a), Point(a, a))); + if (! m_enforcers[po_idx].empty()) + svg.draw(m_enforcers[po_idx][layer_id].polys, "blue"); + if (! m_blockers[po_idx].empty()) + svg.draw(m_blockers[po_idx][layer_id].polys, "red"); + + if (! blockers_idxs.empty()) { + ; + } + size_t min_idx = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); -// size_t min_idx = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); - -// //svg.draw(polygon.points[idx_min], "red", 6e5); -// for (size_t i=0; i SeamHistory::get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb) { - assert(layer_id >= m_layer_id); - if (layer_id > m_layer_id) { + assert(layer_id >= m_layer_id || layer_id == 0); + if (layer_id != m_layer_id) { // Get seam was called for different layer than last time. + if (layer_id == 0) // seq printing + m_data_this_layer.clear(); m_data_last_layer = m_data_this_layer; m_data_this_layer.clear(); m_layer_id = layer_id; } - - std::optional out; auto seams_it = m_data_last_layer.find(po); diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 74f061e4ea..fae4028deb 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -600,7 +600,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int return std::max(0.f, volume_to_wipe); // Soluble filament cannot be wiped in a random infill, neither the filament after it // we will sort objects so that dedicated for wiping are at the beginning: - PrintObjectPtrs object_list = print.objects(); + ConstPrintObjectPtrs object_list = print.objects().vector(); std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config().wipe_into_objects; }); // We will now iterate through diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 0f72dc415d..24248e16c1 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -42,36 +42,32 @@ public: { // adds tag for analyzer: char buf[64]; +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%f\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming + m_gcode += buf; + sprintf(buf, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erWipeTower).c_str()); +#else sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming m_gcode += buf; sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erWipeTower).c_str()); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE m_gcode += buf; -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING change_analyzer_line_width(line_width); -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING - } + } -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE WipeTowerWriter& change_analyzer_line_width(float line_width) { // adds tag for analyzer: char buf[64]; +#if ENABLE_VALIDATE_CUSTOM_GCODE + sprintf(buf, ";%s%f\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width).c_str(), line_width); +#else sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE m_gcode += buf; return *this; } -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #if ENABLE_GCODE_VIEWER_DATA_CHECKING -#if !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - WipeTowerWriter& change_analyzer_line_width(float line_width) { - // adds tag for analyzer: - char buf[64]; - sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); - m_gcode += buf; - return *this; - } -#endif // !ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE - WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); @@ -405,7 +401,7 @@ public: WipeTowerWriter& append(const std::string& text) { m_gcode += text; return *this; } - std::vector wipe_path() const + const std::vector& wipe_path() const { return m_wipe_path; } @@ -874,12 +870,8 @@ void WipeTower::toolchange_Unload( const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing; // spacing between lines in mm -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING writer.append("; CP TOOLCHANGE UNLOAD\n") .change_analyzer_line_width(line_width); -#else - writer.append("; CP TOOLCHANGE UNLOAD\n"); -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING unsigned i = 0; // iterates through ramming_speed m_left_to_right = true; // current direction of ramming @@ -942,9 +934,7 @@ void WipeTower::toolchange_Unload( } } Vec2f end_of_ramming(writer.x(),writer.y()); -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING writer.change_analyzer_line_width(m_perimeter_width); // so the next lines are not affected by ramming_line_width_multiplier -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE || ENABLE_GCODE_VIEWER_DATA_CHECKING // Retraction: float old_x = writer.x(); diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index 2ef238f105..fb493fcb7e 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -116,8 +116,13 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback) { boost::nowide::ifstream f(file); std::string line; +#if ENABLE_VALIDATE_CUSTOM_GCODE + m_parsing = true; + while (m_parsing && std::getline(f, line)) +#else m_parsing_file = true; while (m_parsing_file && std::getline(f, line)) +#endif // ENABLE_VALIDATE_CUSTOM_GCODE this->parse_line(line, callback); } diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index d90a231608..54e1937997 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -84,7 +84,12 @@ public: { const char *ptr = buffer.c_str(); GCodeLine gline; +#if ENABLE_VALIDATE_CUSTOM_GCODE + m_parsing = true; + while (m_parsing && *ptr != 0) { +#else while (*ptr != 0) { +#endif // ENABLE_VALIDATE_CUSTOM_GCODE gline.reset(); ptr = this->parse_line(ptr, gline, callback); } @@ -108,7 +113,11 @@ public: { GCodeLine gline; this->parse_line(line.c_str(), gline, callback); } void parse_file(const std::string &file, callback_t callback); +#if ENABLE_VALIDATE_CUSTOM_GCODE + void quit_parsing() { m_parsing = false; } +#else void quit_parsing_file() { m_parsing_file = false; } +#endif // ENABLE_VALIDATE_CUSTOM_GCODE float& x() { return m_position[X]; } float x() const { return m_position[X]; } @@ -147,7 +156,11 @@ private: char m_extrusion_axis; float m_position[NUM_AXES]; bool m_verbose; +#if ENABLE_VALIDATE_CUSTOM_GCODE + bool m_parsing{ false }; +#else bool m_parsing_file{ false }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE }; } /* namespace Slic3r */ diff --git a/src/libslic3r/GCodeSender.hpp b/src/libslic3r/GCodeSender.hpp index d7663ca554..3a2055e54f 100644 --- a/src/libslic3r/GCodeSender.hpp +++ b/src/libslic3r/GCodeSender.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace Slic3r { diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index b353877621..847398e69f 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -204,6 +204,9 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration) gcode << "\n"; // M202: Set max travel acceleration gcode << "M202 X" << acceleration << " Y" << acceleration; + } else if (FLAVOR_IS(gcfRepRapFirmware)) { + // M204: Set default acceleration + gcode << "M204 P" << acceleration; } else { // M204: Set default acceleration gcode << "M204 S" << acceleration; diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index f8d3b0a5c9..9d98ea6aeb 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -11,7 +11,16 @@ #include #define BOOST_VORONOI_USE_GMP 1 + +#ifdef _MSC_VER +// Suppress warning C4146 in OpenVDB: unary minus operator applied to unsigned type, result still unsigned +#pragma warning(push) +#pragma warning(disable : 4146) +#endif // _MSC_VER #include "boost/polygon/voronoi.hpp" +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER namespace ClipperLib { class PolyNode; @@ -213,7 +222,7 @@ inline bool liang_barsky_line_clipping_interval( double t0 = 0.0; double t1 = 1.0; // Traverse through left, right, bottom, top edges. - auto clip_side = [&x0, &v, &bbox, &t0, &t1](double p, double q) -> bool { + auto clip_side = [&t0, &t1](double p, double q) -> bool { if (p == 0) { if (q < 0) // Line parallel to the bounding box edge is fully outside of the bounding box. diff --git a/src/libslic3r/KDTreeIndirect.hpp b/src/libslic3r/KDTreeIndirect.hpp index 239008559c..12e462569e 100644 --- a/src/libslic3r/KDTreeIndirect.hpp +++ b/src/libslic3r/KDTreeIndirect.hpp @@ -195,8 +195,9 @@ private: template size_t find_closest_point(const KDTreeIndirectType &kdtree, const PointType &point, FilterFn filter) { + using CoordType = typename KDTreeIndirectType::CoordType; + struct Visitor { - using CoordType = typename KDTreeIndirectType::CoordType; const KDTreeIndirectType &kdtree; const PointType &point; const FilterFn filter; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 9752744453..b974ff2172 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -143,16 +143,20 @@ void Layer::make_perimeters() if (! (*it)->slices.empty()) { LayerRegion* other_layerm = *it; const PrintRegionConfig &other_config = other_layerm->region()->config(); - if (config.perimeter_extruder == other_config.perimeter_extruder - && config.perimeters == other_config.perimeters - && config.perimeter_speed == other_config.perimeter_speed - && config.external_perimeter_speed == other_config.external_perimeter_speed - && config.gap_fill_speed == other_config.gap_fill_speed - && config.overhangs == other_config.overhangs + if (config.perimeter_extruder == other_config.perimeter_extruder + && config.perimeters == other_config.perimeters + && config.perimeter_speed == other_config.perimeter_speed + && config.external_perimeter_speed == other_config.external_perimeter_speed + && (config.gap_fill_enabled ? config.gap_fill_speed.value : 0.) == + (other_config.gap_fill_enabled ? other_config.gap_fill_speed.value : 0.) + && config.overhangs == other_config.overhangs && config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width") - && config.thin_walls == other_config.thin_walls - && config.external_perimeters_first == other_config.external_perimeters_first - && config.infill_overlap == other_config.infill_overlap) + && config.thin_walls == other_config.thin_walls + && config.external_perimeters_first == other_config.external_perimeters_first + && config.infill_overlap == other_config.infill_overlap + && config.fuzzy_skin == other_config.fuzzy_skin + && config.fuzzy_skin_thickness == other_config.fuzzy_skin_thickness + && config.fuzzy_skin_point_dist == other_config.fuzzy_skin_point_dist) { other_layerm->perimeters.clear(); other_layerm->fills.clear(); diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 508269f1a4..9a3fe368d3 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -46,7 +46,7 @@ public: // collection of expolygons representing the bridged areas (thus not // needing support material) - Polygons bridged; +// Polygons bridged; // collection of polylines representing the unsupported bridge edges Polylines unsupported_bridge_edges; diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index b3383fcc5a..1a0bd341c4 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -277,8 +277,8 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly double custom_angle = Geometry::deg2rad(this->region()->config().bridge_angle.value); if (bd.detect_angle(custom_angle)) { bridges[idx_last].bridge_angle = bd.angle; - if (this->layer()->object()->config().support_material) { - polygons_append(this->bridged, bd.coverage()); + if (this->layer()->object()->has_support()) { +// polygons_append(this->bridged, bd.coverage()); append(this->unsupported_bridge_edges, bd.unsupported_edges()); } } else if (custom_angle > 0) { @@ -290,7 +290,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly surfaces_append(bottom, union_ex(grown, true), bridges[idx_last]); } - fill_boundaries = std::move(to_polygons(fill_boundaries_ex)); + fill_boundaries = to_polygons(fill_boundaries_ex); BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges - done"; } @@ -327,7 +327,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly surfaces_append( new_surfaces, // Don't use a safety offset as fill_boundaries were already united using the safety offset. - std::move(intersection_ex(polys, fill_boundaries, false)), + intersection_ex(polys, fill_boundaries, false), s1); } } @@ -424,7 +424,7 @@ void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_comp Polygons slices_polygons = to_polygons(slices_expolygons); Polygons tmp = intersection(slices_polygons, trimming_polygons, false); append(tmp, diff(slices_polygons, offset(offset_ex(slices_expolygons, -elephant_foot_compensation_perimeter_step), elephant_foot_compensation_perimeter_step))); - this->slices.set(std::move(union_ex(tmp)), stInternal); + this->slices.set(union_ex(tmp), stInternal); } void LayerRegion::export_region_slices_to_svg(const char *path) const diff --git a/src/libslic3r/MarchingSquares.hpp b/src/libslic3r/MarchingSquares.hpp index d5f07fbde6..8370c8cef9 100644 --- a/src/libslic3r/MarchingSquares.hpp +++ b/src/libslic3r/MarchingSquares.hpp @@ -297,7 +297,7 @@ template class Grid { case SquareTag::full: case SquareTag::none: { Coord crd{tl(cell) + Coord{m_cellsize.r / 2, m_cellsize.c / 2}}; - return {{crd, Dir::none, m_rst}, crd}; + return {{crd, Dir::none, m_rst}, {crd}}; } } diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index c25026cc49..5f806955ee 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -472,6 +472,29 @@ void Model::convert_from_imperial_units(bool only_small_volumes) } } +bool Model::looks_like_saved_in_meters() const +{ + if (this->objects.size() == 0) + return false; + + for (ModelObject* obj : this->objects) + if (obj->get_object_stl_stats().volume < 0.001) // 0.001 = 0.1*0.1*0.1; + return true; + + return false; +} + +void Model::convert_from_meters(bool only_small_volumes) +{ + double m_to_mm = 1000; + for (ModelObject* obj : this->objects) + if (! only_small_volumes || obj->get_object_stl_stats().volume < 0.001) { // 0.001 = 0.1*0.1*0.1; + obj->scale_mesh_after_creation(Vec3d(m_to_mm, m_to_mm, m_to_mm)); + for (ModelVolume* v : obj->volumes) + v->source.is_converted_from_meters = true; + } +} + void Model::adjust_min_z() { if (objects.empty()) @@ -1023,13 +1046,14 @@ void ModelObject::scale_mesh_after_creation(const Vec3d &versor) this->invalidate_bounding_box(); } -void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial, std::vector volume_idxs) +void ModelObject::convert_units(ModelObjectPtrs& new_objects, ConversionType conv_type, std::vector volume_idxs) { BOOST_LOG_TRIVIAL(trace) << "ModelObject::convert_units - start"; ModelObject* new_object = new_clone(*this); - double koef = from_imperial ? 25.4 : 0.0393700787; + double koef = conv_type == ConversionType::CONV_FROM_INCH ? 25.4 : conv_type == ConversionType::CONV_TO_INCH ? 0.0393700787 : + conv_type == ConversionType::CONV_FROM_METER ? 1000 : conv_type == ConversionType::CONV_TO_METER ? 0.001 : 1; const Vec3d versor = Vec3d(koef, koef, koef); new_object->set_model(nullptr); @@ -1057,6 +1081,8 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial vol->source.input_file = volume->source.input_file; vol->source.object_idx = (int)new_objects.size(); vol->source.volume_idx = vol_idx; + vol->source.is_converted_from_inches = volume->source.is_converted_from_inches; + vol->source.is_converted_from_meters = volume->source.is_converted_from_meters; vol->supported_facets.assign(volume->supported_facets); vol->seam_facets.assign(volume->seam_facets); @@ -1068,7 +1094,10 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial std::find(volume_idxs.begin(), volume_idxs.end(), vol_idx) != volume_idxs.end())) { vol->scale_geometry_after_creation(versor); vol->set_offset(versor.cwiseProduct(volume->get_offset())); - vol->source.is_converted_from_inches = from_imperial; + if (conv_type == ConversionType::CONV_FROM_INCH || conv_type == ConversionType::CONV_TO_INCH) + vol->source.is_converted_from_inches = conv_type == ConversionType::CONV_FROM_INCH; + if (conv_type == ConversionType::CONV_FROM_METER || conv_type == ConversionType::CONV_TO_METER) + vol->source.is_converted_from_meters = conv_type == ConversionType::CONV_FROM_METER; } else vol->set_offset(volume->get_offset()); @@ -1282,6 +1311,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects) ModelVolume* volume = this->volumes.front(); TriangleMeshPtrs meshptrs = volume->mesh().split(); + size_t counter = 1; for (TriangleMesh *mesh : meshptrs) { // FIXME: crashes if not satisfied @@ -1291,7 +1321,8 @@ void ModelObject::split(ModelObjectPtrs* new_objects) // XXX: this seems to be the only real usage of m_model, maybe refactor this so that it's not needed? ModelObject* new_object = m_model->add_object(); - new_object->name = this->name; + new_object->name = this->name + (meshptrs.size() > 1 ? "_" + std::to_string(counter++) : ""); + // Don't copy the config's ID. new_object->config.assign_config(this->config); assert(new_object->config.id().valid()); @@ -1816,6 +1847,14 @@ void ModelVolume::convert_from_imperial_units() this->source.is_converted_from_inches = true; } +void ModelVolume::convert_from_meters() +{ + double m_to_mm = 1000; + this->scale_geometry_after_creation(Vec3d(m_to_mm, m_to_mm, m_to_mm)); + this->set_offset(Vec3d(0, 0, 0)); + this->source.is_converted_from_meters = true; +} + void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const { mesh->transform(get_matrix(dont_translate)); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 99db132f67..868639ee80 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -29,6 +29,7 @@ namespace cereal { } namespace Slic3r { +enum class ConversionType; class Model; class ModelInstance; @@ -325,7 +326,7 @@ public: // This method could only be called before the meshes of this ModelVolumes are not shared! void scale_mesh_after_creation(const Vec3d& versor); - void convert_units(ModelObjectPtrs&new_objects, bool from_imperial, std::vector volume_idxs); + void convert_units(ModelObjectPtrs&new_objects, ConversionType conv_type, std::vector volume_idxs); size_t materials_count() const; size_t facets_count() const; @@ -495,6 +496,13 @@ enum class EnforcerBlockerType : int8_t { BLOCKER = 2 }; +enum class ConversionType : int { + CONV_TO_INCH, + CONV_FROM_INCH, + CONV_TO_METER, + CONV_FROM_METER, +}; + class FacetsAnnotation final : public ObjectWithTimestamp { public: // Assign the content if the timestamp differs, don't assign an ObjectID. @@ -553,11 +561,12 @@ public: Vec3d mesh_offset{ Vec3d::Zero() }; Geometry::Transformation transform; bool is_converted_from_inches = false; + bool is_converted_from_meters = false; template void serialize(Archive& ar) { //FIXME Vojtech: Serialize / deserialize only if the Source is set. // likely testing input_file or object_idx would be sufficient. - ar(input_file, object_idx, volume_idx, mesh_offset, transform, is_converted_from_inches); + ar(input_file, object_idx, volume_idx, mesh_offset, transform, is_converted_from_inches, is_converted_from_meters); } }; Source source; @@ -657,6 +666,7 @@ public: void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } void convert_from_imperial_units(); + void convert_from_meters(); const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } @@ -1019,6 +1029,8 @@ public: void convert_multipart_object(unsigned int max_extruders); bool looks_like_imperial_units() const; void convert_from_imperial_units(bool only_small_volumes); + bool looks_like_saved_in_meters() const; + void convert_from_meters(bool only_small_volumes); // Ensures that the min z of the model is not negative void adjust_min_z(); diff --git a/src/libslic3r/OpenVDBUtils.cpp b/src/libslic3r/OpenVDBUtils.cpp index 31ae203ddf..0f5bfa157c 100644 --- a/src/libslic3r/OpenVDBUtils.cpp +++ b/src/libslic3r/OpenVDBUtils.cpp @@ -1,6 +1,16 @@ #define NOMINMAX #include "OpenVDBUtils.hpp" + +#ifdef _MSC_VER +// Suppress warning C4146 in OpenVDB: unary minus operator applied to unsigned type, result still unsigned +#pragma warning(push) +#pragma warning(disable : 4146) +#endif // _MSC_VER #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + #include #include #include diff --git a/src/libslic3r/OpenVDBUtils.hpp b/src/libslic3r/OpenVDBUtils.hpp index e35231d35b..aa4b5154a8 100644 --- a/src/libslic3r/OpenVDBUtils.hpp +++ b/src/libslic3r/OpenVDBUtils.hpp @@ -3,7 +3,16 @@ #include #include + +#ifdef _MSC_VER +// Suppress warning C4146 in include/gmp.h(2177,31): unary minus operator applied to unsigned type, result still unsigned +#pragma warning(push) +#pragma warning(disable : 4146) +#endif // _MSC_VER #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER namespace Slic3r { diff --git a/src/libslic3r/PNGReadWrite.cpp b/src/libslic3r/PNGReadWrite.cpp index 1e8a7de537..3308f1fd42 100644 --- a/src/libslic3r/PNGReadWrite.cpp +++ b/src/libslic3r/PNGReadWrite.cpp @@ -102,7 +102,8 @@ bool decode_png(IStream &in_buf, ImageGreyscale &out_img) // Down to earth function to store a packed RGB image to file. Mostly useful for debugging purposes. // Based on https://www.lemoda.net/c/write-png/ -bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb) +// png_color_type is PNG_COLOR_TYPE_RGB or PNG_COLOR_TYPE_GRAY +static bool write_rgb_or_gray_to_file(const char *file_name_utf8, size_t width, size_t height, int png_color_type, const uint8_t *data) { bool result = false; @@ -141,17 +142,22 @@ bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, png_uint_32(width), png_uint_32(height), 8, // depth - PNG_COLOR_TYPE_RGB, + png_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Initialize rows of PNG. row_pointers = reinterpret_cast(::png_malloc(png_ptr, height * sizeof(png_byte*))); - for (size_t y = 0; y < height; ++ y) { - auto row = reinterpret_cast(::png_malloc(png_ptr, sizeof(uint8_t) * width * 3)); - row_pointers[y] = row; - memcpy(row, data_rgb + width * y * 3, sizeof(uint8_t) * width * 3); + { + int line_width = width; + if (png_color_type == PNG_COLOR_TYPE_RGB) + line_width *= 3; + for (size_t y = 0; y < height; ++ y) { + auto row = reinterpret_cast(::png_malloc(png_ptr, line_width)); + row_pointers[y] = row; + memcpy(row, data + line_width * y, line_width); + } } // Write the image data to "fp". @@ -174,6 +180,11 @@ fopen_failed: return result; } +bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb) +{ + return write_rgb_or_gray_to_file(file_name_utf8, width, height, PNG_COLOR_TYPE_RGB, data_rgb); +} + bool write_rgb_to_file(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb) { return write_rgb_to_file(file_name_utf8.c_str(), width, height, data_rgb); @@ -185,32 +196,54 @@ bool write_rgb_to_file(const std::string &file_name_utf8, size_t width, size_t h return write_rgb_to_file(file_name_utf8.c_str(), width, height, data_rgb.data()); } +bool write_gray_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_gray) +{ + return write_rgb_or_gray_to_file(file_name_utf8, width, height, PNG_COLOR_TYPE_GRAY, data_gray); +} + +bool write_gray_to_file(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_gray) +{ + return write_gray_to_file(file_name_utf8.c_str(), width, height, data_gray); +} + +bool write_gray_to_file(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_gray) +{ + assert(width * height == data_gray.size()); + return write_gray_to_file(file_name_utf8.c_str(), width, height, data_gray.data()); +} + // Scaled variants are mostly useful for debugging purposes, for example to export images of low resolution distance fileds. // Scaling is done by multiplying rows and columns without any smoothing to emphasise the original pixels. -bool write_rgb_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale) +// png_color_type is PNG_COLOR_TYPE_RGB or PNG_COLOR_TYPE_GRAY +static bool write_rgb_or_gray_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, int png_color_type, const uint8_t *data, size_t scale) { if (scale <= 1) - return write_rgb_to_file(file_name_utf8, width, height, data_rgb); + return write_rgb_or_gray_to_file(file_name_utf8, width, height, png_color_type, data); else { - std::vector scaled(width * height * 3 * scale * scale); + size_t pixel_bytes = png_color_type == PNG_COLOR_TYPE_RGB ? 3 : 1; + size_t line_width = width * pixel_bytes; + std::vector scaled(line_width * height * scale * scale); uint8_t *dst = scaled.data(); for (size_t r = 0; r < height; ++ r) { for (size_t repr = 0; repr < scale; ++ repr) { - const uint8_t *row = data_rgb + width * 3 * r; + const uint8_t *row = data + line_width * r; for (size_t c = 0; c < width; ++ c) { - for (size_t repc = 0; repc < scale; ++ repc) { - *dst ++ = row[0]; - *dst ++ = row[1]; - *dst ++ = row[2]; - } - row += 3; + for (size_t repc = 0; repc < scale; ++ repc) + for (size_t b = 0; b < pixel_bytes; ++ b) + *dst ++ = row[b]; + row += pixel_bytes; } } } - return write_rgb_to_file(file_name_utf8, width * scale, height * scale, scaled.data()); + return write_rgb_or_gray_to_file(file_name_utf8, width * scale, height * scale, png_color_type, scaled.data()); } } +bool write_rgb_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale) +{ + return write_rgb_or_gray_to_file_scaled(file_name_utf8, width, height, PNG_COLOR_TYPE_RGB, data_rgb, scale); +} + bool write_rgb_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale) { return write_rgb_to_file_scaled(file_name_utf8.c_str(), width, height, data_rgb, scale); @@ -222,4 +255,20 @@ bool write_rgb_to_file_scaled(const std::string &file_name_utf8, size_t width, s return write_rgb_to_file_scaled(file_name_utf8.c_str(), width, height, data_rgb.data(), scale); } +bool write_gray_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_gray, size_t scale) +{ + return write_rgb_or_gray_to_file_scaled(file_name_utf8, width, height, PNG_COLOR_TYPE_GRAY, data_gray, scale); +} + +bool write_gray_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_gray, size_t scale) +{ + return write_gray_to_file_scaled(file_name_utf8.c_str(), width, height, data_gray, scale); +} + +bool write_gray_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_gray, size_t scale) +{ + assert(width * height == data_gray.size()); + return write_gray_to_file_scaled(file_name_utf8.c_str(), width, height, data_gray.data(), scale); +} + }} // namespace Slic3r::png diff --git a/src/libslic3r/PNGReadWrite.hpp b/src/libslic3r/PNGReadWrite.hpp index 6be8ed5553..01e1f47450 100644 --- a/src/libslic3r/PNGReadWrite.hpp +++ b/src/libslic3r/PNGReadWrite.hpp @@ -71,11 +71,21 @@ template bool decode_png(const ReadBuf &in_buf, Img &out_img) bool write_rgb_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb); bool write_rgb_to_file(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb); bool write_rgb_to_file(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_rgb); +// Grayscale variants +bool write_gray_to_file(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_gray); +bool write_gray_to_file(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_gray); +bool write_gray_to_file(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_gray); + // Scaled variants are mostly useful for debugging purposes, for example to export images of low resolution distance fileds. // Scaling is done by multiplying rows and columns without any smoothing to emphasise the original pixels. bool write_rgb_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale); bool write_rgb_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale); bool write_rgb_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_rgb, size_t scale); +// Grayscale variants +bool write_gray_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_gray, size_t scale); +bool write_gray_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const uint8_t *data_gray, size_t scale); +bool write_gray_to_file_scaled(const std::string &file_name_utf8, size_t width, size_t height, const std::vector &data_gray, size_t scale); + }} // namespace Slic3r::png diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 7a4bbe27ae..7cfdc58473 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -5,7 +5,6 @@ #include #include -#include namespace Slic3r { @@ -113,30 +112,69 @@ static void variable_width(const ThickPolylines& polylines, ExtrusionRole role, class PerimeterGeneratorLoop { public: // Polygon of this contour. - Polygon polygon; + Polygon polygon; // Is it a contour or a hole? // Contours are CCW oriented, holes are CW oriented. - bool is_contour; + bool is_contour; // Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole. - unsigned short depth; + unsigned short depth; + // Should this contur be fuzzyfied on path generation? + bool fuzzify; // Children contour, may be both CCW and CW oriented (outer contours or holes). std::vector children; - PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) : - polygon(polygon), is_contour(is_contour), depth(depth) {} + PerimeterGeneratorLoop(const Polygon &polygon, unsigned short depth, bool is_contour, bool fuzzify) : + polygon(polygon), is_contour(is_contour), depth(depth), fuzzify(fuzzify) {} // External perimeter. It may be CCW or CW oriented (outer contour or hole contour). bool is_external() const { return this->depth == 0; } // An island, which may have holes, but it does not have another internal island. bool is_internal_contour() const; }; -typedef std::vector PerimeterGeneratorLoops; +// Thanks Cura developers for this function. +static void fuzzy_polygon(Polygon &poly, double fuzzy_skin_thickness, double fuzzy_skin_point_dist) +{ + const double min_dist_between_points = fuzzy_skin_point_dist * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value + const double range_random_point_dist = fuzzy_skin_point_dist / 2.; + double dist_left_over = double(rand()) * (min_dist_between_points / 2) / double(RAND_MAX); // the distance to be traversed on the line before making the first new point + Point* p0 = &poly.points.back(); + Points out; + out.reserve(poly.points.size()); + for (Point &p1 : poly.points) + { // 'a' is the (next) new point between p0 and p1 + Vec2d p0p1 = (p1 - *p0).cast(); + double p0p1_size = p0p1.norm(); + // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size + double dist_last_point = dist_left_over + p0p1_size * 2.; + for (double p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; + p0pa_dist += min_dist_between_points + double(rand()) * range_random_point_dist / double(RAND_MAX)) + { + double r = double(rand()) * (fuzzy_skin_thickness * 2.) / double(RAND_MAX) - fuzzy_skin_thickness; + out.emplace_back(*p0 + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast().normalized() * r).cast()); + dist_last_point = p0pa_dist; + } + dist_left_over = p0p1_size - dist_last_point; + p0 = &p1; + } + while (out.size() < 3) { + size_t point_idx = poly.size() - 2; + out.emplace_back(poly[point_idx]); + if (point_idx == 0) + break; + -- point_idx; + } + if (out.size() >= 3) + poly.points = std::move(out); +} + +using PerimeterGeneratorLoops = std::vector; static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perimeter_generator, const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) { // loops is an arrayref of ::Loop objects // turn each one into an ExtrusionLoop object - ExtrusionEntityCollection coll; + ExtrusionEntityCollection coll; + Polygon fuzzified; for (const PerimeterGeneratorLoop &loop : loops) { bool is_external = loop.is_external(); @@ -154,12 +192,18 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime // detect overhanging/bridging perimeters ExtrusionPaths paths; - if (perimeter_generator.config->overhangs && perimeter_generator.layer_id > 0 - && !(perimeter_generator.object_config->support_material && perimeter_generator.object_config->support_material_contact_distance.value == 0)) { + const Polygon &polygon = loop.fuzzify ? fuzzified : loop.polygon; + if (loop.fuzzify) { + fuzzified = loop.polygon; + fuzzy_polygon(fuzzified, scaled(perimeter_generator.config->fuzzy_skin_thickness.value), scaled(perimeter_generator.config->fuzzy_skin_point_dist.value)); + } + if (perimeter_generator.config->overhangs && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers + && ! ((perimeter_generator.object_config->support_material || perimeter_generator.object_config->support_material_enforce_layers > 0) && + perimeter_generator.object_config->support_material_contact_distance.value == 0)) { // get non-overhang paths by intersecting this loop with the grown lower slices extrusion_paths_append( paths, - intersection_pl((Polygons)loop.polygon, perimeter_generator.lower_slices_polygons()), + intersection_pl({ polygon }, perimeter_generator.lower_slices_polygons()), role, is_external ? perimeter_generator.ext_mm3_per_mm() : perimeter_generator.mm3_per_mm(), is_external ? perimeter_generator.ext_perimeter_flow.width : perimeter_generator.perimeter_flow.width, @@ -170,7 +214,7 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime // the loop centerline and original lower slices is >= half nozzle diameter extrusion_paths_append( paths, - diff_pl((Polygons)loop.polygon, perimeter_generator.lower_slices_polygons()), + diff_pl({ polygon }, perimeter_generator.lower_slices_polygons()), erOverhangPerimeter, perimeter_generator.mm3_per_mm_overhang(), perimeter_generator.overhang_flow.width, @@ -181,7 +225,7 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime chain_and_reorder_extrusion_paths(paths, &paths.front().first_point()); } else { ExtrusionPath path(role); - path.polyline = loop.polygon.split_at_first_point(); + path.polyline = polygon.split_at_first_point(); path.mm3_per_mm = is_external ? perimeter_generator.ext_mm3_per_mm() : perimeter_generator.mm3_per_mm(); path.width = is_external ? perimeter_generator.ext_perimeter_flow.width : perimeter_generator.perimeter_flow.width; path.height = (float)perimeter_generator.layer_height; @@ -231,130 +275,8 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime return out; } -/* -enum class FuzzyShape { - Triangle, - Sawtooth, - Random -}; -*/ - -static void fuzzy_polygon(Polygon &poly, /* FuzzyShape shape, */ double fuzzy_skin_thickness, double fuzzy_skin_point_dist) -{ -#if 0 - Point last = poly.points.at(poly.points.size() - 1); - Point last_processed = last; - - double max_length = scale_(2); - double min_length = scale_(1); - - if (poly.length() < scale_(5)) - return; - - deepness *= 3; - - bool triangle_or_sawtooth = shape == FuzzyShape::Sawtooth; - double length_sum = 0; - Points::iterator it = poly.points.begin(); - while (it != poly.points.end()) { - Point &pt = *it; - - Line line(last, pt); - double length = line.length(); - - // split long line - if (length > max_length) { - auto parts = int(ceil(length / max_length)); - if (parts == 2) { - Point point_to_insert(line.midpoint()); - it = poly.points.insert(it, point_to_insert); - } - else { - Vector part_vector = line.vector() / parts; - - Points points_to_insert; - Point point_to_insert(last); - while (--parts) { - point_to_insert += part_vector; - Point point_to_insert_2(point_to_insert); - points_to_insert.push_back(point_to_insert_2); - } - - it = poly.points.insert(it, points_to_insert.begin(), points_to_insert.end()); - } - continue; - } - - length_sum += length; - - // join short lines - if (length_sum < min_length) { - last = pt; - it = poly.points.erase(it); - continue; - } - - line = Line(last_processed, pt); - last = pt; - last_processed = pt; - - if (shape == FuzzyShape::Random) { - triangle_or_sawtooth = !(rand() % 2); - } - - Point point_to_insert(triangle_or_sawtooth ? pt : line.midpoint()); - - int scale = (rand() % deepness) + 1; - - Vec2d normal = line.normal().cast(); - normal /= line.length() / scale_(1.) / ((double)scale / 20.); - - it = poly.points.insert(it, point_to_insert + normal.cast()) + 2; - - length_sum = 0; - } - -#else - const double min_dist_between_points = fuzzy_skin_point_dist * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value - const double range_random_point_dist = fuzzy_skin_point_dist / 2.; - double dist_left_over = double(rand()) * (min_dist_between_points / 2) / double(RAND_MAX); // the distance to be traversed on the line before making the first new point - Point* p0 = &poly.points.back(); - Points out; - out.reserve(poly.points.size()); - for (Point &p1 : poly.points) - { // 'a' is the (next) new point between p0 and p1 - Vec2d p0p1 = (p1 - *p0).cast(); - double p0p1_size = p0p1.norm(); - // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size - double dist_last_point = dist_left_over + p0p1_size * 2.; - for (double p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; - p0pa_dist += min_dist_between_points + double(rand()) * range_random_point_dist / double(RAND_MAX)) - { - double r = double(rand()) * (fuzzy_skin_thickness * 2.) / double(RAND_MAX) - fuzzy_skin_thickness; - out.emplace_back(*p0 + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast().normalized() * r).cast()); - dist_last_point = p0pa_dist; - } - dist_left_over = p0p1_size - dist_last_point; - p0 = &p1; - } - while (out.size() < 3) { - size_t point_idx = poly.size() - 2; - out.emplace_back(poly[point_idx]); - if (point_idx == 0) - break; - -- point_idx; - } - if (out.size() >= 3) - poly.points = std::move(out); -#endif -} - void PerimeterGenerator::process() { - // nasty hack! initialize random generator - auto time_us = std::chrono::duration_cast(std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()).time_since_epoch()).count(); - srand(this->layer_id * time_us); - // other perimeters m_mm3_per_mm = this->perimeter_flow.mm3_per_mm(); coord_t perimeter_width = this->perimeter_flow.scaled_width(); @@ -384,7 +306,7 @@ void PerimeterGenerator::process() // internal flow which is unrelated. coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE)); coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE)); - bool has_gap_fill = this->config->gap_fill_speed.value > 0; + bool has_gap_fill = this->config->gap_fill_enabled.value && this->config->gap_fill_speed.value > 0; // prepare grown lower layer slices for overhang detection if (this->lower_slices != NULL && this->config->overhangs) { @@ -395,32 +317,6 @@ void PerimeterGenerator::process() m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter/2))); } - // fuzzy skin configuration - double fuzzy_skin_thickness = scale_(this->object_config->fuzzy_skin_thickness); - double fuzzy_skin_point_dist = scale_(this->object_config->fuzzy_skin_point_dist); - //FuzzyShape fuzzy_skin_shape; - if (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::None) { - /* - switch (this->object_config->fuzzy_skin_shape) { - case FuzzySkinShape::Triangle1: - case FuzzySkinShape::Triangle2: - case FuzzySkinShape::Triangle3: - fuzzy_skin_shape = FuzzyShape::Triangle; - break; - case FuzzySkinShape::Sawtooth1: - case FuzzySkinShape::Sawtooth2: - case FuzzySkinShape::Sawtooth3: - fuzzy_skin_shape = FuzzyShape::Sawtooth; - break; - case FuzzySkinShape::Random1: - case FuzzySkinShape::Random2: - case FuzzySkinShape::Random3: - fuzzy_skin_shape = FuzzyShape::Random; - break; - } - */ - } - // we need to process each island separately because we might have different // extra perimeters for each one for (const Surface &surface : this->slices->surfaces) { @@ -501,39 +397,22 @@ void PerimeterGenerator::process() // If i > loop_number, we were looking just for gaps. break; } - for (ExPolygon &expolygon : offsets) { - // Outer contour may overlap with an inner contour, - // inner contour may overlap with another inner contour, - // outer contour may overlap with itself. - //FIXME evaluate the overlaps, annotate each point with an overlap depth, - - bool skip_polygon = false; - - if (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::None) { - if (i == 0 && (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::ExternalSkipFirst || this->layer_id > 0)) { - if ( - this->object_config->fuzzy_skin_perimeter_mode == FuzzySkinPerimeterMode::External || - this->object_config->fuzzy_skin_perimeter_mode == FuzzySkinPerimeterMode::ExternalSkipFirst - ) { - ExPolygon expolygon_fuzzy(expolygon); - fuzzy_polygon(expolygon_fuzzy.contour, /* fuzzy_skin_shape, */ fuzzy_skin_thickness, fuzzy_skin_point_dist); - // compensate for the depth of intersection. - contours[i].emplace_back(PerimeterGeneratorLoop(expolygon_fuzzy.contour, i, true)); - skip_polygon = true; - } else - fuzzy_polygon(expolygon.contour, /* fuzzy_skin_shape, */ fuzzy_skin_thickness, fuzzy_skin_point_dist); - } - } - - if (!skip_polygon) { + { + const bool fuzzify_contours = this->config->fuzzy_skin != FuzzySkinType::None && i == 0 && this->layer_id > 0; + const bool fuzzify_holes = fuzzify_contours && this->config->fuzzy_skin == FuzzySkinType::All; + for (const ExPolygon &expolygon : offsets) { + // Outer contour may overlap with an inner contour, + // inner contour may overlap with another inner contour, + // outer contour may overlap with itself. + //FIXME evaluate the overlaps, annotate each point with an overlap depth, // compensate for the depth of intersection. - contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true)); - } + contours[i].emplace_back(expolygon.contour, i, true, fuzzify_contours); - if (! expolygon.holes.empty()) { - holes[i].reserve(holes[i].size() + expolygon.holes.size()); - for (const Polygon &hole : expolygon.holes) - holes[i].emplace_back(PerimeterGeneratorLoop(hole, i, false)); + if (! expolygon.holes.empty()) { + holes[i].reserve(holes[i].size() + expolygon.holes.size()); + for (const Polygon &hole : expolygon.holes) + holes[i].emplace_back(hole, i, false, fuzzify_holes); + } } } last = std::move(offsets); @@ -604,7 +483,7 @@ void PerimeterGenerator::process() // we continue inwards after having finished the brim // TODO: add test for perimeter order if (this->config->external_perimeters_first || - (this->layer_id == 0 && this->print_config->brim_width.value > 0)) + (this->layer_id == 0 && this->object_config->brim_width.value > 0)) entities.reverse(); // append perimeters for this slice as a collection if (! entities.empty()) diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index f74df1c9a2..7c588c67cc 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -96,6 +96,14 @@ bool Polygon::make_clockwise() return false; } +void Polygon::douglas_peucker(double tolerance) +{ + this->points.push_back(this->points.front()); + Points p = MultiPoint::_douglas_peucker(this->points, tolerance); + p.pop_back(); + this->points = std::move(p); +} + // Does an unoriented polygon contain a point? // Tested by counting intersections along a horizontal line. bool Polygon::contains(const Point &point) const diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index b550ae7d7a..aa72b4244d 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -55,6 +55,7 @@ public: bool make_counter_clockwise(); bool make_clockwise(); bool is_valid() const { return this->points.size() >= 3; } + void douglas_peucker(double tolerance); // Does an unoriented polygon contain a point? // Tested by counting intersections along a horizontal line. diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp index ef1da9afb9..9c70522bfb 100644 --- a/src/libslic3r/Polyline.hpp +++ b/src/libslic3r/Polyline.hpp @@ -75,6 +75,7 @@ public: template void simplify_by_visibility(const T &area); void split_at(const Point &point, Polyline* p1, Polyline* p2) const; bool is_straight() const; + bool is_closed() const { return this->points.front() == this->points.back(); } }; // Don't use this class in production code, it is used exclusively by the Perl binding for unit tests! diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 751b2a2a6d..6a656e6d8f 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -15,7 +15,7 @@ // !!! If you needed to translate some string, // !!! please use _L(string) // !!! _() - is a standard wxWidgets macro to translate -// !!! L() is used only for marking localizable string +// !!! L() is used only for marking localizable string // !!! It will be used in "xgettext" to create a Locating Message Catalog. #define L(s) s #endif /* L */ @@ -290,6 +290,12 @@ void Preset::normalize(DynamicPrintConfig &config) static_cast(opt)->values.resize(n, std::string()); } } + if (const auto *gap_fill_speed = config.option("gap_fill_speed", false); gap_fill_speed && gap_fill_speed->value <= 0.) { + // Legacy conversion. If the gap fill speed is zero, it means the gap fill is not enabled. + // Set the new gap_fill_enabled value, so that it will show up in the UI as disabled. + if (auto *gap_fill_enabled = config.option("gap_fill_enabled", false); gap_fill_enabled) + gap_fill_enabled->value = false; + } } std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config) @@ -386,7 +392,7 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config) } else if (type == TYPE_FILAMENT || type == TYPE_SLA_MATERIAL) { const std::string §ion_name = (type == TYPE_FILAMENT) ? AppConfig::SECTION_FILAMENTS : AppConfig::SECTION_MATERIALS; if (app_config.has_section(section_name)) { - // Check whether this profile is marked as "installed" in PrusaSlicer.ini, + // Check whether this profile is marked as "installed" in PrusaSlicer.ini, // or whether a profile is marked as "installed", which this profile may have been renamed from. const std::map &installed = app_config.get_section(section_name); auto has = [&installed](const std::string &name) { @@ -403,24 +409,25 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config) const std::vector& Preset::print_options() { static std::vector s_opts { - "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", + "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness", "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs", "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern", "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", - "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", + "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing", "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour", - "fuzzy_skin_perimeter_mode", /* "fuzzy_skin_shape", */ "fuzzy_skin_thickness", "fuzzy_skin_point_dist", + "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist", #ifdef HAS_PRESSURE_EQUALIZER "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", #endif /* HAS_PRESSURE_EQUALIZER */ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", - "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", + "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", "bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield", - "min_skirt_length", "brim_width", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", - "raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing", + "min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", + "raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion", + "support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance", "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius", @@ -485,7 +492,7 @@ const std::vector& Preset::printer_options() "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits", - "remaining_times", "silent_mode", + "remaining_times", "silent_mode", "machine_limits_usage", "thumbnails" }; s_opts.insert(s_opts.end(), Preset::machine_limits_options().begin(), Preset::machine_limits_options().end()); @@ -616,10 +623,6 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vector m_num_default_presets) { @@ -650,7 +653,7 @@ void PresetCollection::add_default_preset(const std::vector &keys, // Throws an exception on error. void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir) { - // Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points, + // Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points, // see https://github.com/prusa3d/PrusaSlicer/issues/732 boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred(); m_dir_path = dir.string(); @@ -974,7 +977,7 @@ const Preset* PresetCollection::get_selected_preset_parent() const // Resolve the "renamed_from" field. assert(! inherits.empty()); auto it = this->find_preset_renamed(inherits); - if (it != m_presets.end()) + if (it != m_presets.end()) preset = &(*it); } return (preset == nullptr/* || preset->is_default*/ || preset->is_external) ? nullptr : preset; @@ -989,17 +992,17 @@ const Preset* PresetCollection::get_preset_parent(const Preset& child) const const Preset* preset = this->find_preset(inherits, false); if (preset == nullptr) { auto it = this->find_preset_renamed(inherits); - if (it != m_presets.end()) + if (it != m_presets.end()) preset = &(*it); } - return + return // not found - (preset == nullptr/* || preset->is_default */|| + (preset == nullptr/* || preset->is_default */|| // this should not happen, user profile should not derive from an external profile preset->is_external || // this should not happen, however people are creative, see GH #4996 - preset == &child) ? - nullptr : + preset == &child) ? + nullptr : preset; } @@ -1026,7 +1029,7 @@ const std::string& PresetCollection::get_preset_name_by_alias(const std::string& // Continue over all profile names with the same alias. it != m_map_alias_to_profile_name.end() && it->first == alias; ++ it) if (auto it_preset = this->find_preset_internal(it->second); - it_preset != m_presets.end() && it_preset->name == it->second && + it_preset != m_presets.end() && it_preset->name == it->second && it_preset->is_visible && (it_preset->is_compatible || size_t(it_preset - m_presets.begin()) == m_idx_selected)) return it_preset->name; return alias; @@ -1096,7 +1099,7 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil some_compatible |= preset_edited.is_compatible; if (active_print != nullptr) preset_edited.is_compatible &= is_compatible_with_print(this_preset_with_vendor_profile, *active_print, active_printer); - if (! preset_edited.is_compatible && selected && + if (! preset_edited.is_compatible && selected && (unselect_if_incompatible == PresetSelectCompatibleType::Always || (unselect_if_incompatible == PresetSelectCompatibleType::OnlyIfWasCompatible && was_compatible))) m_idx_selected = size_t(-1); if (selected) @@ -1278,6 +1281,18 @@ std::vector PresetCollection::merge_presets(PresetCollection &&othe return duplicates; } +void PresetCollection::update_vendor_ptrs_after_copy(const VendorMap &new_vendors) +{ + for (Preset &preset : m_presets) + if (preset.vendor != nullptr) { + assert(! preset.is_default && ! preset.is_external); + // Re-assign a pointer to the vendor structure in the new PresetBundle. + auto it = new_vendors.find(preset.vendor->id); + assert(it != new_vendors.end()); + preset.vendor = &it->second; + } +} + void PresetCollection::update_map_alias_to_profile_name() { m_map_alias_to_profile_name.clear(); @@ -1425,13 +1440,13 @@ const std::set& PhysicalPrinter::get_preset_names() const return preset_names; } -bool PhysicalPrinter::has_empty_config() const +bool PhysicalPrinter::has_empty_config() const { - return config.opt_string("print_host" ).empty() && - config.opt_string("printhost_apikey" ).empty() && - config.opt_string("printhost_cafile" ).empty() && + return config.opt_string("print_host" ).empty() && + config.opt_string("printhost_apikey" ).empty() && + config.opt_string("printhost_cafile" ).empty() && config.opt_string("printhost_port" ).empty() && - config.opt_string("printhost_user" ).empty() && + config.opt_string("printhost_user" ).empty() && config.opt_string("printhost_password").empty(); } @@ -1443,7 +1458,7 @@ void PhysicalPrinter::update_preset_names_in_config() name += el + ";"; name.pop_back(); config.set_key_value("preset_name", new ConfigOptionString(name)); - } + } } void PhysicalPrinter::save(const std::string& file_name_from, const std::string& file_name_to) @@ -1492,7 +1507,7 @@ bool PhysicalPrinter::delete_preset(const std::string& preset_name) return preset_names.erase(preset_name) > 0; } -PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig& default_config) : +PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig& default_config) : name(name), config(default_config) { update_from_config(config); @@ -1549,7 +1564,7 @@ PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector PhysicalPrinterCollection::get_printers_with_preset(con for (auto printer : m_printers) { if (printer.preset_names.size() == 1) - continue; + continue; if (printer.preset_names.find(preset_name) != printer.preset_names.end()) printers.emplace_back(printer.name); } @@ -1879,7 +1894,7 @@ void PhysicalPrinterCollection::unselect_printer() bool PhysicalPrinterCollection::is_selected(PhysicalPrinterCollection::ConstIterator it, const std::string& preset_name) const { - return m_idx_selected == size_t(it - m_printers.begin()) && + return m_idx_selected == size_t(it - m_printers.begin()) && m_selected_preset == preset_name; } diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index b6d44d58ff..d81717f0e0 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -115,13 +115,11 @@ public: TYPE_COUNT, }; - Preset(Type type, const std::string &name, bool is_default = false) : type(type), is_default(is_default), name(name) {} - Type type = TYPE_INVALID; // The preset represents a "default" set of properties, // pulled from the default values of the PrintConfig (see PrintConfigDef for their definitions). - bool is_default; + bool is_default = false; // External preset points to a configuration, which has been loaded but not imported // into the Slic3r default configuration location. bool is_external = false; @@ -233,6 +231,9 @@ public: static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config); protected: + Preset(Type type, const std::string &name, bool is_default = false) : type(type), is_default(is_default), name(name) {} + Preset() = default; + friend class PresetCollection; friend class PresetBundle; }; @@ -256,7 +257,6 @@ class PresetCollection public: // Initialize the PresetCollection with the "- default -" preset. PresetCollection(Preset::Type type, const std::vector &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -"); - ~PresetCollection(); typedef std::deque::iterator Iterator; typedef std::deque::const_iterator ConstIterator; @@ -460,6 +460,15 @@ public: size_t num_default_presets() { return m_num_default_presets; } protected: + PresetCollection() = default; + // Copy constructor and copy operators are not to be used from outside PresetBundle, + // as the Profile::vendor points to an instance of VendorProfile stored at parent PresetBundle! + PresetCollection(const PresetCollection &other) = default; + PresetCollection& operator=(const PresetCollection &other) = default; + // After copying a collection with the default operators above, call this function + // to adjust Profile::vendor pointers. + void update_vendor_ptrs_after_copy(const VendorMap &vendors); + // Select a preset, if it exists. If it does not exist, select an invalid (-1) index. // This is a temporary state, which shall be fixed immediately by the following step. bool select_preset_by_name_strict(const std::string &name); @@ -474,10 +483,6 @@ protected: void update_map_system_profile_renamed(); private: - PresetCollection(); - PresetCollection(const PresetCollection &other); - PresetCollection& operator=(const PresetCollection &other); - // Find a preset position in the sorted list of presets. // The "-- default -- " preset is always the first, so it needs // to be handled differently. @@ -507,9 +512,9 @@ private: { return const_cast(this)->find_preset_renamed(name); } size_t update_compatible_internal(const PresetWithVendorProfile &active_printer, const PresetWithVendorProfile *active_print, PresetSelectCompatibleType unselect_if_incompatible); - +public: static std::vector dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false); - +private: // Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER. Preset::Type m_type; // List of presets, starting with the "- default -" preset. @@ -531,7 +536,7 @@ private: // Path to the directory to store the config files into. std::string m_dir_path; - // to access select_preset_by_name_strict() + // to access select_preset_by_name_strict() and the default & copy constructors. friend class PresetBundle; }; @@ -542,9 +547,17 @@ class PrinterPresetCollection : public PresetCollection public: PrinterPresetCollection(Preset::Type type, const std::vector &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -") : PresetCollection(type, keys, defaults, default_name) {} + const Preset& default_preset_for(const DynamicPrintConfig &config) const override; const Preset* find_by_model_id(const std::string &model_id) const; + +private: + PrinterPresetCollection() = default; + PrinterPresetCollection(const PrinterPresetCollection &other) = default; + PrinterPresetCollection& operator=(const PrinterPresetCollection &other) = default; + + friend class PresetBundle; }; namespace PresetUtils { @@ -634,7 +647,6 @@ class PhysicalPrinterCollection { public: PhysicalPrinterCollection(const std::vector& keys); - ~PhysicalPrinterCollection() {} typedef std::deque::iterator Iterator; typedef std::deque::const_iterator ConstIterator; @@ -725,7 +737,9 @@ public: const DynamicPrintConfig& default_config() const { return m_default_config; } private: - PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other); + friend class PresetBundle; + PhysicalPrinterCollection() = default; + PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other) = default; // Find a physical printer position in the sorted list of printers. // The name of a printer should be unique and case insensitive diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index d9b1ed76ef..7d08c93592 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -105,8 +105,33 @@ PresetBundle::PresetBundle() : this->project_config.apply_only(FullPrintConfig::defaults(), s_project_options); } -PresetBundle::~PresetBundle() +PresetBundle::PresetBundle(const PresetBundle &rhs) { + *this = rhs; +} + +PresetBundle& PresetBundle::operator=(const PresetBundle &rhs) +{ + prints = rhs.prints; + sla_prints = rhs.sla_prints; + filaments = rhs.filaments; + sla_materials = rhs.sla_materials; + printers = rhs.printers; + physical_printers = rhs.physical_printers; + + filament_presets = rhs.filament_presets; + project_config = rhs.project_config; + vendors = rhs.vendors; + obsolete_presets = rhs.obsolete_presets; + + // Adjust Preset::vendor pointers to point to the copied vendors map. + prints .update_vendor_ptrs_after_copy(this->vendors); + sla_prints .update_vendor_ptrs_after_copy(this->vendors); + filaments .update_vendor_ptrs_after_copy(this->vendors); + sla_materials.update_vendor_ptrs_after_copy(this->vendors); + printers .update_vendor_ptrs_after_copy(this->vendors); + + return *this; } void PresetBundle::reset(bool delete_files) @@ -890,7 +915,7 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const std::string bundle_name = std::string(" - ") + boost::filesystem::path(path).filename().string(); // 2) Extract active configs from the config bundle, copy them and activate them in this bundle. - auto load_one = [this, &path, &bundle_name](PresetCollection &collection_dst, PresetCollection &collection_src, const std::string &preset_name_src, bool activate) -> std::string { + auto load_one = [&path, &bundle_name](PresetCollection &collection_dst, PresetCollection &collection_src, const std::string &preset_name_src, bool activate) -> std::string { Preset *preset_src = collection_src.find_preset(preset_name_src, false); Preset *preset_dst = collection_dst.find_preset(preset_name_src, false); assert(preset_src != nullptr); @@ -1459,11 +1484,15 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri int operator()(const Preset &preset) const { - return (! m_prefered_alias.empty() && m_prefered_alias == preset.alias) ? - // Matching an alias, always take this preset with priority. - std::numeric_limits::max() : - // Otherwise take the prefered profile, or the first compatible. - preset.name == m_prefered_name; + return + preset.is_default || preset.is_external ? + // Don't match any properties of the "-- default --" profile or the external profiles when switching printer profile. + 0 : + ! m_prefered_alias.empty() && m_prefered_alias == preset.alias ? + // Matching an alias, always take this preset with priority. + std::numeric_limits::max() : + // Otherwise take the prefered profile, or the first compatible. + preset.name == m_prefered_name; } private: @@ -1475,11 +1504,14 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri class PreferedPrintProfileMatch : public PreferedProfileMatch { public: - PreferedPrintProfileMatch(const Preset &preset, const std::string &prefered_name) : - PreferedProfileMatch(preset.alias, prefered_name), m_prefered_layer_height(preset.config.opt_float("layer_height")) {} + PreferedPrintProfileMatch(const Preset *preset, const std::string &prefered_name) : + PreferedProfileMatch(preset ? preset->alias : std::string(), prefered_name), m_prefered_layer_height(preset ? preset->config.opt_float("layer_height") : 0) {} int operator()(const Preset &preset) const { + // Don't match any properties of the "-- default --" profile or the external profiles when switching printer profile. + if (preset.is_default || preset.is_external) + return 0; int match_quality = PreferedProfileMatch::operator()(preset); if (match_quality < std::numeric_limits::max()) { match_quality += 1; @@ -1503,6 +1535,9 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri int operator()(const Preset &preset) const { + // Don't match any properties of the "-- default --" profile or the external profiles when switching printer profile. + if (preset.is_default || preset.is_external) + return 0; int match_quality = PreferedProfileMatch::operator()(preset); if (match_quality < std::numeric_limits::max()) { match_quality += 1; @@ -1520,14 +1555,17 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri class PreferedFilamentsProfileMatch { public: - PreferedFilamentsProfileMatch(const Preset &preset, const std::vector &prefered_names) : - m_prefered_alias(preset.alias), - m_prefered_filament_type(preset.config.opt_string("filament_type", 0)), + PreferedFilamentsProfileMatch(const Preset *preset, const std::vector &prefered_names) : + m_prefered_alias(preset ? preset->alias : std::string()), + m_prefered_filament_type(preset ? preset->config.opt_string("filament_type", 0) : std::string()), m_prefered_names(prefered_names) {} int operator()(const Preset &preset) const { + // Don't match any properties of the "-- default --" profile or the external profiles when switching printer profile. + if (preset.is_default || preset.is_external) + return 0; if (! m_prefered_alias.empty() && m_prefered_alias == preset.alias) // Matching an alias, always take this preset with priority. return std::numeric_limits::max(); @@ -1550,7 +1588,7 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri assert(printer_preset.config.has("default_filament_profile")); const std::vector &prefered_filament_profiles = printer_preset.config.option("default_filament_profile")->values; this->prints.update_compatible(printer_preset_with_vendor_profile, nullptr, select_other_print_if_incompatible, - PreferedPrintProfileMatch(this->prints.get_edited_preset(), printer_preset.config.opt_string("default_print_profile"))); + PreferedPrintProfileMatch(this->prints.get_selected_idx() == size_t(-1) ? nullptr : &this->prints.get_edited_preset(), printer_preset.config.opt_string("default_print_profile"))); const PresetWithVendorProfile print_preset_with_vendor_profile = this->prints.get_edited_preset_with_vendor_profile(); // Remember whether the filament profiles were compatible before updating the filament compatibility. std::vector filament_preset_was_compatible(this->filament_presets.size(), false); @@ -1560,7 +1598,7 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri } // First select a first compatible profile for the preset editor. this->filaments.update_compatible(printer_preset_with_vendor_profile, &print_preset_with_vendor_profile, select_other_filament_if_incompatible, - PreferedFilamentsProfileMatch(this->filaments.get_edited_preset(), prefered_filament_profiles)); + PreferedFilamentsProfileMatch(this->filaments.get_selected_idx() == size_t(-1) ? nullptr : &this->filaments.get_edited_preset(), prefered_filament_profiles)); if (select_other_filament_if_incompatible != PresetSelectCompatibleType::Never) { // Verify validity of the current filament presets. const std::string prefered_filament_profile = prefered_filament_profiles.empty() ? std::string() : prefered_filament_profiles.front(); @@ -1587,10 +1625,10 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri assert(printer_preset.config.has("default_sla_print_profile")); assert(printer_preset.config.has("default_sla_material_profile")); this->sla_prints.update_compatible(printer_preset_with_vendor_profile, nullptr, select_other_print_if_incompatible, - PreferedPrintProfileMatch(this->sla_prints.get_edited_preset(), printer_preset.config.opt_string("default_sla_print_profile"))); + PreferedPrintProfileMatch(this->sla_prints.get_selected_idx() == size_t(-1) ? nullptr : &this->sla_prints.get_edited_preset(), printer_preset.config.opt_string("default_sla_print_profile"))); const PresetWithVendorProfile sla_print_preset_with_vendor_profile = this->sla_prints.get_edited_preset_with_vendor_profile(); this->sla_materials.update_compatible(printer_preset_with_vendor_profile, &sla_print_preset_with_vendor_profile, select_other_filament_if_incompatible, - PreferedProfileMatch(this->sla_materials.get_edited_preset().alias, printer_preset.config.opt_string("default_sla_material_profile"))); + PreferedProfileMatch(this->sla_materials.get_selected_idx() == size_t(-1) ? std::string() : this->sla_materials.get_edited_preset().alias, printer_preset.config.opt_string("default_sla_material_profile"))); break; } default: break; diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 5d7cc84ba2..5902d42088 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -15,7 +15,8 @@ class PresetBundle { public: PresetBundle(); - ~PresetBundle(); + PresetBundle(const PresetBundle &rhs); + PresetBundle& operator=(const PresetBundle &rhs); // Remove all the presets but the "-- default --". // Optionally remove all the files referenced by the presets from the user profile directory. @@ -25,8 +26,7 @@ public: // Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets. // Load selections (current print, current filaments, current printer) from config.ini - // This is done just once on application start up. - void load_presets(AppConfig &config, const std::string &preferred_model_id = ""); + void load_presets(AppConfig &config, const std::string &preferred_model_id = std::string()); // Export selections (current print, current filaments, current printer) into config.ini void export_selections(AppConfig &config); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d50ff19e8a..643cc9a970 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1,8 +1,7 @@ -#include "clipper/clipper_z.hpp" - #include "Exception.hpp" #include "Print.hpp" #include "BoundingBox.hpp" +#include "Brim.hpp" #include "ClipperUtils.hpp" #include "Extruder.hpp" #include "Flow.hpp" @@ -15,8 +14,6 @@ #include "GCode/WipeTower.hpp" #include "Utils.hpp" -//#include "PrintExport.hpp" - #include #include @@ -62,7 +59,7 @@ PrintRegion* Print::add_region(const PrintRegionConfig &config) // Called by Print::apply(). // This method only accepts PrintConfig option keys. -bool Print::invalidate_state_by_config_options(const std::vector &opt_keys) +bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* new_config */, const std::vector &opt_keys) { if (opt_keys.empty()) return false; @@ -174,9 +171,6 @@ bool Print::invalidate_state_by_config_options(const std::vectorinvalidate_state_by_config_options(print_diff)); + update_apply_status(this->invalidate_state_by_config_options(new_full_config, print_diff)); // Apply variables to placeholder parser. The placeholder parser is used by G-code export, // which should be stopped if print_diff is not empty. @@ -797,7 +791,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } if (deleted_any) { // Delete PrintObjects of the deleted ModelObjects. - std::vector print_objects_old = std::move(m_objects); + PrintObjectPtrs print_objects_old = std::move(m_objects); m_objects.clear(); m_objects.reserve(print_objects_old.size()); for (PrintObject *print_object : print_objects_old) { @@ -902,7 +896,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (auto it = range.first; it != range.second; ++ it) { t_config_option_keys diff = it->print_object->config().diff(new_config); if (! diff.empty()) { - update_apply_status(it->print_object->invalidate_state_by_config_options(diff)); + update_apply_status(it->print_object->invalidate_state_by_config_options(it->print_object->config(), new_config, diff)); it->print_object->config_apply_only(new_config, diff, true); } } @@ -945,7 +939,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // 4) Generate PrintObjects from ModelObjects and their instances. { - std::vector print_objects_new; + PrintObjectPtrs print_objects_new; print_objects_new.reserve(std::max(m_objects.size(), m_model.objects.size())); bool new_objects = false; // Walk over all new model objects and check, whether there are matching PrintObjects. @@ -1091,10 +1085,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ if (this_region_config_set) { t_config_option_keys diff = region.config().diff(this_region_config); if (! diff.empty()) { - region.config_apply_only(this_region_config, diff, false); + // Stop the background process before assigning new configuration to the regions. for (PrintObject *print_object : m_objects) if (region_id < print_object->region_volumes.size() && ! print_object->region_volumes[region_id].empty()) - update_apply_status(print_object->invalidate_state_by_config_options(diff)); + update_apply_status(print_object->invalidate_state_by_config_options(region.config(), this_region_config, diff)); + region.config_apply_only(this_region_config, diff, false); } } } @@ -1188,6 +1183,11 @@ bool Print::has_skirt() const return (m_config.skirt_height > 0 && m_config.skirts > 0) || this->has_infinite_skirt(); } +bool Print::has_brim() const +{ + return std::any_of(m_objects.begin(), m_objects.end(), [](PrintObject *object) { return object->has_brim(); }); +} + static inline bool sequential_print_horizontal_clearance_valid(const Print &print) { Polygons convex_hulls_other; @@ -1399,7 +1399,7 @@ std::string Print::validate() const return L("One or more object were assigned an extruder that the printer does not have."); #endif - auto validate_extrusion_width = [min_nozzle_diameter, max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool { + auto validate_extrusion_width = [/*min_nozzle_diameter,*/ max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool { // This may change in the future, if we switch to "extrusion width wrt. nozzle diameter" // instead of currently used logic "extrusion width wrt. layer height", see GH issues #1923 #2829. // double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter); @@ -1418,7 +1418,7 @@ std::string Print::validate() const return true; }; for (PrintObject *object : m_objects) { - if (object->config().raft_layers > 0 || object->config().support_material.value) { + if (object->has_support_material()) { if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && max_nozzle_diameter - min_nozzle_diameter > EPSILON) { // The object has some form of support and either support_material_extruder or support_material_interface_extruder // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles @@ -1444,7 +1444,7 @@ std::string Print::validate() const // validate first_layer_height double first_layer_height = object->config().get_abs_value("first_layer_height"); double first_layer_min_nozzle_diameter; - if (object->config().raft_layers > 0) { + if (object->has_raft()) { // if we have raft layers, only support material extruder is used on first layer size_t first_layer_extruder = object->config().raft_layers == 1 ? object->config().support_material_interface_extruder-1 @@ -1468,7 +1468,7 @@ std::string Print::validate() const std::string err_msg; if (! validate_extrusion_width(object->config(), "extrusion_width", layer_height, err_msg)) return err_msg; - if ((object->config().support_material || object->config().raft_layers > 0) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg)) + if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg)) return err_msg; for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" }) for (size_t i = 0; i < object->region_volumes.size(); ++ i) @@ -1655,9 +1655,12 @@ void Print::process() if (this->set_started(psBrim)) { m_brim.clear(); m_first_layer_convex_hull.points.clear(); - if (m_config.brim_width > 0) { + if (this->has_brim()) { this->set_status(88, L("Generating brim")); - this->_make_brim(); + Polygons islands_area; + m_brim = make_brim(*this, this->make_try_cancel(), islands_area); + for (Polygon &poly : union_(this->first_layer_islands(), islands_area)) + append(m_first_layer_convex_hull.points, std::move(poly.points)); } // Brim depends on skirt (brim lines are trimmed by the skirt lines), therefore if // the skirt gets invalidated, brim gets invalidated as well and the following line is called. @@ -1728,8 +1731,7 @@ void Print::_make_skirt() for (const SupportLayer *layer : object->support_layers()) { if (layer->print_z > skirt_height_z) break; - for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities) - append(object_points, extrusion_entity->as_polyline().points); + layer->support_fills.collect_points(object_points); } // Repeat points for each object copy. for (const PrintInstance &instance : object->instances()) { @@ -1831,164 +1833,6 @@ void Print::_make_skirt() append(m_skirt_convex_hull, std::move(poly.points)); } -void Print::_make_brim() -{ - // Brim is only printed on first layer and uses perimeter extruder. - Polygons islands = this->first_layer_islands(); - Polygons loops; - Flow flow = this->brim_flow(); - size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing())); - for (size_t i = 0; i < num_loops; ++ i) { - this->throw_if_canceled(); - islands = offset(islands, float(flow.scaled_spacing()), jtSquare); - for (Polygon &poly : islands) { - // poly.simplify(SCALED_RESOLUTION); - poly.points.push_back(poly.points.front()); - Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION); - p.pop_back(); - poly.points = std::move(p); - } - if (i + 1 == num_loops) { - // Remember the outer edge of the last brim line extruded as m_first_layer_convex_hull. - for (Polygon &poly : islands) - append(m_first_layer_convex_hull.points, poly.points); - } - polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing()))); - } - loops = union_pt_chained_outside_in(loops, false); - - // If there is a possibility that brim intersects skirt, go through loops and split those extrusions - // The result is either the original Polygon or a list of Polylines - if (! m_skirt.empty() && m_config.skirt_distance.value < m_config.brim_width) - { - // Find the bounding polygons of the skirt - const Polygons skirt_inners = offset(dynamic_cast(m_skirt.entities.back())->polygon(), - -float(scale_(this->skirt_flow().spacing()))/2.f, - ClipperLib::jtRound, - float(scale_(0.1))); - const Polygons skirt_outers = offset(dynamic_cast(m_skirt.entities.front())->polygon(), - float(scale_(this->skirt_flow().spacing()))/2.f, - ClipperLib::jtRound, - float(scale_(0.1))); - - // First calculate the trimming region. - ClipperLib_Z::Paths trimming; - { - ClipperLib_Z::Paths input_subject; - ClipperLib_Z::Paths input_clip; - for (const Polygon &poly : skirt_outers) { - input_subject.emplace_back(); - ClipperLib_Z::Path &out = input_subject.back(); - out.reserve(poly.points.size()); - for (const Point &pt : poly.points) - out.emplace_back(pt.x(), pt.y(), 0); - } - for (const Polygon &poly : skirt_inners) { - input_clip.emplace_back(); - ClipperLib_Z::Path &out = input_clip.back(); - out.reserve(poly.points.size()); - for (const Point &pt : poly.points) - out.emplace_back(pt.x(), pt.y(), 0); - } - // init Clipper - ClipperLib_Z::Clipper clipper; - // add polygons - clipper.AddPaths(input_subject, ClipperLib_Z::ptSubject, true); - clipper.AddPaths(input_clip, ClipperLib_Z::ptClip, true); - // perform operation - clipper.Execute(ClipperLib_Z::ctDifference, trimming, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd); - } - - // Second, trim the extrusion loops with the trimming regions. - ClipperLib_Z::Paths loops_trimmed; - { - // Produce a closed polyline (repeat the first point at the end). - ClipperLib_Z::Paths input_clip; - for (const Polygon &loop : loops) { - input_clip.emplace_back(); - ClipperLib_Z::Path& out = input_clip.back(); - out.reserve(loop.points.size()); - int64_t loop_idx = &loop - &loops.front(); - for (const Point& pt : loop.points) - // The Z coordinate carries index of the source loop. - out.emplace_back(pt.x(), pt.y(), loop_idx + 1); - out.emplace_back(out.front()); - } - // init Clipper - ClipperLib_Z::Clipper clipper; - clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot, const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) { - // Assign a valid input loop identifier. Such an identifier is strictly positive, the next line is safe even in case one side of a segment - // hat the Z coordinate not set to the contour coordinate. - pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z)); - }); - // add polygons - clipper.AddPaths(input_clip, ClipperLib_Z::ptSubject, false); - clipper.AddPaths(trimming, ClipperLib_Z::ptClip, true); - // perform operation - ClipperLib_Z::PolyTree loops_trimmed_tree; - clipper.Execute(ClipperLib_Z::ctDifference, loops_trimmed_tree, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd); - ClipperLib_Z::PolyTreeToPaths(loops_trimmed_tree, loops_trimmed); - } - - // Third, produce the extrusions, sorted by the source loop indices. - { - std::vector> loops_trimmed_order; - loops_trimmed_order.reserve(loops_trimmed.size()); - for (const ClipperLib_Z::Path &path : loops_trimmed) { - size_t input_idx = 0; - for (const ClipperLib_Z::IntPoint &pt : path) - if (pt.Z > 0) { - input_idx = (size_t)pt.Z; - break; - } - assert(input_idx != 0); - loops_trimmed_order.emplace_back(&path, input_idx); - } - std::stable_sort(loops_trimmed_order.begin(), loops_trimmed_order.end(), - [](const std::pair &l, const std::pair &r) { - return l.second < r.second; - }); - - Point last_pt(0, 0); - for (size_t i = 0; i < loops_trimmed_order.size();) { - // Find all pieces that the initial loop was split into. - size_t j = i + 1; - for (; j < loops_trimmed_order.size() && loops_trimmed_order[i].second == loops_trimmed_order[j].second; ++ j) ; - const ClipperLib_Z::Path &first_path = *loops_trimmed_order[i].first; - if (i + 1 == j && first_path.size() > 3 && first_path.front().X == first_path.back().X && first_path.front().Y == first_path.back().Y) { - auto *loop = new ExtrusionLoop(); - m_brim.entities.emplace_back(loop); - loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height())); - Points &points = loop->paths.front().polyline.points; - points.reserve(first_path.size()); - for (const ClipperLib_Z::IntPoint &pt : first_path) - points.emplace_back(coord_t(pt.X), coord_t(pt.Y)); - i = j; - } else { - //FIXME The path chaining here may not be optimal. - ExtrusionEntityCollection this_loop_trimmed; - this_loop_trimmed.entities.reserve(j - i); - for (; i < j; ++ i) { - this_loop_trimmed.entities.emplace_back(new ExtrusionPath(erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()))); - const ClipperLib_Z::Path &path = *loops_trimmed_order[i].first; - Points &points = static_cast(this_loop_trimmed.entities.back())->polyline.points; - points.reserve(path.size()); - for (const ClipperLib_Z::IntPoint &pt : path) - points.emplace_back(coord_t(pt.X), coord_t(pt.Y)); - } - chain_and_reorder_extrusion_entities(this_loop_trimmed.entities, &last_pt); - m_brim.entities.reserve(m_brim.entities.size() + this_loop_trimmed.entities.size()); - append(m_brim.entities, std::move(this_loop_trimmed.entities)); - this_loop_trimmed.entities.clear(); - } - last_pt = m_brim.last_point(); - } - } - } else { - extrusion_entities_append_loops(m_brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height())); - } -} - Polygons Print::first_layer_islands() const { Polygons islands; @@ -2104,8 +1948,8 @@ void Print::_make_wipe_tower() if (idx_begin != size_t(-1)) { // Find the position in m_objects.first()->support_layers to insert these new support layers. double wipe_tower_new_layer_print_z_first = m_wipe_tower_data.tool_ordering.layer_tools()[idx_begin].print_z; - SupportLayerPtrs::const_iterator it_layer = m_objects.front()->support_layers().begin(); - SupportLayerPtrs::const_iterator it_end = m_objects.front()->support_layers().end(); + auto it_layer = m_objects.front()->support_layers().begin(); + auto it_end = m_objects.front()->support_layers().end(); for (; it_layer != it_end && (*it_layer)->print_z - EPSILON < wipe_tower_new_layer_print_z_first; ++ it_layer); // Find the stopper of the sequence of wipe tower layers, which do not have a counterpart in an object or a support layer. for (size_t i = idx_begin; i < idx_end; ++ i) { diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 281ce35bc0..e8e81a5295 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -73,7 +73,7 @@ public: // Collect 0-based extruder indices used to print this region's object. void collect_object_printing_extruders(std::vector &object_extruders) const; - static void collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, std::vector &object_extruders); + static void collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, const bool has_brim, std::vector &object_extruders); // Methods modifying the PrintRegion's state: public: @@ -95,9 +95,39 @@ private: ~PrintRegion() = default; }; +template +class ConstVectorOfPtrsAdaptor { +public: + // Returning a non-const pointer to const pointers to T. + T * const * begin() const { return m_data->data(); } + T * const * end() const { return m_data->data() + m_data->size(); } + const T* front() const { return m_data->front(); } + const T* back() const { return m_data->front(); } + size_t size() const { return m_data->size(); } + bool empty() const { return m_data->empty(); } + const T* operator[](size_t i) const { return (*m_data)[i]; } + const T* at(size_t i) const { return m_data->at(i); } + std::vector vector() const { return std::vector(this->begin(), this->end()); } +protected: + ConstVectorOfPtrsAdaptor(const std::vector *data) : m_data(data) {} +private: + const std::vector *m_data; +}; + +typedef std::vector LayerPtrs; +typedef std::vector ConstLayerPtrs; +class ConstLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor { + friend PrintObject; + ConstLayerPtrsAdaptor(const LayerPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} +}; + +typedef std::vector SupportLayerPtrs; +typedef std::vector ConstSupportLayerPtrs; +class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor { + friend PrintObject; + ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} +}; -typedef std::vector LayerPtrs; -typedef std::vector SupportLayerPtrs; class BoundingBoxf3; // TODO: for temporary constructor parameter // Single instance of a PrintObject. @@ -125,21 +155,28 @@ public: std::vector>> region_volumes; // Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane. - const Vec3crd& size() const { return m_size; } - const PrintObjectConfig& config() const { return m_config; } - const LayerPtrs& layers() const { return m_layers; } - const SupportLayerPtrs& support_layers() const { return m_support_layers; } - const Transform3d& trafo() const { return m_trafo; } - const PrintInstances& instances() const { return m_instances; } + const Vec3crd& size() const { return m_size; } + const PrintObjectConfig& config() const { return m_config; } + ConstLayerPtrsAdaptor layers() const { return ConstLayerPtrsAdaptor(&m_layers); } + ConstSupportLayerPtrsAdaptor support_layers() const { return ConstSupportLayerPtrsAdaptor(&m_support_layers); } + const Transform3d& trafo() const { return m_trafo; } + const PrintInstances& instances() const { return m_instances; } + + // Whoever will get a non-const pointer to PrintObject will be able to modify its layers. + LayerPtrs& layers() { return m_layers; } + SupportLayerPtrs& support_layers() { return m_support_layers; } // Bounding box is used to align the object infill patterns, and to calculate attractor for the rear seam. // The bounding box may not be quite snug. - BoundingBox bounding_box() const { return BoundingBox(Point(- m_size.x() / 2, - m_size.y() / 2), Point(m_size.x() / 2, m_size.y() / 2)); } + BoundingBox bounding_box() const { return BoundingBox(Point(- m_size.x() / 2, - m_size.y() / 2), Point(m_size.x() / 2, m_size.y() / 2)); } // Height is used for slicing, for sorting the objects by height for sequential printing and for checking vertical clearence in sequential print mode. // The height is snug. - coord_t height() const { return m_size.z(); } + coord_t height() const { return m_size.z(); } // Centering offset of the sliced mesh from the scaled and rotated mesh of the model. - const Point& center_offset() const { return m_center_offset; } + const Point& center_offset() const { return m_center_offset; } + + bool has_brim() const { return this->config().brim_type != btNoBrim && this->config().brim_width.value > 0.; } + // adds region_id, too, if necessary void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) { @@ -165,14 +202,14 @@ public: const Layer* get_first_layer_bellow_printz(coordf_t print_z, coordf_t epsilon) const; // print_z: top of the layer; slice_z: center of the layer. - Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); + Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); - size_t support_layer_count() const { return m_support_layers.size(); } - void clear_support_layers(); - SupportLayer* get_support_layer(int idx) { return m_support_layers[idx]; } - SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z); - SupportLayerPtrs::const_iterator insert_support_layer(SupportLayerPtrs::const_iterator pos, size_t id, coordf_t height, coordf_t print_z, coordf_t slice_z); - void delete_support_layer(int idx); + size_t support_layer_count() const { return m_support_layers.size(); } + void clear_support_layers(); + SupportLayer* get_support_layer(int idx) { return m_support_layers[idx]; } + SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z); + SupportLayerPtrs::iterator insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, coordf_t height, coordf_t print_z, coordf_t slice_z); + void delete_support_layer(int idx); // Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters. // Returns true, if the layer_height_profile was changed. @@ -185,6 +222,10 @@ public: const SlicingParameters& slicing_parameters() const { return m_slicing_params; } static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z); + bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; } + bool has_raft() const { return m_config.raft_layers > 0; } + bool has_support_material() const { return this->has_support() || this->has_raft(); } + // returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions) std::vector object_extruders() const; @@ -214,7 +255,9 @@ private: // Invalidates all PrintObject and Print steps. bool invalidate_all_steps(); // Invalidate steps based on a set of parameters changed. - bool invalidate_state_by_config_options(const std::vector &opt_keys); + // It may be called for both the PrintObjectConfig and PrintRegionConfig. + bool invalidate_state_by_config_options( + const ConfigOptionResolver &old_config, const ConfigOptionResolver &new_config, const std::vector &opt_keys); // If ! m_slicing_params.valid, recalculate. void update_slicing_parameters(); @@ -231,7 +274,7 @@ private: void _slice(const std::vector &layer_height_profile); std::string _fix_slicing_errors(); void simplify_slices(double distance); - bool has_support_material() const; + // Has any support (not counting the raft). void detect_surfaces_type(); void process_external_surfaces(); void discover_vertical_shells(); @@ -344,14 +387,27 @@ struct PrintStatistics } }; -typedef std::vector PrintObjectPtrs; -typedef std::vector PrintRegionPtrs; +typedef std::vector PrintObjectPtrs; +typedef std::vector ConstPrintObjectPtrs; +class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor { + friend Print; + ConstPrintObjectPtrsAdaptor(const PrintObjectPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} +}; + +typedef std::vector PrintRegionPtrs; +typedef std::vector ConstPrintRegionPtrs; +class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor { + friend Print; + ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} +}; // The complete print tray with possibly multiple objects. class Print : public PrintBaseWithState { private: // Prevents erroneous use by other classes. typedef PrintBaseWithState Inherited; + // Bool indicates if supports of PrintObject are top-level contour. + typedef std::pair PrintObjectInfo; public: Print() = default; @@ -385,6 +441,7 @@ public: bool has_infinite_skirt() const; bool has_skirt() const; + bool has_brim() const; // Returns an empty string if valid, otherwise returns an error message. std::string validate() const override; @@ -403,9 +460,8 @@ public: const PrintConfig& config() const { return m_config; } const PrintObjectConfig& default_object_config() const { return m_default_object_config; } const PrintRegionConfig& default_region_config() const { return m_default_region_config; } - //FIXME returning const vector to non-const PrintObject*, caller could modify PrintObjects! - const PrintObjectPtrs& objects() const { return m_objects; } - PrintObject* get_object(size_t idx) { return m_objects[idx]; } + ConstPrintObjectPtrsAdaptor objects() const { return ConstPrintObjectPtrsAdaptor(&m_objects); } + PrintObject* get_object(size_t idx) { return const_cast(m_objects[idx]); } const PrintObject* get_object(size_t idx) const { return m_objects[idx]; } // PrintObject by its ObjectID, to be used to uniquely bind slicing warnings to their source PrintObjects // in the notification center. @@ -414,11 +470,15 @@ public: [object_id](const PrintObject *obj) { return obj->id() == object_id; }); return (it == m_objects.end()) ? nullptr : *it; } - const PrintRegionPtrs& regions() const { return m_regions; } + ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); } // How many of PrintObject::copies() over all print objects are there? // If zero, then the print is empty and the print shall not be executed. unsigned int num_object_instances() const; + // For Perl bindings. + PrintObjectPtrs& objects_mutable() { return m_objects; } + PrintRegionPtrs& regions_mutable() { return m_regions; } + const ExtrusionEntityCollection& skirt() const { return m_skirt; } const ExtrusionEntityCollection& brim() const { return m_brim; } // Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line. @@ -458,10 +518,9 @@ private: t_config_option_keys &full_config_diff, DynamicPrintConfig &filament_overrides) const; - bool invalidate_state_by_config_options(const std::vector &opt_keys); + bool invalidate_state_by_config_options(const ConfigOptionResolver &new_config, const std::vector &opt_keys); void _make_skirt(); - void _make_brim(); void _make_wipe_tower(); void finalize_first_layer_convex_hull(); diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp index fb5e102c1a..721741d4a8 100644 --- a/src/libslic3r/PrintBase.cpp +++ b/src/libslic3r/PrintBase.cpp @@ -13,6 +13,11 @@ namespace Slic3r { +void PrintTryCancel::operator()() +{ + m_print->throw_if_canceled(); +} + size_t PrintStateBase::g_last_timestamp = 0; // Update "scale", "input_filename", "input_filename_base" placeholders from the current m_objects. diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index bfbabd06b5..8fca43319a 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -324,6 +324,20 @@ protected: ModelObject *m_model_object; }; +// Wrapper around the private PrintBase.throw_if_canceled(), so that a cancellation object could be passed +// to a non-friend of PrintBase by a PrintBase derived object. +class PrintTryCancel +{ +public: + // calls print.throw_if_canceled(). + void operator()(); +private: + friend PrintBase; + PrintTryCancel() = delete; + PrintTryCancel(const PrintBase *print) : m_print(print) {} + const PrintBase *m_print; +}; + /** * @brief Printing involves slicing and export of device dependent instructions. * @@ -472,6 +486,8 @@ protected: // If the background processing stop was requested, throw CanceledException. // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly. void throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); } + // Wrapper around this->throw_if_canceled(), so that throw_if_canceled() may be passed to a function without making throw_if_canceled() public. + PrintTryCancel make_try_cancel() const { return PrintTryCancel(this); } // To be called by this->output_filename() with the format string pulled from the configuration layer. std::string output_filename(const std::string &format, const std::string &default_ext, const std::string &filename_base, const DynamicConfig *config_override = nullptr) const; @@ -495,6 +511,8 @@ private: // The mutex will be used to guard the worker thread against entering a stage // while the data influencing the stage is modified. mutable tbb::mutex m_state_mutex; + + friend PrintTryCancel; }; template diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 587c22cc6e..b272dbfba3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -298,12 +298,37 @@ void PrintConfigDef::init_fff_params() def = this->add("brim_width", coFloat); def->label = L("Brim width"); + def->category = L("Skirt and brim"); def->tooltip = L("Horizontal width of the brim that will be printed around each object on the first layer."); def->sidetext = L("mm"); def->min = 0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("brim_type", coEnum); + def->label = L("Brim type"); + def->category = L("Skirt and brim"); + def->tooltip = L("The places where the brim will be printed around each object on the first layer."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.emplace_back("no_brim"); + def->enum_values.emplace_back("outer_only"); + def->enum_values.emplace_back("inner_only"); + def->enum_values.emplace_back("outer_and_inner"); + def->enum_labels.emplace_back(L("No brim")); + def->enum_labels.emplace_back(L("Outer brim only")); + def->enum_labels.emplace_back(L("Inner brim only")); + def->enum_labels.emplace_back(L("Outer and inner brim")); + def->mode = comSimple; + def->set_default_value(new ConfigOptionEnum(btOuterOnly)); + + def = this->add("brim_offset", coFloat); + def->label = L("Brim offset"); + def->category = L("Skirt and brim"); + def->tooltip = L("The offset of the brim from the printed object."); + def->sidetext = L("mm"); + def->mode = comSimple; + def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("clip_multipart_objects", coBool); def->label = L("Clip multi-part objects"); def->tooltip = L("When printing multi-material objects, this settings will make Slic3r " @@ -1007,56 +1032,25 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionInts { 0 }); - def = this->add("fuzzy_skin_perimeter_mode", coEnum); - def->label = L("Fuzzy skin perimeter mode"); + def = this->add("fuzzy_skin", coEnum); + def->label = L("Fuzzy Skin"); def->category = L("Fuzzy Skin"); - def->tooltip = L("Fuzzy skin perimeter mode."); + def->tooltip = L("Fuzzy skin type."); - def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("none"); - def->enum_values.push_back("external_only"); - def->enum_values.push_back("external_only_skip_first_layer"); + def->enum_values.push_back("external"); def->enum_values.push_back("all"); def->enum_labels.push_back(L("None")); - def->enum_labels.push_back(L("External")); - def->enum_labels.push_back(L("External (skip first layer)")); + def->enum_labels.push_back(L("External perimeters")); def->enum_labels.push_back(L("All perimeters")); def->mode = comSimple; - def->set_default_value(new ConfigOptionEnum(FuzzySkinPerimeterMode::None)); - -/* - def = this->add("fuzzy_skin_shape", coEnum); - def->label = L("Fuzzy skin shape"); - def->category = L("Fuzzy Skin"); - def->tooltip = L("Fuzzy skin shape."); - - def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); - def->enum_values.push_back("triangle1"); - def->enum_values.push_back("triangle2"); - def->enum_values.push_back("triangle3"); - def->enum_values.push_back("sawtooth1"); - def->enum_values.push_back("sawtooth2"); - def->enum_values.push_back("sawtooth3"); - def->enum_values.push_back("random1"); - def->enum_values.push_back("random2"); - def->enum_values.push_back("random3"); - def->enum_labels.push_back(L("Triangle (1)")); - def->enum_labels.push_back(L("Triangle (2)")); - def->enum_labels.push_back(L("Triangle (3)")); - def->enum_labels.push_back(L("Sawtooth (1)")); - def->enum_labels.push_back(L("Sawtooth (2)")); - def->enum_labels.push_back(L("Sawtooth (3)")); - def->enum_labels.push_back(L("Random (1)")); - def->enum_labels.push_back(L("Random (2)")); - def->enum_labels.push_back(L("Random (3)")); - def->mode = comSimple; - def->set_default_value(new ConfigOptionEnum(FuzzySkinShape::Triangle1)); -*/ + def->set_default_value(new ConfigOptionEnum(FuzzySkinType::None)); def = this->add("fuzzy_skin_thickness", coFloat); def->label = L("Fuzzy skin thickness"); def->category = L("Fuzzy Skin"); - def->tooltip = L(""); + def->tooltip = ""; def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; @@ -1065,12 +1059,19 @@ void PrintConfigDef::init_fff_params() def = this->add("fuzzy_skin_point_dist", coFloat); def->label = L("Fuzzy skin point distance"); def->category = L("Fuzzy Skin"); - def->tooltip = L(""); + def->tooltip = ""; def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.8)); + def = this->add("gap_fill_enabled", coBool); + def->label = L("Fill gaps"); + def->category = L("Layers and Perimeters"); + def->tooltip = L("Enables filling of gaps between perimeters and between the inner most perimeters and infill."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(true)); + def = this->add("gap_fill_speed", coFloat); def->label = L("Gap fill"); def->category = L("Speed"); @@ -1774,6 +1775,43 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; + def = this->add("raft_contact_distance", coFloat); + def->label = L("Raft contact Z distance"); + def->category = L("Support material"); + def->tooltip = L("The vertical distance between object and raft. Ignored for soluble interface."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.1)); + + def = this->add("raft_expansion", coFloat); + def->label = L("Raft expansion"); + def->category = L("Support material"); + def->tooltip = L("Expansion of the raft in XY plane for better stability."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(1.5)); + + def = this->add("raft_first_layer_density", coPercent); + def->label = L("First layer density"); + def->category = L("Support material"); + def->tooltip = L("Density of the first raft or support layer."); + def->sidetext = L("%"); + def->min = 0; + def->max = 150; + def->mode = comExpert; + def->set_default_value(new ConfigOptionPercent(90)); + + def = this->add("raft_first_layer_expansion", coFloat); + def->label = L("First layer expansion"); + def->category = L("Support material"); + def->tooltip = L("Expansion of the first raft or support layer to improve adhesion to print bed."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(3.)); + def = this->add("raft_layers", coInt); def->label = L("Raft layers"); def->category = L("Support material"); @@ -3325,7 +3363,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va #ifndef HAS_PRESSURE_EQUALIZER , "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", #endif /* HAS_PRESSURE_EQUALIZER */ - "serial_port", "serial_speed" + "serial_port", "serial_speed", + // Introduced in some PrusaSlicer 2.3.1 alpha, later renamed or removed. + "fuzzy_skin_perimeter_mode", "fuzzy_skin_shape", }; // In PrusaSlicer 2.3.0-alpha0 the "monotonous" infill was introduced, which was later renamed to "monotonic". diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e2f71a9415..aa63e723a6 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -43,27 +43,12 @@ enum AuthorizationType { atKeyPassword, atUserPassword }; -enum class FuzzySkinPerimeterMode { +enum class FuzzySkinType { None, External, - ExternalSkipFirst, - All + All, }; -/* -enum class FuzzySkinShape { - Triangle1, - Triangle2, - Triangle3, - Sawtooth1, - Sawtooth2, - Sawtooth3, - Random1, - Random2, - Random3 -}; -*/ - enum InfillPattern : int { ipRectilinear, ipMonotonic, ipAlignedRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb, ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipSupportCubic, ipCount, @@ -103,6 +88,13 @@ enum SLAPillarConnectionMode { slapcmDynamic }; +enum BrimType { + btNoBrim, + btOuterOnly, + btInnerOnly, + btOuterAndInner, +}; + template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { @@ -161,35 +153,16 @@ template<> inline const t_config_enum_values& ConfigOptionEnum inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { +template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { - keys_map["none"] = int(FuzzySkinPerimeterMode::None); - keys_map["external_only"] = int(FuzzySkinPerimeterMode::External); - keys_map["external_only_skip_first_layer"] = int(FuzzySkinPerimeterMode::ExternalSkipFirst); - keys_map["all"] = int(FuzzySkinPerimeterMode::All); + keys_map["none"] = int(FuzzySkinType::None); + keys_map["external"] = int(FuzzySkinType::External); + keys_map["all"] = int(FuzzySkinType::All); } return keys_map; } -/* -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["triangle1"] = int(FuzzySkinShape::Triangle1); - keys_map["triangle2"] = int(FuzzySkinShape::Triangle2); - keys_map["triangle3"] = int(FuzzySkinShape::Triangle3); - keys_map["sawtooth1"] = int(FuzzySkinShape::Sawtooth1); - keys_map["sawtooth2"] = int(FuzzySkinShape::Sawtooth2); - keys_map["sawtooth3"] = int(FuzzySkinShape::Sawtooth3); - keys_map["random1"] = int(FuzzySkinShape::Random1); - keys_map["random2"] = int(FuzzySkinShape::Random2); - keys_map["random3"] = int(FuzzySkinShape::Random3); - } - return keys_map; -} -*/ - template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { @@ -264,6 +237,17 @@ template<> inline const t_config_enum_values& ConfigOptionEnum inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { + static const t_config_enum_values keys_map = { + {"no_brim", btNoBrim}, + {"outer_only", btOuterOnly}, + {"inner_only", btInnerOnly}, + {"outer_and_inner", btOuterAndInner} + }; + + return keys_map; +} + // Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs. // Does not store the actual values, but defines default values. class PrintConfigDef : public ConfigDef @@ -477,19 +461,22 @@ class PrintObjectConfig : public StaticPrintConfig { STATIC_PRINT_CONFIG_CACHE(PrintObjectConfig) public: + ConfigOptionFloat brim_offset; + ConfigOptionEnum brim_type; + ConfigOptionFloat brim_width; ConfigOptionBool clip_multipart_objects; ConfigOptionBool dont_support_bridges; ConfigOptionFloat elefant_foot_compensation; ConfigOptionFloatOrPercent extrusion_width; ConfigOptionFloatOrPercent first_layer_height; - ConfigOptionEnum fuzzy_skin_perimeter_mode; -// ConfigOptionEnum fuzzy_skin_shape; - ConfigOptionFloat fuzzy_skin_thickness; - ConfigOptionFloat fuzzy_skin_point_dist; ConfigOptionBool infill_only_where_needed; // Force the generation of solid shells between adjacent materials/volumes. ConfigOptionBool interface_shells; ConfigOptionFloat layer_height; + ConfigOptionFloat raft_contact_distance; + ConfigOptionFloat raft_expansion; + ConfigOptionPercent raft_first_layer_density; + ConfigOptionFloat raft_first_layer_expansion; ConfigOptionInt raft_layers; ConfigOptionEnum seam_position; // ConfigOptionFloat seam_preferred_direction; @@ -526,18 +513,21 @@ public: protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { + OPT_PTR(brim_offset); + OPT_PTR(brim_type); + OPT_PTR(brim_width); OPT_PTR(clip_multipart_objects); OPT_PTR(dont_support_bridges); OPT_PTR(elefant_foot_compensation); OPT_PTR(extrusion_width); OPT_PTR(first_layer_height); - OPT_PTR(fuzzy_skin_perimeter_mode); -// OPT_PTR(fuzzy_skin_shape); - OPT_PTR(fuzzy_skin_thickness); - OPT_PTR(fuzzy_skin_point_dist); OPT_PTR(infill_only_where_needed); OPT_PTR(interface_shells); OPT_PTR(layer_height); + OPT_PTR(raft_contact_distance); + OPT_PTR(raft_expansion); + OPT_PTR(raft_first_layer_density); + OPT_PTR(raft_first_layer_expansion); OPT_PTR(raft_layers); OPT_PTR(seam_position); OPT_PTR(slice_closing_radius); @@ -588,6 +578,10 @@ public: ConfigOptionFloat fill_angle; ConfigOptionPercent fill_density; ConfigOptionEnum fill_pattern; + ConfigOptionEnum fuzzy_skin; + ConfigOptionFloat fuzzy_skin_thickness; + ConfigOptionFloat fuzzy_skin_point_dist; + ConfigOptionBool gap_fill_enabled; ConfigOptionFloat gap_fill_speed; ConfigOptionFloatOrPercent infill_anchor; ConfigOptionFloatOrPercent infill_anchor_max; @@ -641,6 +635,10 @@ protected: OPT_PTR(fill_angle); OPT_PTR(fill_density); OPT_PTR(fill_pattern); + OPT_PTR(fuzzy_skin); + OPT_PTR(fuzzy_skin_thickness); + OPT_PTR(fuzzy_skin_point_dist); + OPT_PTR(gap_fill_enabled); OPT_PTR(gap_fill_speed); OPT_PTR(infill_anchor); OPT_PTR(infill_anchor_max); @@ -891,7 +889,6 @@ public: ConfigOptionInts bed_temperature; ConfigOptionFloat bridge_acceleration; ConfigOptionInts bridge_fan_speed; - ConfigOptionFloat brim_width; ConfigOptionBool complete_objects; ConfigOptionFloats colorprint_heights; ConfigOptionBools cooling; @@ -966,7 +963,6 @@ protected: OPT_PTR(bed_temperature); OPT_PTR(bridge_acceleration); OPT_PTR(bridge_fan_speed); - OPT_PTR(brim_width); OPT_PTR(complete_objects); OPT_PTR(colorprint_heights); OPT_PTR(cooling); @@ -1098,7 +1094,7 @@ public: // The percentage of smaller pillars compared to the normal pillar diameter // which are used in problematic areas where a normal pilla cannot fit. ConfigOptionPercent support_small_pillar_diameter_percent; - + // How much bridge (supporting another pinhead) can be placed on a pillar. ConfigOptionInt support_max_bridges_on_pillar; @@ -1150,7 +1146,7 @@ public: // The height of the pad from the bottom to the top not considering the pit ConfigOptionFloat pad_wall_height /*= 5*/; - + // How far should the pad extend around the contained geometry ConfigOptionFloat pad_brim_size; @@ -1174,7 +1170,7 @@ public: // Disable the elevation (ignore its value) and use the zero elevation mode ConfigOptionBool pad_around_object; - + ConfigOptionBool pad_around_object_everywhere; // This is the gap between the object bottom and the generated pad @@ -1188,7 +1184,7 @@ public: // How much should the tiny connectors penetrate into the model body ConfigOptionFloat pad_object_connector_penetration; - + // ///////////////////////////////////////////////////////////////////////// // Model hollowing parameters: // - Models can be hollowed out as part of the SLA print process @@ -1197,17 +1193,17 @@ public: // - Additional holes will be drilled into the hollow model to allow for // - resin removal. // ///////////////////////////////////////////////////////////////////////// - + ConfigOptionBool hollowing_enable; - - // The minimum thickness of the model walls to maintain. Note that the + + // The minimum thickness of the model walls to maintain. Note that the // resulting walls may be thicker due to smoothing out fine cavities where // resin could stuck. ConfigOptionFloat hollowing_min_thickness; - + // Indirectly controls the voxel size (resolution) used by openvdb ConfigOptionFloat hollowing_quality; - + // Indirectly controls the minimum size of created cavities. ConfigOptionFloat hollowing_closing_distance; @@ -1429,13 +1425,13 @@ Points get_bed_shape(const SLAPrinterConfig &cfg); // ModelConfig is a wrapper around DynamicPrintConfig with an addition of a timestamp. // Each change of ModelConfig is tracked by assigning a new timestamp from a global counter. // The counter is used for faster synchronization of the background slicing thread -// with the front end by skipping synchronization of equal config dictionaries. -// The global counter is also used for avoiding unnecessary serialization of config +// with the front end by skipping synchronization of equal config dictionaries. +// The global counter is also used for avoiding unnecessary serialization of config // dictionaries when taking an Undo snapshot. // // The global counter is NOT thread safe, therefore it is recommended to use ModelConfig from // the main thread only. -// +// // As there is a global counter and it is being increased with each change to any ModelConfig, // if two ModelConfig dictionaries differ, they should differ with their timestamp as well. // Therefore copying the ModelConfig including its timestamp is safe as there is no harm diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 543a45846b..53403024e4 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -399,7 +399,8 @@ void PrintObject::ironing() if (this->set_started(posIroning)) { BOOST_LOG_TRIVIAL(debug) << "Ironing in parallel - start"; tbb::parallel_for( - tbb::blocked_range(1, m_layers.size()), + // Ironing starting with layer 0 to support ironing all surfaces. + tbb::blocked_range(0, m_layers.size()), [this](const tbb::blocked_range& range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); @@ -417,7 +418,7 @@ void PrintObject::generate_support_material() { if (this->set_started(posSupportMaterial)) { this->clear_support_layers(); - if ((m_config.support_material || m_config.raft_layers > 0) && m_layers.size() > 1) { + if (this->has_support_material() && m_layers.size() > 1) { m_print->set_status(85, L("Generating support material")); this->_generate_support_material(); m_print->throw_if_canceled(); @@ -501,14 +502,15 @@ SupportLayer* PrintObject::add_support_layer(int id, coordf_t height, coordf_t p return m_support_layers.back(); } -SupportLayerPtrs::const_iterator PrintObject::insert_support_layer(SupportLayerPtrs::const_iterator pos, size_t id, coordf_t height, coordf_t print_z, coordf_t slice_z) +SupportLayerPtrs::iterator PrintObject::insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, coordf_t height, coordf_t print_z, coordf_t slice_z) { return m_support_layers.insert(pos, new SupportLayer(id, this, height, print_z, slice_z)); } // Called by Print::apply(). // This method only accepts PrintObjectConfig and PrintRegionConfig option keys. -bool PrintObject::invalidate_state_by_config_options(const std::vector &opt_keys) +bool PrintObject::invalidate_state_by_config_options( + const ConfigOptionResolver &old_config, const ConfigOptionResolver &new_config, const std::vector &opt_keys) { if (opt_keys.empty()) return false; @@ -516,13 +518,19 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector steps; bool invalidated = false; for (const t_config_option_key &opt_key : opt_keys) { - if ( opt_key == "perimeters" + if ( opt_key == "brim_width" + || opt_key == "brim_offset" + || opt_key == "brim_type") { + // Brim is printed below supports, support invalidates brim and skirt. + steps.emplace_back(posSupportMaterial); + } else if ( + opt_key == "perimeters" || opt_key == "extra_perimeters" + || opt_key == "gap_fill_enabled" || opt_key == "gap_fill_speed" || opt_key == "overhangs" || opt_key == "first_layer_extrusion_width" - || opt_key == "fuzzy_skin_perimeter_mode" -// || opt_key == "fuzzy_skin_shape" + || opt_key == "fuzzy_skin" || opt_key == "fuzzy_skin_thickness" || opt_key == "fuzzy_skin_point_dist" || opt_key == "perimeter_extrusion_width" @@ -534,6 +542,7 @@ bool PrintObject::invalidate_state_by_config_options(const std::vectorconfig().spiral_vase) { + if (m_print->config().spiral_vase) { // Changing the number of bottom layers when a spiral vase is enabled requires re-slicing the object again. // Otherwise, holes in the bottom layers could be filled, as is reported in GH #5528. steps.emplace_back(posSlice); @@ -604,9 +616,19 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector(opt_key); + const auto *new_density = new_config.option(opt_key); + assert(old_density && new_density); + //FIXME Vojtech is not quite sure about the 100% here, maybe it is not needed. + if (is_approx(old_density->value, 0.) || is_approx(old_density->value, 100.) || + is_approx(new_density->value, 0.) || is_approx(new_density->value, 100.)) + steps.emplace_back(posPerimeters); + steps.emplace_back(posPrepareInfill); + } else if (opt_key == "solid_infill_extrusion_width") { + // This value is used for calculating perimeter - infill overlap, thus perimeters need to be recalculated. steps.emplace_back(posPerimeters); steps.emplace_back(posPrepareInfill); } else if ( @@ -695,13 +717,6 @@ bool PrintObject::invalidate_all_steps() return result; } -bool PrintObject::has_support_material() const -{ - return m_config.support_material - || m_config.raft_layers > 0 - || m_config.support_material_enforce_layers > 0; -} - static const PrintRegion* first_printing_region(const PrintObject &print_object) { for (size_t idx_region = 0; idx_region < print_object.region_volumes.size(); ++ idx_region) @@ -753,14 +768,10 @@ void PrintObject::detect_surfaces_type() // In non-spiral vase mode, go over all layers. m_layers.size()), [this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range& range) { - // If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void. - SurfaceType surface_type_bottom_1st = - (m_config.raft_layers.value > 0 && m_config.support_material_contact_distance.value > 0) ? - stBottomBridge : stBottom; // If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating // the support from the print. SurfaceType surface_type_bottom_other = - (m_config.support_material.value && m_config.support_material_contact_distance.value == 0) ? + (this->has_support() && m_config.support_material_contact_distance.value == 0) ? stBottom : stBottomBridge; for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); @@ -835,7 +846,7 @@ void PrintObject::detect_surfaces_type() // we clone surfaces because we're going to clear the slices collection bottom = layerm->slices.surfaces; for (Surface &surface : bottom) - surface.surface_type = surface_type_bottom_1st; + surface.surface_type = stBottom; } // now, if the object contained a thin membrane, we could have overlapping bottom @@ -908,7 +919,7 @@ void PrintObject::detect_surfaces_type() // Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces. tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), - [this, idx_region, interface_shells](const tbb::blocked_range& range) { + [this, idx_region](const tbb::blocked_range& range) { for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); LayerRegion *layerm = m_layers[idx_layer]->m_regions[idx_region]; @@ -1601,6 +1612,12 @@ PrintRegionConfig PrintObject::region_config_from_model_volume(const PrintRegion clamp_exturder_to_default(config.infill_extruder, num_extruders); clamp_exturder_to_default(config.perimeter_extruder, num_extruders); clamp_exturder_to_default(config.solid_infill_extruder, num_extruders); + if (config.fill_density.value < 0.00011f) + // Switch of infill for very low infill rates, also avoid division by zero in infill generator for these very low rates. + // See GH issue #5910. + config.fill_density.value = 0; + else + config.fill_density.value = std::min(config.fill_density.value, 100.); return config; } @@ -1628,6 +1645,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full PrintRegion::collect_object_printing_extruders( print_config, region_config_from_model_volume(default_region_config, nullptr, *model_volume, num_extruders), + object_config.brim_type != btNoBrim && object_config.brim_width > 0., object_extruders); for (const std::pair &range_and_config : model_object.layer_config_ranges) if (range_and_config.second.has("perimeter_extruder") || @@ -1636,6 +1654,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full PrintRegion::collect_object_printing_extruders( print_config, region_config_from_model_volume(default_region_config, &range_and_config.second.get(), *model_volume, num_extruders), + object_config.brim_type != btNoBrim && object_config.brim_width > 0., object_extruders); } sort_remove_duplicates(object_extruders); @@ -1721,7 +1740,7 @@ void PrintObject::_slice(const std::vector &layer_height_profile) } // Make sure all layers contain layer region objects for all regions. for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) - layer->add_region(this->print()->regions()[region_id]); + layer->add_region(this->print()->get_region(region_id)); prev = layer; } } @@ -1924,7 +1943,7 @@ end: BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin"; { // Compensation value, scaled. - const float xy_compensation_scaled = float(scale_(m_config.xy_size_compensation.value)); + const float xy_compensation_scaled = float(scale_(m_config.xy_size_compensation.value)); const float elephant_foot_compensation_scaled = (m_config.raft_layers == 0) ? // Only enable Elephant foot compensation if printing directly on the print bed. float(scale_(m_config.elefant_foot_compensation.value)) : @@ -2781,8 +2800,9 @@ void PrintObject::project_and_append_custom_facets( const Transform3f& tr1 = mv->get_matrix().cast(); const Transform3f& tr2 = this->trafo().cast(); const Transform3f tr = tr2 * tr1; - const float tr_det_sign = (tr.matrix().determinant() > 0. ? 1.f : -1.f); - + const float tr_det_sign = (tr.matrix().determinant() > 0. ? 1.f : -1.f); + const Vec2f center = unscaled(this->center_offset()); + ConstLayerPtrsAdaptor layers = this->layers(); // The projection will be at most a pentagon. Let's minimize heap // reallocations by saving in in the following struct. @@ -2790,10 +2810,17 @@ void PrintObject::project_and_append_custom_facets( // and they can be moved from to create an ExPolygon later. struct LightPolygon { LightPolygon() { pts.reserve(5); } + LightPolygon(const std::array& tri) { + pts.reserve(3); + pts.emplace_back(scaled(tri.front())); + pts.emplace_back(scaled(tri[1])); + pts.emplace_back(scaled(tri.back())); + } + Points pts; void add(const Vec2f& pt) { - pts.emplace_back(scale_(pt.x()), scale_(pt.y())); + pts.emplace_back(scaled(pt)); assert(pts.size() <= 5); } }; @@ -2811,7 +2838,7 @@ void PrintObject::project_and_append_custom_facets( // Iterate over all triangles. tbb::parallel_for( tbb::blocked_range(0, custom_facets.indices.size()), - [&](const tbb::blocked_range& range) { + [center, &custom_facets, &tr, tr_det_sign, seam, layers, &projections_of_triangles](const tbb::blocked_range& range) { for (size_t idx = range.begin(); idx < range.end(); ++ idx) { std::array facet; @@ -2825,6 +2852,11 @@ void PrintObject::project_and_append_custom_facets( if (! seam && tr_det_sign * z_comp > 0.) continue; + // The algorithm does not process vertical triangles, but it should for seam. + // In that case, tilt the triangle a bit so the projection does not degenerate. + if (seam && z_comp == 0.f) + facet[0].x() += float(EPSILON); + // Sort the three vertices according to z-coordinate. std::sort(facet.begin(), facet.end(), [](const Vec3f& pt1, const Vec3f&pt2) { @@ -2832,30 +2864,43 @@ void PrintObject::project_and_append_custom_facets( }); std::array trianglef; - for (int i=0; i<3; ++i) { - trianglef[i] = Vec2f(facet[i].x(), facet[i].y()); - trianglef[i] -= Vec2f(unscale(this->center_offset().x()), - unscale(this->center_offset().y())); - } + for (int i=0; i<3; ++i) + trianglef[i] = to_2d(facet[i]) - center; // Find lowest slice not below the triangle. - auto it = std::lower_bound(layers().begin(), layers().end(), facet[0].z()+EPSILON, + auto it = std::lower_bound(layers.begin(), layers.end(), facet[0].z()+EPSILON, [](const Layer* l1, float z) { return l1->slice_z < z; }); // Count how many projections will be generated for this triangle // and allocate respective amount in projections_of_triangles. - projections_of_triangles[idx].first_layer_id = it-layers().begin(); - size_t last_layer_id = projections_of_triangles[idx].first_layer_id; + size_t first_layer_id = projections_of_triangles[idx].first_layer_id = it - layers.begin(); + size_t last_layer_id = first_layer_id; // The cast in the condition below is important. The comparison must // be an exact opposite of the one lower in the code where // the polygons are appended. And that one is on floats. - while (last_layer_id + 1 < layers().size() - && float(layers()[last_layer_id]->slice_z) <= facet[2].z()) + while (last_layer_id + 1 < layers.size() + && float(layers[last_layer_id]->slice_z) <= facet[2].z()) ++last_layer_id; - projections_of_triangles[idx].polygons.resize( - last_layer_id - projections_of_triangles[idx].first_layer_id + 1); + + if (first_layer_id == last_layer_id) { + // The triangle fits just a single slab, just project it. This also avoids division by zero for horizontal triangles. + float dz = facet[2].z() - facet[0].z(); + assert(dz >= 0); + // The face is nearly horizontal and it crosses the slicing plane at first_layer_id - 1. + // Rather add this face to both the planes. + bool add_below = dz < float(2. * EPSILON) && first_layer_id > 0 && layers[first_layer_id - 1]->slice_z > facet[0].z() - EPSILON; + projections_of_triangles[idx].polygons.reserve(add_below ? 2 : 1); + projections_of_triangles[idx].polygons.emplace_back(trianglef); + if (add_below) { + -- projections_of_triangles[idx].first_layer_id; + projections_of_triangles[idx].polygons.emplace_back(trianglef); + } + continue; + } + + projections_of_triangles[idx].polygons.resize(last_layer_id - first_layer_id + 1); // Calculate how to move points on triangle sides per unit z increment. Vec2f ta(trianglef[1] - trianglef[0]); @@ -2871,7 +2916,7 @@ void PrintObject::project_and_append_custom_facets( bool stop = false; // Project a sub-polygon on all slices intersecting the triangle. - while (it != layers().end()) { + while (it != layers.end()) { const float z = float((*it)->slice_z); // Projections of triangle sides intersections with slices. @@ -2889,7 +2934,7 @@ void PrintObject::project_and_append_custom_facets( } // This slice is above the triangle already. - if (z > facet[2].z() || it+1 == layers().end()) { + if (z > facet[2].z() || it+1 == layers.end()) { proj->add(trianglef[2]); stop = true; } @@ -2919,14 +2964,19 @@ void PrintObject::project_and_append_custom_facets( }); // end of parallel_for // Make sure that the output vector can be used. - expolys.resize(layers().size()); + expolys.resize(layers.size()); // Now append the collected polygons to respective layers. for (auto& trg : projections_of_triangles) { int layer_id = int(trg.first_layer_id); - for (const LightPolygon& poly : trg.polygons) { + for (LightPolygon &poly : trg.polygons) { if (layer_id >= int(expolys.size())) break; // part of triangle could be projected above top layer + assert(! poly.pts.empty()); + // The resulting triangles are fed to the Clipper library, which seem to handle flipped triangles well. +// if (cross2(Vec2d((poly.pts[1] - poly.pts[0]).cast()), Vec2d((poly.pts[2] - poly.pts[1]).cast())) < 0) +// std::swap(poly.pts.front(), poly.pts.back()); + expolys[layer_id].emplace_back(std::move(poly.pts)); ++layer_id; } diff --git a/src/libslic3r/PrintRegion.cpp b/src/libslic3r/PrintRegion.cpp index 2a75cd621d..79eb647f66 100644 --- a/src/libslic3r/PrintRegion.cpp +++ b/src/libslic3r/PrintRegion.cpp @@ -66,7 +66,7 @@ coordf_t PrintRegion::bridging_height_avg(const PrintConfig &print_config) const return this->nozzle_dmr_avg(print_config) * sqrt(m_config.bridge_flow_ratio.value); } -void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, std::vector &object_extruders) +void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, const bool has_brim, std::vector &object_extruders) { // These checks reflect the same logic used in the GUI for enabling/disabling extruder selection fields. auto num_extruders = (int)print_config.nozzle_diameter.size(); @@ -74,7 +74,7 @@ void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_con int i = std::max(0, extruder_id - 1); object_extruders.emplace_back((i >= num_extruders) ? 0 : i); }; - if (region_config.perimeters.value > 0 || print_config.brim_width.value > 0) + if (region_config.perimeters.value > 0 || has_brim) emplace_extruder(region_config.perimeter_extruder); if (region_config.fill_density.value > 0) emplace_extruder(region_config.infill_extruder); @@ -92,7 +92,7 @@ void PrintRegion::collect_object_printing_extruders(std::vector &o assert(this->config().infill_extruder <= num_extruders); assert(this->config().solid_infill_extruder <= num_extruders); #endif - collect_object_printing_extruders(print()->config(), this->config(), object_extruders); + collect_object_printing_extruders(print()->config(), this->config(), print()->has_brim(), object_extruders); } } diff --git a/src/libslic3r/SLA/AGGRaster.hpp b/src/libslic3r/SLA/AGGRaster.hpp index 917f718e98..849cec30a1 100644 --- a/src/libslic3r/SLA/AGGRaster.hpp +++ b/src/libslic3r/SLA/AGGRaster.hpp @@ -136,7 +136,7 @@ public: const TColor & background, GammaFn && gammafn) : m_resolution(res) - , m_pxdim_scaled(SCALING_FACTOR / pd.w_mm, SCALING_FACTOR / pd.h_mm) + , m_pxdim_scaled(SCALING_FACTOR, SCALING_FACTOR) , m_buf(res.pixels()) , m_rbuf(reinterpret_cast(m_buf.data()), unsigned(res.width_px), @@ -147,6 +147,12 @@ public: , m_renderer(m_raw_renderer) , m_trafo(trafo) { + // Visual Studio compiler gives warnings about possible division by zero. + assert(pd.w_mm != 0 && pd.h_mm != 0); + if (pd.w_mm != 0 && pd.h_mm != 0) { + m_pxdim_scaled.w_mm /= pd.w_mm; + m_pxdim_scaled.h_mm /= pd.h_mm; + } m_renderer.color(foreground); clear(background); diff --git a/src/libslic3r/SLA/Concurrency.hpp b/src/libslic3r/SLA/Concurrency.hpp index 300024c76d..b692914aca 100644 --- a/src/libslic3r/SLA/Concurrency.hpp +++ b/src/libslic3r/SLA/Concurrency.hpp @@ -41,7 +41,7 @@ template<> struct _ccr static void for_each(It from, It to, Fn &&fn, size_t granularity = 1) { tbb::parallel_for(tbb::blocked_range{from, to, granularity}, - [&fn, from](const auto &range) { + [&fn](const auto &range) { loop_(range, std::forward(fn)); }); } diff --git a/src/libslic3r/SLA/IndexedMesh.cpp b/src/libslic3r/SLA/IndexedMesh.cpp index efcf09873e..485fa98ed8 100644 --- a/src/libslic3r/SLA/IndexedMesh.cpp +++ b/src/libslic3r/SLA/IndexedMesh.cpp @@ -55,8 +55,6 @@ public: } }; -static const constexpr double MESH_EPS = 1e-6; - IndexedMesh::IndexedMesh(const TriangleMesh& tmesh) : m_aabb(new AABBImpl()), m_tm(&tmesh) { diff --git a/src/libslic3r/SLA/RasterBase.hpp b/src/libslic3r/SLA/RasterBase.hpp index 431c731a66..9f9f29cd52 100644 --- a/src/libslic3r/SLA/RasterBase.hpp +++ b/src/libslic3r/SLA/RasterBase.hpp @@ -80,8 +80,8 @@ public: /// Types that represents the dimension of a pixel in millimeters. struct PixelDim { - double w_mm = 0.; - double h_mm = 0.; + double w_mm = 1.; + double h_mm = 1.; PixelDim(double px_width_mm = 0.0, double px_height_mm = 0.0) : w_mm(px_width_mm), h_mm(px_height_mm) diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index 9378977663..702690c196 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -165,7 +165,7 @@ XYRotation from_transform3d(const Transform3d &tr) template std::array find_min_score(Fn &&fn, It from, It to, StopCond &&stopfn) { - std::array ret; + std::array ret = {}; double score = std::numeric_limits::max(); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index f69ed7b8e9..742670e2cb 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -424,7 +424,7 @@ public: void clear() override; bool empty() const override { return m_objects.empty(); } // List of existing PrintObject IDs, to remove notifications for non-existent IDs. - std::vector print_object_ids() const; + std::vector print_object_ids() const override; ApplyStatus apply(const Model &model, DynamicPrintConfig config) override; void set_task(const TaskParams ¶ms) override; void process() override; diff --git a/src/libslic3r/SVG.cpp b/src/libslic3r/SVG.cpp index da30a197fc..7308d7e50c 100644 --- a/src/libslic3r/SVG.cpp +++ b/src/libslic3r/SVG.cpp @@ -319,31 +319,67 @@ void SVG::export_expolygons(const char *path, const BoundingBox &bbox, const Sli svg.Close(); } +// Paint the expolygons in the order they are presented, thus the latter overwrites the former expolygon. +// 1) Paint all areas with the provided ExPolygonAttributes::color_fill and ExPolygonAttributes::fill_opacity. +// 2) Optionally paint outlines of the areas if ExPolygonAttributes::outline_width > 0. +// Paint with ExPolygonAttributes::color_contour and ExPolygonAttributes::color_holes. +// If color_contour is empty, color_fill is used. If color_hole is empty, color_contour is used. +// 3) Optionally paint points of all expolygon contours with ExPolygonAttributes::radius_points if radius_points > 0. +// 4) Paint ExPolygonAttributes::legend into legend using the ExPolygonAttributes::color_fill if legend is not empty. void SVG::export_expolygons(const char *path, const std::vector> &expolygons_with_attributes) { if (expolygons_with_attributes.empty()) return; + size_t num_legend = std::count_if(expolygons_with_attributes.begin(), expolygons_with_attributes.end(), [](const auto &v){ return ! v.second.legend.empty(); }); + // Format in num_columns. + size_t num_columns = 3; + // Width of the column. + coord_t step_x = scale_(20.); + Point legend_size(scale_(1.) + num_columns * step_x, scale_(0.4 + 1.3 * (num_legend + num_columns - 1) / num_columns)); + BoundingBox bbox = get_extents(expolygons_with_attributes.front().first); for (size_t i = 0; i < expolygons_with_attributes.size(); ++ i) bbox.merge(get_extents(expolygons_with_attributes[i].first)); + // Legend y. + coord_t pos_y = bbox.max.y() + scale_(1.5); + bbox.merge(Point(std::max(bbox.min.x() + legend_size.x(), bbox.max.x()), bbox.max.y() + legend_size.y())); SVG svg(path, bbox); for (const auto &exp_with_attr : expolygons_with_attributes) svg.draw(exp_with_attr.first, exp_with_attr.second.color_fill, exp_with_attr.second.fill_opacity); for (const auto &exp_with_attr : expolygons_with_attributes) { - std::string color_contour = exp_with_attr.second.color_contour; - if (color_contour.empty()) - color_contour = exp_with_attr.second.color_fill; - std::string color_holes = exp_with_attr.second.color_holes; - if (color_holes.empty()) - color_holes = color_contour; - svg.draw_outline(exp_with_attr.first, color_contour, color_holes, exp_with_attr.second.outline_width); + if (exp_with_attr.second.outline_width > 0) { + std::string color_contour = exp_with_attr.second.color_contour; + if (color_contour.empty()) + color_contour = exp_with_attr.second.color_fill; + std::string color_holes = exp_with_attr.second.color_holes; + if (color_holes.empty()) + color_holes = color_contour; + svg.draw_outline(exp_with_attr.first, color_contour, color_holes, exp_with_attr.second.outline_width); + } } for (const auto &exp_with_attr : expolygons_with_attributes) if (exp_with_attr.second.radius_points > 0) for (const ExPolygon &expoly : exp_with_attr.first) svg.draw((Points)expoly, exp_with_attr.second.color_points, exp_with_attr.second.radius_points); + + // Export legend. + // 1st row + coord_t pos_x0 = bbox.min.x() + scale_(1.); + coord_t pos_x = pos_x0; + size_t i_legend = 0; + for (const auto &exp_with_attr : expolygons_with_attributes) { + if (! exp_with_attr.second.legend.empty()) { + svg.draw_legend(Point(pos_x, pos_y), exp_with_attr.second.legend.c_str(), exp_with_attr.second.color_fill.c_str()); + if ((++ i_legend) % num_columns == 0) { + pos_x = pos_x0; + pos_y += scale_(1.3); + } else { + pos_x += step_x; + } + } + } svg.Close(); } diff --git a/src/libslic3r/SVG.hpp b/src/libslic3r/SVG.hpp index 1ebd8d918e..da9dca093a 100644 --- a/src/libslic3r/SVG.hpp +++ b/src/libslic3r/SVG.hpp @@ -102,7 +102,7 @@ public: ExPolygonAttributes(color, color, color) {} ExPolygonAttributes( - const std::string &color_fill, + const std::string &color_fill, const std::string &color_contour, const std::string &color_holes, const coord_t outline_width = scale_(0.05), @@ -118,16 +118,54 @@ public: radius_points (radius_points) {} + ExPolygonAttributes( + const std::string &legend, + const std::string &color_fill, + const std::string &color_contour, + const std::string &color_holes, + const coord_t outline_width = scale_(0.05), + const float fill_opacity = 0.5f, + const std::string &color_points = "black", + const coord_t radius_points = 0) : + legend (legend), + color_fill (color_fill), + color_contour (color_contour), + color_holes (color_holes), + outline_width (outline_width), + fill_opacity (fill_opacity), + color_points (color_points), + radius_points (radius_points) + {} + + ExPolygonAttributes( + const std::string &legend, + const std::string &color_fill, + const float fill_opacity) : + legend (legend), + color_fill (color_fill), + fill_opacity (fill_opacity) + {} + + std::string legend; std::string color_fill; std::string color_contour; std::string color_holes; std::string color_points; - coord_t outline_width; + coord_t outline_width { 0 }; float fill_opacity; - coord_t radius_points; + coord_t radius_points { 0 }; }; + // Paint the expolygons in the order they are presented, thus the latter overwrites the former expolygon. + // 1) Paint all areas with the provided ExPolygonAttributes::color_fill and ExPolygonAttributes::fill_opacity. + // 2) Optionally paint outlines of the areas if ExPolygonAttributes::outline_width > 0. + // Paint with ExPolygonAttributes::color_contour and ExPolygonAttributes::color_holes. + // If color_contour is empty, color_fill is used. If color_hole is empty, color_contour is used. + // 3) Optionally paint points of all expolygon contours with ExPolygonAttributes::radius_points if radius_points > 0. + // 4) Paint ExPolygonAttributes::legend into legend using the ExPolygonAttributes::color_fill if legend is not empty. static void export_expolygons(const char *path, const std::vector> &expolygons_with_attributes); + static void export_expolygons(const std::string &path, const std::vector> &expolygons_with_attributes) + { export_expolygons(path.c_str(), expolygons_with_attributes); } private: static float to_svg_coord(float x) throw() { return unscale(x) * 10.f; } diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index facedec3fb..449ff45b53 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -75,7 +75,7 @@ std::vector> chain_segments_greedy_constrained_reversals { // Just sort the end points so that the first point visited is closest to start_near. out.emplace_back(0, could_reverse_func(0) && start_near != nullptr && - (end_point_func(0, true) - *start_near).template cast().squaredNorm() < (end_point_func(0, false) - *start_near).template cast().squaredNorm()); + (end_point_func(0, false) - *start_near).template cast().squaredNorm() < (end_point_func(0, true) - *start_near).template cast().squaredNorm()); } else { @@ -1083,6 +1083,7 @@ void svg_draw_polyline_chain(const char *name, size_t idx, const Polylines &poly } #endif /* DEBUG_SVG_OUTPUT */ +#if 0 // Flip the sequences of polylines to lower the total length of connecting lines. static inline void improve_ordering_by_segment_flipping(Polylines &polylines, bool fixed_start) { @@ -1253,6 +1254,7 @@ static inline void improve_ordering_by_segment_flipping(Polylines &polylines, bo assert(cost_final <= cost_initial); #endif /* NDEBUG */ } +#endif struct FlipEdge { FlipEdge(const Vec2d &p1, const Vec2d &p2, size_t source_index) : p1(p1), p2(p2), source_index(source_index) {} @@ -1337,6 +1339,7 @@ static inline std::pair minimum_crossover_cost( return std::make_pair(cost_min, flip_min); } +#if 0 static inline std::pair minimum_crossover_cost( const std::vector &edges, const std::pair &span1, const ConnectionCost &cost1, @@ -1412,6 +1415,7 @@ static inline std::pair minimum_crossover_cost( } return std::make_pair(cost_min, flip_min); } +#endif static inline void do_crossover(const std::vector &edges_in, std::vector &edges_out, const std::pair &span1, const std::pair &span2, const std::pair &span3, @@ -1423,7 +1427,7 @@ static inline void do_crossover(const std::vector &edges_in, std::vect const std::pair &span2, bool reversed2, bool flipped2, const std::pair &span3, bool reversed3, bool flipped3) { auto it_edges_out = edges_out.begin(); - auto copy_span = [&edges_in, &edges_out, &it_edges_out](std::pair span, bool reversed, bool flipped) { + auto copy_span = [&edges_in, &it_edges_out](std::pair span, bool reversed, bool flipped) { assert(span.first < span.second); auto it = it_edges_out; if (reversed) @@ -1454,7 +1458,7 @@ static inline void do_crossover(const std::vector &edges_in, std::vect assert(edges_in.size() == edges_out.size()); } - +#if 0 static inline void do_crossover(const std::vector &edges_in, std::vector &edges_out, const std::pair &span1, const std::pair &span2, const std::pair &span3, const std::pair &span4, size_t i) @@ -1466,7 +1470,7 @@ static inline void do_crossover(const std::vector &edges_in, std::vect const std::pair &span3, bool reversed3, bool flipped3, const std::pair &span4, bool reversed4, bool flipped4) { auto it_edges_out = edges_out.begin(); - auto copy_span = [&edges_in, &edges_out, &it_edges_out](std::pair span, bool reversed, bool flipped) { + auto copy_span = [&edges_in, &it_edges_out](std::pair span, bool reversed, bool flipped) { assert(span.first < span.second); auto it = it_edges_out; if (reversed) @@ -1526,7 +1530,13 @@ static inline void do_crossover(const std::vector &edges_in, std::vect } assert(edges_in.size() == edges_out.size()); } +#endif +// Worst time complexity: O(min(n, 100) * (n * log n + n^2) +// Expected time complexity: O(min(n, 100) * (n * log n + k * n) +// where n is the number of edges and k is the number of connection_lengths candidates after the first one +// is found that improves the total cost. +//FIXME there are likley better heuristics to lower the time complexity. static inline void reorder_by_two_exchanges_with_segment_flipping(std::vector &edges) { if (edges.size() < 2) @@ -1536,7 +1546,8 @@ static inline void reorder_by_two_exchanges_with_segment_flipping(std::vector edges_tmp(edges); std::vector> connection_lengths(edges.size() - 1, std::pair(0., 0)); std::vector connection_tried(edges.size(), false); - for (size_t iter = 0; iter < edges.size(); ++ iter) { + const size_t max_iterations = std::min(edges.size(), size_t(100)); + for (size_t iter = 0; iter < max_iterations; ++ iter) { // Initialize connection costs and connection lengths. for (size_t i = 1; i < edges.size(); ++ i) { const FlipEdge &e1 = edges[i - 1]; @@ -1600,6 +1611,8 @@ static inline void reorder_by_two_exchanges_with_segment_flipping(std::vector &edges) { if (edges.size() < 3) { @@ -1680,6 +1693,7 @@ static inline void reorder_by_three_exchanges_with_segment_flipping(std::vector< } } } +#endif typedef Eigen::Matrix Matrixd; @@ -1693,6 +1707,7 @@ private: const ConnectionCost* costs[4]; }; +#if 0 static inline std::pair minimum_crossover_cost( const FourOptCosts &segment_costs, const Matrixd &segment_end_point_distance_matrix, @@ -1751,6 +1766,7 @@ static inline std::pair minimum_crossover_cost( return std::make_pair(cost_min, flip_min); } +// Currently not used, too slow. static inline void reorder_by_three_exchanges_with_segment_flipping2(std::vector &edges) { if (edges.size() < 3) { @@ -1845,8 +1861,11 @@ static inline void reorder_by_three_exchanges_with_segment_flipping2(std::vector } } } +#endif // Flip the sequences of polylines to lower the total length of connecting lines. +// Used by the infill generator if the infill is not connected with perimeter lines +// and to order the brim lines. static inline void improve_ordering_by_two_exchanges_with_segment_flipping(Polylines &polylines, bool fixed_start) { #ifndef NDEBUG @@ -1898,6 +1917,7 @@ static inline void improve_ordering_by_two_exchanges_with_segment_flipping(Polyl #endif /* NDEBUG */ } +// Used to optimize order of infill lines and brim lines. Polylines chain_polylines(Polylines &&polylines, const Point *start_near) { #ifdef DEBUG_SVG_OUTPUT diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 16068dde44..083b41202d 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -88,7 +88,7 @@ SlicingParameters SlicingParameters::create_from_config( // Miniumum/maximum of the minimum layer height over all extruders. params.min_layer_height = MIN_LAYER_HEIGHT; params.max_layer_height = std::numeric_limits::max(); - if (object_config.support_material.value || params.base_raft_layers > 0) { + if (object_config.support_material.value || params.base_raft_layers > 0 || object_config.support_material_enforce_layers > 0) { // Has some form of support. Add the support layers to the minimum / maximum layer height limits. params.min_layer_height = std::max( min_layer_height_from_nozzle(print_config, object_config.support_material_extruder), @@ -111,7 +111,7 @@ SlicingParameters SlicingParameters::create_from_config( params.max_layer_height = std::max(params.max_layer_height, params.layer_height); if (! soluble_interface) { - params.gap_raft_object = object_config.support_material_contact_distance.value; + params.gap_raft_object = object_config.raft_contact_distance.value; params.gap_object_support = object_config.support_material_contact_distance.value; params.gap_support_object = object_config.support_material_contact_distance.value; } @@ -122,27 +122,9 @@ SlicingParameters SlicingParameters::create_from_config( // Use as large as possible layer height for the intermediate raft layers. params.base_raft_layer_height = std::max(params.layer_height, 0.75 * support_material_extruder_dmr); params.interface_raft_layer_height = std::max(params.layer_height, 0.75 * support_material_interface_extruder_dmr); - params.contact_raft_layer_height_bridging = false; params.first_object_layer_bridging = false; - #if 1 params.contact_raft_layer_height = std::max(params.layer_height, 0.75 * support_material_interface_extruder_dmr); - if (! soluble_interface) { - // Compute the average of all nozzles used for printing the object over a raft. - //FIXME It is expected, that the 1st layer of the object is printed with a bridging flow over a full raft. Shall it not be vice versa? - coordf_t average_object_extruder_dmr = 0.; - if (! object_extruders.empty()) { - for (unsigned int extruder_id : object_extruders) - average_object_extruder_dmr += print_config.nozzle_diameter.get_at(extruder_id); - average_object_extruder_dmr /= coordf_t(object_extruders.size()); - } - params.first_object_layer_height = average_object_extruder_dmr; - params.first_object_layer_bridging = true; - } - #else - params.contact_raft_layer_height = soluble_interface ? support_material_interface_extruder_dmr : 0.75 * support_material_interface_extruder_dmr; - params.contact_raft_layer_height_bridging = ! soluble_interface; - ... - #endif + params.first_object_layer_height = params.layer_height; } if (params.has_raft()) { @@ -150,8 +132,8 @@ SlicingParameters SlicingParameters::create_from_config( //FIXME The last raft layer is the contact layer, which shall be printed with a bridging flow for ease of separation. Currently it is not the case. if (params.raft_layers() == 1) { // There is only the contact layer. - params.contact_raft_layer_height = first_layer_height; - params.raft_contact_top_z = first_layer_height; + params.contact_raft_layer_height = first_layer_height; + params.raft_contact_top_z = first_layer_height; } else { assert(params.base_raft_layers > 0); assert(params.interface_raft_layers > 0); diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index e151b208f4..8b3d5c917e 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -55,7 +55,6 @@ struct SlicingParameters coordf_t base_raft_layer_height; coordf_t interface_raft_layer_height; coordf_t contact_raft_layer_height; - bool contact_raft_layer_height_bridging; // The regular layer height, applied for all but the first layer, if not overridden by layer ranges // or by the variable layer thickness table. @@ -110,7 +109,6 @@ inline bool equal_layering(const SlicingParameters &sp1, const SlicingParameters sp1.base_raft_layer_height == sp2.base_raft_layer_height && sp1.interface_raft_layer_height == sp2.interface_raft_layer_height && sp1.contact_raft_layer_height == sp2.contact_raft_layer_height && - sp1.contact_raft_layer_height_bridging == sp2.contact_raft_layer_height_bridging && sp1.layer_height == sp2.layer_height && sp1.min_layer_height == sp2.min_layer_height && sp1.max_layer_height == sp2.max_layer_height && diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index 7ab0c47b27..776351ac0d 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -52,7 +52,7 @@ static inline std::pair face_z_span(const stl_facet &f) // https://tams.informatik.uni-hamburg.de/publications/2017/Adaptive%20Slicing%20for%20the%20FDM%20Process%20Revisited.pdf // (page 51, formula (8)) // Currenty @platch's error metric formula is not used. -static constexpr double SURFACE_CONST = 0.18403; +//static constexpr const double SURFACE_CONST = 0.18403; // for a given facet, compute maximum height within the allowed surface roughness / stairstepping deviation static inline float layer_height_from_slope(const SlicingAdaptive::FaceZ &face, float max_surface_deviation) diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 95c4297542..ddd68238e0 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -4,8 +4,8 @@ #include "Print.hpp" #include "SupportMaterial.hpp" #include "Fill/FillBase.hpp" -#include "EdgeGrid.hpp" #include "Geometry.hpp" +#include "Point.hpp" #include #include @@ -16,6 +16,19 @@ #include #include +#define SUPPORT_USE_AGG_RASTERIZER + +#ifdef SUPPORT_USE_AGG_RASTERIZER + #include + #include + #include + #include + #include + #include "PNGReadWrite.hpp" +#else + #include "EdgeGrid.hpp" +#endif // SUPPORT_USE_AGG_RASTERIZER + // #define SLIC3R_DEBUG // Make assert active if SLIC3R_DEBUG @@ -31,6 +44,10 @@ namespace Slic3r { +// how much we extend support around the actual contact area +//FIXME this should be dependent on the nozzle diameter! +#define SUPPORT_MATERIAL_MARGIN 1.5 + // Increment used to reach MARGIN in steps to avoid trespassing thin objects #define NUM_MARGIN_STEPS 3 @@ -129,7 +146,7 @@ void export_print_z_polygons_and_extrusions_to_svg( svg.draw(to_polylines(layers[i]->polygons), support_surface_type_to_color_name(layers[i]->layer_type)); Polygons polygons_support, polygons_interface; - support_layer.support_fills.polygons_covered_by_width(polygons_support, SCALED_EPSILON); + support_layer.support_fills.polygons_covered_by_width(polygons_support, float(SCALED_EPSILON)); // support_layer.support_interface_fills.polygons_covered_by_width(polygons_interface, SCALED_EPSILON); svg.draw(union_ex(polygons_support), "brown"); svg.draw(union_ex(polygons_interface), "black"); @@ -139,6 +156,169 @@ void export_print_z_polygons_and_extrusions_to_svg( } #endif /* SLIC3R_DEBUG */ +#ifdef SUPPORT_USE_AGG_RASTERIZER +static std::vector rasterize_polygons(const Vec2i &grid_size, const double pixel_size, const Point &left_bottom, const Polygons &polygons) +{ + std::vector data(grid_size.x() * grid_size.y()); + agg::rendering_buffer rendering_buffer(data.data(), unsigned(grid_size.x()), unsigned(grid_size.y()), grid_size.x()); + agg::pixfmt_gray8 pixel_renderer(rendering_buffer); + agg::renderer_base raw_renderer(pixel_renderer); + agg::renderer_scanline_aa_solid> renderer(raw_renderer); + + renderer.color(agg::pixfmt_gray8::color_type(255)); + raw_renderer.clear(agg::pixfmt_gray8::color_type(0)); + + agg::scanline_p8 scanline; + agg::rasterizer_scanline_aa<> rasterizer; + + auto convert_pt = [left_bottom, pixel_size](const Point &pt) { + return Vec2d((pt.x() - left_bottom.x()) / pixel_size, (pt.y() - left_bottom.y()) / pixel_size); + }; + rasterizer.reset(); + for (const Polygon &polygon : polygons) { + agg::path_storage path; + auto it = polygon.points.begin(); + Vec2d pt_front = convert_pt(*it); + path.move_to(pt_front.x(), pt_front.y()); + while (++ it != polygon.points.end()) { + Vec2d pt = convert_pt(*it); + path.line_to(pt.x(), pt.y()); + } + path.line_to(pt_front.x(), pt_front.y()); + rasterizer.add_path(std::move(path)); + } + agg::render_scanlines(rasterizer, scanline, renderer); + return data; +} +// Grid has to have the boundary pixels unset. +static Polygons contours_simplified(const Vec2i &grid_size, const double pixel_size, Point left_bottom, const std::vector &grid, coord_t offset, bool fill_holes) +{ + assert(std::abs(2 * offset) < pixel_size - 10); + + // Fill in empty cells, which have a left / right neighbor filled. + // Fill in empty cells, which have the top / bottom neighbor filled. + std::vector cell_inside_data; + const std::vector &cell_inside = fill_holes ? cell_inside_data : grid; + if (fill_holes) { + cell_inside_data = grid; + for (int r = 1; r + 1 < grid_size.y(); ++ r) { + for (int c = 1; c + 1 < grid_size.x(); ++ c) { + int addr = r * grid_size.x() + c; + if ((grid[addr - 1] != 0 && grid[addr + 1] != 0) || + (grid[addr - grid_size.x()] != 0 && grid[addr + grid_size.x()] != 0)) + cell_inside_data[addr] = true; + } + } + } + + // 1) Collect the lines. + std::vector lines; + std::vector> start_point_to_line_idx; + for (int r = 1; r < grid_size.y(); ++ r) { + for (int c = 1; c < grid_size.x(); ++ c) { + int addr = r * grid_size.x() + c; + bool left = cell_inside[addr - 1] != 0; + bool top = cell_inside[addr - grid_size.x()] != 0; + bool current = cell_inside[addr] != 0; + if (left != current) { + lines.push_back( + left ? + Line(Point(c, r+1), Point(c, r )) : + Line(Point(c, r ), Point(c, r+1))); + start_point_to_line_idx.emplace_back(lines.back().a, int(lines.size()) - 1); + } + if (top != current) { + lines.push_back( + top ? + Line(Point(c , r), Point(c+1, r)) : + Line(Point(c+1, r), Point(c , r))); + start_point_to_line_idx.emplace_back(lines.back().a, int(lines.size()) - 1); + } + } + } + std::sort(start_point_to_line_idx.begin(), start_point_to_line_idx.end(), [](const auto &l, const auto &r){ return l.first < r.first; }); + + // 2) Chain the lines. + std::vector line_processed(lines.size(), false); + Polygons out; + for (int i_candidate = 0; i_candidate < int(lines.size()); ++ i_candidate) { + if (line_processed[i_candidate]) + continue; + Polygon poly; + line_processed[i_candidate] = true; + poly.points.push_back(lines[i_candidate].b); + int i_line_current = i_candidate; + for (;;) { + auto line_range = std::equal_range(std::begin(start_point_to_line_idx), std::end(start_point_to_line_idx), + std::make_pair(lines[i_line_current].b, 0), [](const auto& l, const auto& r) { return l.first < r.first; }); + // The interval has to be non empty, there shall be at least one line continuing the current one. + assert(line_range.first != line_range.second); + int i_next = -1; + for (auto it = line_range.first; it != line_range.second; ++ it) { + if (it->second == i_candidate) { + // closing the loop. + goto end_of_poly; + } + if (line_processed[it->second]) + continue; + if (i_next == -1) { + i_next = it->second; + } else { + // This is a corner, where two lines meet exactly. Pick the line, which encloses a smallest angle with + // the current edge. + const Line &line_current = lines[i_line_current]; + const Line &line_next = lines[it->second]; + const Vector v1 = line_current.vector(); + const Vector v2 = line_next.vector(); + int64_t cross = int64_t(v1(0)) * int64_t(v2(1)) - int64_t(v2(0)) * int64_t(v1(1)); + if (cross > 0) { + // This has to be a convex right angle. There is no better next line. + i_next = it->second; + break; + } + } + } + line_processed[i_next] = true; + i_line_current = i_next; + poly.points.push_back(lines[i_line_current].b); + } + end_of_poly: + out.push_back(std::move(poly)); + } + + // 3) Scale the polygons back into world, shrink slightly and remove collinear points. + for (Polygon &poly : out) { + for (Point &p : poly.points) { +#if 0 + p.x() = (p.x() + 1) * pixel_size + left_bottom.x(); + p.y() = (p.y() + 1) * pixel_size + left_bottom.y(); +#else + p *= pixel_size; + p += left_bottom; +#endif + } + // Shrink the contour slightly, so if the same contour gets discretized and simplified again, one will get the same result. + // Remove collinear points. + Points pts; + pts.reserve(poly.points.size()); + for (size_t j = 0; j < poly.points.size(); ++ j) { + size_t j0 = (j == 0) ? poly.points.size() - 1 : j - 1; + size_t j2 = (j + 1 == poly.points.size()) ? 0 : j + 1; + Point v = poly.points[j2] - poly.points[j0]; + if (v(0) != 0 && v(1) != 0) { + // This is a corner point. Copy it to the output contour. + Point p = poly.points[j]; + p(1) += (v(0) < 0) ? - offset : offset; + p(0) += (v(1) > 0) ? - offset : offset; + pts.push_back(p); + } + } + poly.points = std::move(pts); + } + return out; +} +#endif // SUPPORT_USE_AGG_RASTERIZER + PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params) : m_object (object), m_print_config (&object->print()->config()), @@ -291,7 +471,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) BOOST_LOG_TRIVIAL(info) << "Support generator - Creating base layers"; - // Fill in intermediate layers between the top / bottom support contact layers, trimm them by the object. + // Fill in intermediate layers between the top / bottom support contact layers, trim them by the object. this->generate_base_layers(object, bottom_contacts, top_contacts, intermediate_layers, layer_support_areas); #ifdef SLIC3R_DEBUG @@ -312,23 +492,27 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) BOOST_LOG_TRIVIAL(info) << "Support generator - Creating interfaces"; - // Propagate top / bottom contact layers to generate interface layers. - MyLayersPtr interface_layers = this->generate_interface_layers( - bottom_contacts, top_contacts, intermediate_layers, layer_storage); + // Propagate top / bottom contact layers to generate interface layers + // and base interface layers (for soluble interface / non souble base only) + auto [interface_layers, base_interface_layers] = this->generate_interface_layers(bottom_contacts, top_contacts, intermediate_layers, layer_storage); BOOST_LOG_TRIVIAL(info) << "Support generator - Creating raft"; // If raft is to be generated, the 1st top_contact layer will contain the 1st object layer silhouette with holes filled. // There is also a 1st intermediate layer containing bases of support columns. // Inflate the bases of the support columns and create the raft base under the object. - MyLayersPtr raft_layers = this->generate_raft_base(top_contacts, interface_layers, intermediate_layers, layer_storage); + MyLayersPtr raft_layers = this->generate_raft_base(object, top_contacts, interface_layers, intermediate_layers, layer_storage); #ifdef SLIC3R_DEBUG - for (MyLayersPtr::const_iterator it = interface_layers.begin(); it != interface_layers.end(); ++ it) + for (const MyLayer *l : interface_layers) Slic3r::SVG::export_expolygons( - debug_out_path("support-interface-layers-%d-%lf.svg", iRun, (*it)->print_z), - union_ex((*it)->polygons, false)); -#endif /* SLIC3R_DEBUG */ + debug_out_path("support-interface-layers-%d-%lf.svg", iRun, l->print_z), + union_ex(l->polygons, false)); + for (const MyLayer *l : base_interface_layers) + Slic3r::SVG::export_expolygons( + debug_out_path("support-base-interface-layers-%d-%lf.svg", iRun, l->print_z), + union_ex(l->polygons, false)); +#endif // SLIC3R_DEBUG /* // Clip with the pillars. @@ -350,12 +534,13 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) // Install support layers into the object. // A support layer installed on a PrintObject has a unique print_z. MyLayersPtr layers_sorted; - layers_sorted.reserve(raft_layers.size() + bottom_contacts.size() + top_contacts.size() + intermediate_layers.size() + interface_layers.size()); + layers_sorted.reserve(raft_layers.size() + bottom_contacts.size() + top_contacts.size() + intermediate_layers.size() + interface_layers.size() + base_interface_layers.size()); layers_append(layers_sorted, raft_layers); layers_append(layers_sorted, bottom_contacts); layers_append(layers_sorted, top_contacts); layers_append(layers_sorted, intermediate_layers); layers_append(layers_sorted, interface_layers); + layers_append(layers_sorted, base_interface_layers); // Sort the layers lexicographically by a raising print_z and a decreasing height. std::sort(layers_sorted.begin(), layers_sorted.end(), MyLayersPtrCompare()); int layer_id = 0; @@ -388,7 +573,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) BOOST_LOG_TRIVIAL(info) << "Support generator - Generating tool paths"; // Generate the actual toolpaths and save them into each layer. - this->generate_toolpaths(object, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers); + this->generate_toolpaths(object.support_layers(), raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers); #ifdef SLIC3R_DEBUG { @@ -462,7 +647,8 @@ public: const Polygons &trimming_polygons, // Grid spacing, given by "support_material_spacing" + m_support_material_flow.spacing() coordf_t support_spacing, - coordf_t support_angle) : + coordf_t support_angle, + coordf_t line_spacing) : m_support_polygons(&support_polygons), m_trimming_polygons(&trimming_polygons), m_support_spacing(support_spacing), m_support_angle(support_angle) { @@ -475,18 +661,58 @@ public: polygons_rotate(m_support_polygons_rotated, - support_angle); polygons_rotate(m_trimming_polygons_rotated, - support_angle); } - // Create an EdgeGrid, initialize it with projection, initialize signed distance field. + + // Resolution of the sparse support grid. coord_t grid_resolution = coord_t(scale_(m_support_spacing)); BoundingBox bbox = get_extents(*m_support_polygons); bbox.offset(20); + // Align the bounding box with the sparse support grid. bbox.align_to_grid(grid_resolution); + + // Sample a single point per input support polygon, keep it as a reference to maintain corresponding + // polygons if ever these polygons get split into parts by the trimming polygons. + m_island_samples = island_samples(*m_support_polygons); + +#ifdef SUPPORT_USE_AGG_RASTERIZER + m_bbox = bbox; + // Oversample the grid to avoid leaking of supports through or around the object walls. + int oversampling = std::min(8, int(scale_(m_support_spacing) / (scale_(line_spacing) + 100))); + m_pixel_size = scale_(m_support_spacing / oversampling); + assert(scale_(line_spacing) + 20 < m_pixel_size); + // Add one empty column / row boundaries. + m_bbox.offset(m_pixel_size); + // Grid size fitting the support polygons plus one pixel boundary around the polygons. + Vec2i grid_size_raw(int(ceil((m_bbox.max.x() - m_bbox.min.x()) / m_pixel_size)), + int(ceil((m_bbox.max.y() - m_bbox.min.y()) / m_pixel_size))); + // Overlay macro blocks of (oversampling x oversampling) over the grid. + Vec2i grid_blocks((grid_size_raw.x() + oversampling - 1 - 2) / oversampling, + (grid_size_raw.y() + oversampling - 1 - 2) / oversampling); + // and resize the grid to fit the macro blocks + one pixel boundary. + m_grid_size = grid_blocks * oversampling + Vec2i(2, 2); + assert(m_grid_size.x() >= grid_size_raw.x()); + assert(m_grid_size.y() >= grid_size_raw.y()); + m_grid2 = rasterize_polygons(m_grid_size, m_pixel_size, m_bbox.min, *m_support_polygons); + + seed_fill_block(m_grid2, m_grid_size, + dilate_trimming_region(rasterize_polygons(m_grid_size, m_pixel_size, m_bbox.min, *m_trimming_polygons), m_grid_size), + grid_blocks, oversampling); + +#ifdef SLIC3R_DEBUG + { + static int irun; + Slic3r::png::write_gray_to_file_scaled(debug_out_path("support-rasterizer-%d.png", irun++), m_grid_size.x(), m_grid_size.y(), m_grid2.data(), 4); + } +#endif // SLIC3R_DEBUG + +#else // SUPPORT_USE_AGG_RASTERIZER + // Create an EdgeGrid, initialize it with projection, initialize signed distance field. m_grid.set_bbox(bbox); m_grid.create(*m_support_polygons, grid_resolution); #if 0 if (m_grid.has_intersecting_edges()) { // EdgeGrid fails to produce valid signed distance function for self-intersecting polygons. m_support_polygons_rotated = simplify_polygons(*m_support_polygons); - m_support_polygons = &m_support_polygons_rotated; + m_support_polygons = &m_support_polygons_rotated; m_grid.set_bbox(bbox); m_grid.create(*m_support_polygons, grid_resolution); // assert(! m_grid.has_intersecting_edges()); @@ -495,9 +721,7 @@ public: } #endif m_grid.calculate_sdf(); - // Sample a single point per input support polygon, keep it as a reference to maintain corresponding - // polygons if ever these polygons get split into parts by the trimming polygons. - m_island_samples = island_samples(*m_support_polygons); +#endif // SUPPORT_USE_AGG_RASTERIZER } // Extract polygons from the grid, offsetted by offset_in_grid, @@ -506,17 +730,21 @@ public: // Remove all the pieces, which do not contain any of the island_samples. Polygons extract_support(const coord_t offset_in_grid, bool fill_holes) { +#ifdef SUPPORT_USE_AGG_RASTERIZER + Polygons support_polygons_simplified = contours_simplified(m_grid_size, m_pixel_size, m_bbox.min, m_grid2, offset_in_grid, fill_holes); +#else // SUPPORT_USE_AGG_RASTERIZER // Generate islands, so each island may be tested for overlap with m_island_samples. assert(std::abs(2 * offset_in_grid) < m_grid.resolution()); -#ifdef SLIC3R_DEBUG - Polygons support_polygons_simplified = m_grid.contours_simplified(offset_in_grid, fill_holes); + Polygons support_polygons_simplified = m_grid.contours_simplified(offset_in_grid, fill_holes); +#endif // SUPPORT_USE_AGG_RASTERIZER + ExPolygons islands = diff_ex(support_polygons_simplified, *m_trimming_polygons, false); -#else - ExPolygons islands = diff_ex(m_grid.contours_simplified(offset_in_grid, fill_holes), *m_trimming_polygons, false); -#endif // Extract polygons, which contain some of the m_island_samples. Polygons out; +#if 0 + out = to_polygons(std::move(islands)); +#else for (ExPolygon &island : islands) { BoundingBox bbox = get_extents(island.contour); // Samples are sorted lexicographically. @@ -554,6 +782,7 @@ public: } } } +#endif #ifdef SLIC3R_DEBUG static int iRun = 0; @@ -583,7 +812,7 @@ public: return out; } -#ifdef SLIC3R_DEBUG +#if defined(SLIC3R_DEBUG) && ! defined(SUPPORT_USE_AGG_RASTERIZER) void serialize(const std::string &path) { FILE *file = ::fopen(path.c_str(), "wb"); @@ -694,12 +923,76 @@ public: const Polygons& trimming_polygons() const { return *m_trimming_polygons; } const EdgeGrid::Grid& grid() const { return m_grid; } -#endif /* SLIC3R_DEBUG */ +#endif // defined(SLIC3R_DEBUG) && ! defined(SUPPORT_USE_AGG_RASTERIZER) private: SupportGridPattern() {} SupportGridPattern& operator=(const SupportGridPattern &rhs); +#ifdef SUPPORT_USE_AGG_RASTERIZER + // Dilate the trimming region (unmask the boundary pixels). + static std::vector dilate_trimming_region(const std::vector &trimming, const Vec2i &grid_size) + { + std::vector dilated(trimming.size(), 0); + for (int r = 1; r + 1 < grid_size.y(); ++ r) + for (int c = 1; c + 1 < grid_size.x(); ++ c) { + //int addr = c + r * m_grid_size.x(); + // 4-neighborhood is not sufficient. + // dilated[addr] = trimming[addr] != 0 && trimming[addr - 1] != 0 && trimming[addr + 1] != 0 && trimming[addr - m_grid_size.x()] != 0 && trimming[addr + m_grid_size.x()] != 0; + // 8-neighborhood + int addr = c + (r - 1) * grid_size.x(); + bool b = trimming[addr - 1] != 0 && trimming[addr] != 0 && trimming[addr + 1] != 0; + addr += grid_size.x(); + b = b && trimming[addr - 1] != 0 && trimming[addr] != 0 && trimming[addr + 1] != 0; + addr += grid_size.x(); + b = b && trimming[addr - 1] != 0 && trimming[addr] != 0 && trimming[addr + 1] != 0; + dilated[addr - grid_size.x()] = b; + } + return dilated; + } + + // Seed fill each of the (oversampling x oversampling) block up to the dilated trimming region. + static void seed_fill_block(std::vector &grid, Vec2i grid_size, const std::vector &trimming,const Vec2i &grid_blocks, int oversampling) + { + int size = oversampling; + int stride = grid_size.x(); + for (int block_r = 0; block_r < grid_blocks.y(); ++ block_r) + for (int block_c = 0; block_c < grid_blocks.x(); ++ block_c) { + // Propagate the support pixels over the macro cell up to the trimming mask. + int addr = block_c * size + 1 + (block_r * size + 1) * stride; + unsigned char *grid_data = grid.data() + addr; + const unsigned char *mask_data = trimming.data() + addr; + // Top to bottom propagation. + #define PROPAGATION_STEP(offset) \ + do { \ + int addr = r * stride + c; \ + int addr2 = addr + offset; \ + if (grid_data[addr2] && ! mask_data[addr] && ! mask_data[addr2]) \ + grid_data[addr] = 1; \ + } while (0); + for (int r = 0; r < size; ++ r) { + if (r > 0) + for (int c = 0; c < size; ++ c) + PROPAGATION_STEP(- stride); + for (int c = 1; c < size; ++ c) + PROPAGATION_STEP(- 1); + for (int c = size - 2; c >= 0; -- c) + PROPAGATION_STEP(+ 1); + } + // Bottom to top propagation. + for (int r = size - 2; r >= 0; -- r) { + for (int c = 0; c < size; ++ c) + PROPAGATION_STEP(+ stride); + for (int c = 1; c < size; ++ c) + PROPAGATION_STEP(- 1); + for (int c = size - 2; c >= 0; -- c) + PROPAGATION_STEP(+ 1); + } + #undef PROPAGATION_STEP + } + } +#endif // SUPPORT_USE_AGG_RASTERIZER + #if 0 // Get some internal point of an expolygon, to be used as a representative // sample to test, whether this island is inside another island. @@ -740,7 +1033,12 @@ private: Polygons polygons = offset(expoly, - 20.f); for (const Polygon &poly : polygons) if (! poly.points.empty()) { - pts.push_back(poly.points.front()); + // Take a small fixed number of samples of this polygon for robustness. + int num_points = int(poly.points.size()); + int num_samples = std::min(num_points, 4); + int stride = num_points / num_samples; + for (int i = 0; i < num_points; i += stride) + pts.push_back(poly.points[i]); break; } #endif @@ -764,7 +1062,15 @@ private: // X spacing of the support lines parallel with the Y axis. coordf_t m_support_spacing; - Slic3r::EdgeGrid::Grid m_grid; +#ifdef SUPPORT_USE_AGG_RASTERIZER + Vec2i m_grid_size; + double m_pixel_size; + BoundingBox m_bbox; + std::vector m_grid2; +#else // SUPPORT_USE_AGG_RASTERIZER + Slic3r::EdgeGrid::Grid m_grid; +#endif // SUPPORT_USE_AGG_RASTERIZER + // Internal sample points of supporting expolygons. These internal points are used to pick regions corresponding // to the initial supporting regions, after these regions werre grown and possibly split to many by the trimming polygons. Points m_island_samples; @@ -781,7 +1087,7 @@ namespace SupportMaterialInternal { { for (const ExtrusionPath &ep : loop.paths) if (ep.role() == erOverhangPerimeter && ! ep.polyline.empty()) - return ep.size() >= (ep.is_closed() ? 3 : 2); + return int(ep.size()) >= (ep.is_closed() ? 3 : 2); return false; } static bool has_bridging_perimeters(const ExtrusionEntityCollection &perimeters) @@ -980,7 +1286,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // Output layers, sorted by top Z. MyLayersPtr contact_out; - const bool support_auto = m_object_config->support_material_auto.value; + const bool support_auto = m_object_config->support_material.value && m_object_config->support_material_auto.value; // If user specified a custom angle threshold, convert it to radians. // Zero means automatic overhang detection. const double threshold_rad = (m_object_config->support_material_threshold.value > 0) ? @@ -1040,8 +1346,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // we're here just to get the object footprint for the raft. // We only consider contours and discard holes to get a more continuous raft. overhang_polygons = collect_slices_outer(layer); - // Extend by SUPPORT_MATERIAL_MARGIN, which is 1.5mm - contact_polygons = offset(overhang_polygons, scale_(SUPPORT_MATERIAL_MARGIN)); + // Expand for better stability. + contact_polygons = offset(overhang_polygons, scaled(m_object_config->raft_expansion.value)); } else { // Generate overhang / contact_polygons for non-raft layers. const Layer &lower_layer = *object.layers()[layer_id-1]; @@ -1075,6 +1381,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // Get the regions needing a suport, collapse very tiny spots. //FIXME cache the lower layer offset if this layer has multiple regions. #if 1 + //FIXME this solution will trigger stupid supports for sharp corners, see GH #4874 diff_polygons = offset2( diff(layerm_polygons, offset2(lower_layer_polygons, - 0.5f * fw, lower_layer_offset + 0.5f * fw, SUPPORT_SURFACES_OFFSET_PARAMETERS)), @@ -1106,8 +1413,18 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ const ExPolygons &enforcer = enforcers[layer_id]; if (! enforcer.empty()) { // Enforce supports (as if with 90 degrees of slope) for the regions covered by the enforcer meshes. - Polygons new_contacts = diff(intersection(layerm_polygons, to_polygons(std::move(enforcer))), - offset(lower_layer_polygons, 0.05f * fw, SUPPORT_SURFACES_OFFSET_PARAMETERS)); +#ifdef SLIC3R_DEBUG + ExPolygons enforcers_united = union_ex(to_polygons(enforcer), false); +#endif // SLIC3R_DEBUG + Polygons new_contacts = diff(intersection(layerm_polygons, to_polygons(std::move(enforcer))), + offset(lower_layer_polygons, 0.05f * fw, SUPPORT_SURFACES_OFFSET_PARAMETERS)); +#ifdef SLIC3R_DEBUG + SVG::export_expolygons(debug_out_path("support-top-contacts-enforcers-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z), + { { { union_ex(layerm_polygons, false) }, { "layerm_polygons", "gray", 0.2f } }, + { { union_ex(lower_layer_polygons, false) }, { "lower_layer_polygons", "green", 0.5f } }, + { enforcers_united, { "enforcers", "blue", 0.5f } }, + { { union_ex(new_contacts, true) }, { "new_contacts", "red", "black", "", scaled(0.1f), 0.5f } } }); +#endif /* SLIC3R_DEBUG */ if (! new_contacts.empty()) { if (diff_polygons.empty()) diff_polygons = std::move(new_contacts); @@ -1128,8 +1445,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // Subtracting them as they are may leave unwanted narrow // residues of diff_polygons that would then be supported. diff_polygons = diff(diff_polygons, - offset(union_(to_polygons(std::move(blockers[layer_id]))), - 1000.*SCALED_EPSILON)); + offset(union_(to_polygons(std::move(blockers[layer_id]))), float(1000.*SCALED_EPSILON))); } #ifdef SLIC3R_DEBUG @@ -1137,7 +1453,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ ::Slic3r::SVG svg(debug_out_path("support-top-contacts-raw-run%d-layer%d-region%d.svg", iRun, layer_id, std::find_if(layer.regions().begin(), layer.regions().end(), [layerm](const LayerRegion* other){return other == layerm;}) - layer.regions().begin()), - get_extents(diff_polygons)); + get_extents(diff_polygons)); Slic3r::ExPolygons expolys = union_ex(diff_polygons, false); svg.draw(expolys); } @@ -1280,7 +1596,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ slices_margin_cached, // Grid resolution. m_object_config->support_material_spacing.value + m_support_material_flow.spacing(), - Geometry::deg2rad(m_object_config->support_material_angle.value)); + Geometry::deg2rad(m_object_config->support_material_angle.value), + m_support_material_flow.spacing()); // 1) Contact polygons will be projected down. To keep the interface and base layers from growing, return a contour a tiny bit smaller than the grid cells. new_layer.contact_polygons = new Polygons(support_grid_pattern.extract_support(-3, true)); // 2) infill polygons, expand them by half the extrusion width + a tiny bit of extra. @@ -1301,41 +1618,42 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ slices_margin_cached); SupportGridPattern support_grid_pattern( // Support islands, to be stretched into a grid. - dense_interface_polygons, + //FIXME The regularization of dense_interface_polygons above may stretch dense_interface_polygons outside of the contact polygons, + // thus some dense interface areas may not get supported. Trim the excess with contact_polygons at the following line. + // See for example GH #4874. + intersection(dense_interface_polygons, *new_layer.contact_polygons), // Trimming polygons, to trim the stretched support islands. slices_margin_cached, // Grid resolution. m_object_config->support_material_spacing.value + m_support_material_flow.spacing(), - Geometry::deg2rad(m_object_config->support_material_angle.value)); + Geometry::deg2rad(m_object_config->support_material_angle.value), + m_support_material_flow.spacing()); new_layer.polygons = support_grid_pattern.extract_support(m_support_material_flow.scaled_spacing()/2 + 5, false); #ifdef SLIC3R_DEBUG - { - support_grid_pattern.serialize(debug_out_path("support-top-contacts-final-run%d-layer%d-z%f.bin", iRun, layer_id, layer.print_z)); - - BoundingBox bbox = get_extents(contact_polygons); - bbox.merge(get_extents(new_layer.polygons)); - ::Slic3r::SVG svg(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z)); - svg.draw(union_ex(*new_layer.contact_polygons, false), "gray", 0.5f); - svg.draw(union_ex(contact_polygons, false), "blue", 0.5f); - svg.draw(union_ex(dense_interface_polygons, false), "green", 0.5f); - svg.draw(union_ex(new_layer.polygons, true), "red", 0.5f); - svg.draw_outline(union_ex(new_layer.polygons, true), "black", "black", scale_(0.1f)); - } + SVG::export_expolygons(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z), + { { { union_ex(lower_layer_polygons, false) }, { "lower_layer_polygons", "gray", 0.2f } }, + { { union_ex(*new_layer.contact_polygons, false) }, { "new_layer.contact_polygons", "yellow", 0.5f } }, + { { union_ex(slices_margin_cached, false) }, { "slices_margin_cached", "blue", 0.5f } }, + { { union_ex(dense_interface_polygons, false) }, { "dense_interface_polygons", "green", 0.5f } }, + { { union_ex(new_layer.polygons, true) }, { "new_layer.polygons", "red", "black", "", scaled(0.1f), 0.5f } } }); + //support_grid_pattern.serialize(debug_out_path("support-top-contacts-final-run%d-layer%d-z%f.bin", iRun, layer_id, layer.print_z)); + SVG::export_expolygons(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z), + { { { union_ex(lower_layer_polygons, false) }, { "lower_layer_polygons", "gray", 0.2f } }, + { { union_ex(*new_layer.contact_polygons, false) }, { "new_layer.contact_polygons", "yellow", 0.5f } }, + { { union_ex(contact_polygons, false) }, { "contact_polygons", "blue", 0.5f } }, + { { union_ex(dense_interface_polygons, false) }, { "dense_interface_polygons", "green", 0.5f } }, + { { union_ex(new_layer.polygons, true) }, { "new_layer.polygons", "red", "black", "", scaled(0.1f), 0.5f } } }); #endif /* SLIC3R_DEBUG */ } } #ifdef SLIC3R_DEBUG - { - BoundingBox bbox = get_extents(contact_polygons); - bbox.merge(get_extents(new_layer.polygons)); - ::Slic3r::SVG svg(debug_out_path("support-top-contacts-final-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z)); - svg.draw(union_ex(*new_layer.contact_polygons, false), "gray", 0.5f); - svg.draw(union_ex(contact_polygons, false), "blue", 0.5f); - svg.draw(union_ex(overhang_polygons, false), "green", 0.5f); - svg.draw(union_ex(new_layer.polygons, true), "red", 0.5f); - svg.draw_outline(union_ex(new_layer.polygons, true), "black", "black", scale_(0.1f)); - } - #endif /* SLIC3R_DEBUG */ + SVG::export_expolygons(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z), + { { { union_ex(lower_layer_polygons, false) }, { "lower_layer_polygons", "gray", 0.2f } }, + { { union_ex(*new_layer.contact_polygons, false) }, { "new_layer.contact_polygons", "yellow", 0.5f } }, + { { union_ex(contact_polygons, false) }, { "contact_polygons", "blue", 0.5f } }, + { { union_ex(overhang_polygons, false) }, { "overhang_polygons", "green", 0.5f } }, + { { union_ex(new_layer.polygons, true) }, { "new_layer.polygons", "red", "black", "", scaled(0.1f), 0.5f } } }); + #endif /* SLIC3R_DEBUG */ // Even after the contact layer was expanded into a grid, some of the contact islands may be too tiny to be extruded. // Remove those tiny islands from new_layer.polygons and new_layer.contact_polygons. @@ -1450,8 +1768,13 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta BOOST_LOG_TRIVIAL(trace) << "Support generator - bottom_contact_layers - layer " << layer_id; const Layer &layer = *object.get_layer(layer_id); // Collect projections of all contact areas above or at the same level as this top surface. +#ifdef SLIC3R_DEBUG + Polygons polygons_new; +#endif // SLIC3R_DEBUG for (; contact_idx >= 0 && top_contacts[contact_idx]->print_z > layer.print_z - EPSILON; -- contact_idx) { +#ifndef SLIC3R_DEBUG Polygons polygons_new; +#endif // SLIC3R_DEBUG // Contact surfaces are expanded away from the object, trimmed by the object. // Use a slight positive offset to overlap the touching regions. #if 0 @@ -1474,7 +1797,11 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta tbb::task_group task_group; if (! m_object_config->support_material_buildplate_only) // Find the bottom contact layers above the top surfaces of this layer. - task_group.run([this, &object, &top_contacts, contact_idx, &layer, layer_id, &layer_storage, &layer_support_areas, &bottom_contacts, &projection_raw] { + task_group.run([this, &object, &top_contacts, contact_idx, &layer, layer_id, &layer_storage, &layer_support_areas, &bottom_contacts, &projection_raw + #ifdef SLIC3R_DEBUG + , &polygons_new + #endif // SLIC3R_DEBUG + ] { Polygons top = collect_region_slices_by_type(layer, stTop); #ifdef SLIC3R_DEBUG { @@ -1485,6 +1812,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta svg.draw(union_ex(projection_raw, true), "red", 0.5f); svg.draw_outline(union_ex(projection_raw, true), "red", "blue", scale_(0.1f)); svg.draw(layer.lslices, "green", 0.5f); + svg.draw(union_ex(polygons_new, true), "magenta", 0.5f); + svg.draw_outline(union_ex(polygons_new, true), "magenta", "magenta", scale_(0.1f)); } #endif /* SLIC3R_DEBUG */ @@ -1582,7 +1911,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta }); Polygons &layer_support_area = layer_support_areas[layer_id]; - task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area, layer_id] { + task_group.run([this, &projection, &projection_raw, &layer, &layer_support_area] { // Remove the areas that touched from the projection that will continue on next, lower, top surfaces. // Polygons trimming = union_(to_polygons(layer.slices), touching, true); Polygons trimming = offset(layer.lslices, float(SCALED_EPSILON)); @@ -1611,7 +1940,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta trimming, // Grid spacing. m_object_config->support_material_spacing.value + m_support_material_flow.spacing(), - Geometry::deg2rad(m_object_config->support_material_angle.value)); + Geometry::deg2rad(m_object_config->support_material_angle.value), + m_support_material_flow.spacing()); tbb::task_group task_group_inner; // 1) Cache the slice of a support volume. The support volume is expanded by 1/2 of support material flow spacing // to allow a placement of suppot zig-zag snake along the grid lines. @@ -1631,7 +1961,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta Polygons projection_new; task_group_inner.run([&projection_new, &support_grid_pattern #ifdef SLIC3R_DEBUG - , &layer + , &layer, &projection, &trimming #endif /* SLIC3R_DEBUG */ ] { projection_new = support_grid_pattern.extract_support(-5, true); @@ -1640,6 +1970,17 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta debug_out_path("support-projection_new-gridded-%d-%lf.svg", iRun, layer.print_z), union_ex(projection_new, false)); #endif /* SLIC3R_DEBUG */ +#ifdef SLIC3R_DEBUG + { + BoundingBox bbox = get_extents(projection); + bbox.merge(get_extents(projection_new)); + bbox.merge(get_extents(trimming)); + ::Slic3r::SVG svg(debug_out_path("support-projection_new-gridded-%d-%lf.svg", iRun, layer.print_z), bbox); + svg.draw(union_ex(trimming, false), "gray", 0.5f); + svg.draw(union_ex(projection_new, false), "red", 0.5f); + svg.draw(union_ex(projection, false), "blue", 0.5f); + } +#endif /* SLIC3R_DEBUG */ }); task_group_inner.wait(); projection = std::move(projection_new); @@ -1662,69 +2003,81 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta // If no vec item with Z value >= of an internal threshold of fn_higher_equal is found, return vec.size() // If the initial idx is size_t(-1), then use binary search. // Otherwise search linearly upwards. -template -size_t idx_higher_or_equal(const std::vector &vec, size_t idx, FN_HIGHER_EQUAL fn_higher_equal) +template +IndexType idx_higher_or_equal(IteratorType begin, IteratorType end, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal) { - if (vec.empty()) { + auto size = int(end - begin); + if (size == 0) { idx = 0; - } else if (idx == size_t(-1)) { + } else if (idx == IndexType(-1)) { // First of the batch of layers per thread pool invocation. Use binary search. int idx_low = 0; - int idx_high = std::max(0, int(vec.size()) - 1); + int idx_high = std::max(0, size - 1); while (idx_low + 1 < idx_high) { int idx_mid = (idx_low + idx_high) / 2; - if (fn_higher_equal(vec[idx_mid])) + if (fn_higher_equal(begin[idx_mid])) idx_high = idx_mid; else idx_low = idx_mid; } - idx = fn_higher_equal(vec[idx_low]) ? idx_low : - (fn_higher_equal(vec[idx_high]) ? idx_high : vec.size()); + idx = fn_higher_equal(begin[idx_low]) ? idx_low : + (fn_higher_equal(begin[idx_high]) ? idx_high : size); } else { // For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search. - while (idx < vec.size() && ! fn_higher_equal(vec[idx])) + while (int(idx) < size && ! fn_higher_equal(begin[idx])) ++ idx; } return idx; } +template +IndexType idx_higher_or_equal(const std::vector& vec, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal) +{ + return idx_higher_or_equal(vec.begin(), vec.end(), idx, fn_higher_equal); +} // FN_LOWER_EQUAL: the provided object pointer has a Z value <= of an internal threshold. // Find the first item with Z value <= of an internal threshold of fn_lower_equal. // If no vec item with Z value <= of an internal threshold of fn_lower_equal is found, return -1. // If the initial idx is < -1, then use binary search. // Otherwise search linearly downwards. -template -int idx_lower_or_equal(const std::vector &vec, int idx, FN_LOWER_EQUAL fn_lower_equal) +template +int idx_lower_or_equal(IT begin, IT end, int idx, FN_LOWER_EQUAL fn_lower_equal) { - if (vec.empty()) { + auto size = int(end - begin); + if (size == 0) { idx = -1; } else if (idx < -1) { // First of the batch of layers per thread pool invocation. Use binary search. int idx_low = 0; - int idx_high = std::max(0, int(vec.size()) - 1); + int idx_high = std::max(0, size - 1); while (idx_low + 1 < idx_high) { int idx_mid = (idx_low + idx_high) / 2; - if (fn_lower_equal(vec[idx_mid])) + if (fn_lower_equal(begin[idx_mid])) idx_low = idx_mid; else idx_high = idx_mid; } - idx = fn_lower_equal(vec[idx_high]) ? idx_high : - (fn_lower_equal(vec[idx_low ]) ? idx_low : -1); + idx = fn_lower_equal(begin[idx_high]) ? idx_high : + (fn_lower_equal(begin[idx_low ]) ? idx_low : -1); } else { // For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search. - while (idx >= 0 && ! fn_lower_equal(vec[idx])) + while (idx >= 0 && ! fn_lower_equal(begin[idx])) -- idx; } return idx; } +template +int idx_lower_or_equal(const std::vector &vec, int idx, FN_LOWER_EQUAL fn_lower_equal) +{ + return idx_lower_or_equal(vec.begin(), vec.end(), idx, fn_lower_equal); +} // Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them. void PrintObjectSupportMaterial::trim_top_contacts_by_bottom_contacts( const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const { tbb::parallel_for(tbb::blocked_range(0, int(top_contacts.size())), - [this, &object, &bottom_contacts, &top_contacts](const tbb::blocked_range& range) { + [&bottom_contacts, &top_contacts](const tbb::blocked_range& range) { int idx_bottom_overlapping_first = -2; // For all top contact layers, counting downwards due to the way idx_higher_or_equal caches the last index to avoid repeated binary search. for (int idx_top = range.end() - 1; idx_top >= range.begin(); -- idx_top) { @@ -1829,7 +2182,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int assert(extr2z > extr1z || (extr1 != nullptr && extr2->layer_type == sltBottomContact)); if (std::abs(extr1z) < EPSILON) { // This layer interval starts with the 1st layer. Print the 1st layer using the prescribed 1st layer thickness. - assert(! m_slicing_params.has_raft()); + // assert(! m_slicing_params.has_raft()); RaftingEdition: unclear where the issue is: assert fails with 1-layer raft & base supports assert(intermediate_layers.empty() || intermediate_layers.back()->print_z <= m_slicing_params.first_print_layer_height); // At this point only layers above first_print_layer_heigth + EPSILON are expected as the other cases were captured earlier. assert(extr2z >= m_slicing_params.first_print_layer_height + EPSILON); @@ -1953,7 +2306,7 @@ void PrintObjectSupportMaterial::generate_base_layers( BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_base_layers() in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, intermediate_layers.size()), - [this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_support_areas](const tbb::blocked_range& range) { + [&object, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_support_areas](const tbb::blocked_range& range) { // index -2 means not initialized yet, -1 means intialized and decremented to 0 and then -1. int idx_top_contact_above = -2; int idx_bottom_contact_overlapping = -2; @@ -1972,7 +2325,7 @@ void PrintObjectSupportMaterial::generate_base_layers( Polygons polygons_new; // Use the precomputed layer_support_areas. - idx_object_layer_above = std::max(0, idx_lower_or_equal(object.layers(), idx_object_layer_above, + idx_object_layer_above = std::max(0, idx_lower_or_equal(object.layers().begin(), object.layers().end(), idx_object_layer_above, [&layer_intermediate](const Layer *layer){ return layer->print_z <= layer_intermediate.print_z + EPSILON; })); polygons_new = layer_support_areas[idx_object_layer_above]; @@ -2108,7 +2461,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object( // Find the overlapping object layers including the extra above / below gap. coordf_t z_threshold = support_layer.print_z - support_layer.height - gap_extra_below + EPSILON; idx_object_layer_overlapping = idx_higher_or_equal( - object.layers(), idx_object_layer_overlapping, + object.layers().begin(), object.layers().end(), idx_object_layer_overlapping, [z_threshold](const Layer *layer){ return layer->print_z >= z_threshold; }); // Collect all the object layers intersecting with this layer. Polygons polygons_trimming; @@ -2150,14 +2503,44 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object( } PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raft_base( + const PrintObject &object, const MyLayersPtr &top_contacts, const MyLayersPtr &interface_layers, const MyLayersPtr &base_layers, MyLayerStorage &layer_storage) const { + // If there is brim to be generated, calculate the trimming regions. + Polygons brim; + if (object.has_brim()) { + // Calculate the area covered by the brim. + const BrimType brim_type = object.config().brim_type; + const bool brim_outer = brim_type == btOuterOnly || brim_type == btOuterAndInner; + const bool brim_inner = brim_type == btInnerOnly || brim_type == btOuterAndInner; + const auto brim_offset = scaled(object.config().brim_offset.value + object.config().brim_width.value); + for (const ExPolygon &ex : object.layers().front()->lslices) { + if (brim_outer && brim_inner) + polygons_append(brim, offset(ex, brim_offset)); + else { + if (brim_outer) + polygons_append(brim, offset(ex.contour, brim_offset, ClipperLib::jtRound, float(scale_(0.1)))); + else + brim.emplace_back(ex.contour); + if (brim_inner) { + Polygons holes = ex.holes; + polygons_reverse(holes); + holes = offset(holes, - brim_offset, ClipperLib::jtRound, float(scale_(0.1))); + polygons_reverse(holes); + polygons_append(brim, std::move(holes)); + } else + polygons_append(brim, ex.holes); + } + } + brim = union_(brim); + } + // How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed. const float inflate_factor_fine = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON)); - const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine; + const float inflate_factor_1st_layer = std::max(0.f, float(scale_(object.config().raft_first_layer_expansion)) - inflate_factor_fine); MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front(); MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front(); MyLayer *columns_base = base_layers .empty() ? nullptr : base_layers .front(); @@ -2202,7 +2585,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf new_layer.print_z = m_slicing_params.first_print_layer_height; new_layer.height = m_slicing_params.first_print_layer_height; new_layer.bottom_z = 0.; - new_layer.polygons = offset(base, inflate_factor_1st_layer); + new_layer.polygons = inflate_factor_1st_layer > 0 ? offset(base, inflate_factor_1st_layer) : base; } // Insert the base layers. for (size_t i = 1; i < m_slicing_params.base_raft_layers; ++ i) { @@ -2229,17 +2612,24 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf } else if (columns_base != nullptr) { // Expand the bases of the support columns in the 1st layer. columns_base->polygons = diff( - offset(columns_base->polygons, inflate_factor_1st_layer), + inflate_factor_1st_layer > 0 ? offset(columns_base->polygons, inflate_factor_1st_layer) : columns_base->polygons, offset(m_object->layers().front()->lslices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS)); if (contacts != nullptr) columns_base->polygons = diff(columns_base->polygons, interface_polygons); + if (! brim.empty()) { + columns_base->polygons = diff(columns_base->polygons, brim); + if (contacts) + contacts->polygons = diff(contacts->polygons, brim); + if (interfaces) + interfaces->polygons = diff(interfaces->polygons, brim); + } } return raft_layers; } -// Convert some of the intermediate layers into top/bottom interface layers. -PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_interface_layers( +// Convert some of the intermediate layers into top/bottom interface layers as well as base interface layers. +std::pair PrintObjectSupportMaterial::generate_interface_layers( const MyLayersPtr &bottom_contacts, const MyLayersPtr &top_contacts, MyLayersPtr &intermediate_layers, @@ -2247,99 +2637,160 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_int { // my $area_threshold = $self->interface_flow->scaled_spacing ** 2; - MyLayersPtr interface_layers; + std::pair base_and_interface_layers; + MyLayersPtr &interface_layers = base_and_interface_layers.first; + MyLayersPtr &base_interface_layers = base_and_interface_layers.second; + + // distinguish between interface and base interface layers // Contact layer is considered an interface layer, therefore run the following block only if support_material_interface_layers > 1. - if (! intermediate_layers.empty() && m_object_config->support_material_interface_layers.value > 1) { + // Contact layer needs a base_interface layer, therefore run the following block if support_material_interface_layers > 0, has soluble support and extruders are different. + bool soluble_interface_non_soluble_base = + // Zero z-gap between the overhangs and the support interface. + m_slicing_params.soluble_interface && + // Interface extruder soluble. + m_object_config->support_material_interface_extruder.value > 0 && m_print_config->filament_soluble.get_at(m_object_config->support_material_interface_extruder.value - 1) && + // Base extruder: Either "print with active extruder" not soluble. + (m_object_config->support_material_extruder.value == 0 || ! m_print_config->filament_soluble.get_at(m_object_config->support_material_extruder.value - 1)); + int num_interface_layers = m_object_config->support_material_interface_layers.value; + int num_base_interface_layers = soluble_interface_non_soluble_base ? std::min(num_interface_layers / 2, 2) : 0; + + if (! intermediate_layers.empty() && num_interface_layers > 1) { // For all intermediate layers, collect top contact surfaces, which are not further than support_material_interface_layers. BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_interface_layers() in parallel - start"; + // Since the intermediate layer index starts at zero the number of interface layer needs to be reduced by 1. + -- num_interface_layers; + int num_interface_layers_only = num_interface_layers - num_base_interface_layers; interface_layers.assign(intermediate_layers.size(), nullptr); + if (num_base_interface_layers) + base_interface_layers.assign(intermediate_layers.size(), nullptr); tbb::spin_mutex layer_storage_mutex; - tbb::parallel_for(tbb::blocked_range(0, intermediate_layers.size()), - [this, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_storage, &layer_storage_mutex, &interface_layers](const tbb::blocked_range& range) { + // Insert a new layer into base_interface_layers, if intersection with base exists. + auto insert_layer = [&layer_storage, &layer_storage_mutex](MyLayer &intermediate_layer, Polygons &bottom, Polygons &&top, const Polygons *subtract, SupporLayerType type) { + assert(! bottom.empty() || ! top.empty()); + MyLayer &layer_new = layer_allocate(layer_storage, layer_storage_mutex, type); + layer_new.print_z = intermediate_layer.print_z; + layer_new.bottom_z = intermediate_layer.bottom_z; + layer_new.height = intermediate_layer.height; + layer_new.bridging = intermediate_layer.bridging; + // Merge top into bottom, unite them with a safety offset. + append(bottom, std::move(top)); + layer_new.polygons = union_(std::move(bottom), true); + // Subtract the interface from the base regions. + intermediate_layer.polygons = diff(intermediate_layer.polygons, layer_new.polygons, false); + if (subtract) + // Trim the base interface layer with the interface layer. + layer_new.polygons = diff(std::move(layer_new.polygons), *subtract); + //FIXME filter layer_new.polygons islands by a minimum area? +// $interface_area = [ grep abs($_->area) >= $area_threshold, @$interface_area ]; + return &layer_new; + }; + tbb::parallel_for(tbb::blocked_range(0, int(intermediate_layers.size())), + [&bottom_contacts, &top_contacts, &intermediate_layers, &insert_layer, num_interface_layers, num_base_interface_layers, num_interface_layers_only, + &interface_layers, &base_interface_layers](const tbb::blocked_range& range) { + // Gather the top / bottom contact layers intersecting with num_interface_layers resp. num_interface_layers_only intermediate layers above / below + // this intermediate layer. // Index of the first top contact layer intersecting the current intermediate layer. - size_t idx_top_contact_first = size_t(-1); + auto idx_top_contact_first = -1; // Index of the first bottom contact layer intersecting the current intermediate layer. - size_t idx_bottom_contact_first = size_t(-1); - for (size_t idx_intermediate_layer = range.begin(); idx_intermediate_layer < range.end(); ++ idx_intermediate_layer) { + auto idx_bottom_contact_first = -1; + auto num_intermediate = int(intermediate_layers.size()); + for (int idx_intermediate_layer = range.begin(); idx_intermediate_layer < range.end(); ++ idx_intermediate_layer) { MyLayer &intermediate_layer = *intermediate_layers[idx_intermediate_layer]; - // Top / bottom Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces. - coordf_t top_z = intermediate_layers[std::min(intermediate_layers.size()-1, idx_intermediate_layer + m_object_config->support_material_interface_layers - 1)]->print_z; - coordf_t bottom_z = intermediate_layers[std::max(0, int(idx_intermediate_layer) - int(m_object_config->support_material_interface_layers) + 1)]->bottom_z; + // Top / bottom Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces + coordf_t top_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers - 1)]->print_z; + coordf_t top_inteface_z = std::numeric_limits::max(); + coordf_t bottom_z = intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers + 1)]->bottom_z; + coordf_t bottom_interface_z = - std::numeric_limits::max(); + if (num_base_interface_layers > 0) { + // Some base interface layers will be generated. + if (num_interface_layers_only == 0) + // Only base interface layers to generate. + std::swap(top_inteface_z, bottom_interface_z); + else { + top_inteface_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers_only - 1)]->print_z; + bottom_interface_z = intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers_only)]->bottom_z; + } + } // Move idx_top_contact_first up until above the current print_z. idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON // Collect the top contact areas above this intermediate layer, below top_z. - Polygons polygons_top_contact_projected; - for (size_t idx_top_contact = idx_top_contact_first; idx_top_contact < top_contacts.size(); ++ idx_top_contact) { + Polygons polygons_top_contact_projected_interface; + Polygons polygons_top_contact_projected_base; + for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) { const MyLayer &top_contact_layer = *top_contacts[idx_top_contact]; //FIXME maybe this adds one interface layer in excess? if (top_contact_layer.bottom_z - EPSILON > top_z) break; - polygons_append(polygons_top_contact_projected, top_contact_layer.polygons); + polygons_append(top_contact_layer.bottom_z - EPSILON > top_inteface_z ? polygons_top_contact_projected_base : polygons_top_contact_projected_interface, top_contact_layer.polygons); } // Move idx_bottom_contact_first up until touching bottom_z. idx_bottom_contact_first = idx_higher_or_equal(bottom_contacts, idx_bottom_contact_first, [bottom_z](const MyLayer *layer){ return layer->print_z >= bottom_z - EPSILON; }); // Collect the top contact areas above this intermediate layer, below top_z. - Polygons polygons_bottom_contact_projected; - for (size_t idx_bottom_contact = idx_bottom_contact_first; idx_bottom_contact < bottom_contacts.size(); ++ idx_bottom_contact) { + Polygons polygons_bottom_contact_projected_interface; + Polygons polygons_bottom_contact_projected_base; + for (int idx_bottom_contact = idx_bottom_contact_first; idx_bottom_contact < int(bottom_contacts.size()); ++ idx_bottom_contact) { const MyLayer &bottom_contact_layer = *bottom_contacts[idx_bottom_contact]; if (bottom_contact_layer.print_z - EPSILON > intermediate_layer.bottom_z) break; - polygons_append(polygons_bottom_contact_projected, bottom_contact_layer.polygons); + polygons_append(bottom_contact_layer.print_z - EPSILON > bottom_interface_z ? polygons_bottom_contact_projected_interface : polygons_bottom_contact_projected_base, bottom_contact_layer.polygons); } - if (polygons_top_contact_projected.empty() && polygons_bottom_contact_projected.empty()) - continue; - - // Insert a new layer into top_interface_layers. - MyLayer &layer_new = layer_allocate(layer_storage, layer_storage_mutex, - polygons_top_contact_projected.empty() ? sltBottomInterface : sltTopInterface); - layer_new.print_z = intermediate_layer.print_z; - layer_new.bottom_z = intermediate_layer.bottom_z; - layer_new.height = intermediate_layer.height; - layer_new.bridging = intermediate_layer.bridging; - interface_layers[idx_intermediate_layer] = &layer_new; - - polygons_append(polygons_top_contact_projected, polygons_bottom_contact_projected); - polygons_top_contact_projected = union_(polygons_top_contact_projected, true); - layer_new.polygons = intersection(intermediate_layer.polygons, polygons_top_contact_projected); - //FIXME filter layer_new.polygons islands by a minimum area? - // $interface_area = [ grep abs($_->area) >= $area_threshold, @$interface_area ]; - intermediate_layer.polygons = diff(intermediate_layer.polygons, polygons_top_contact_projected, false); + MyLayer *interface_layer = nullptr; + if (! polygons_bottom_contact_projected_interface.empty() || ! polygons_top_contact_projected_interface.empty()) { + interface_layer = insert_layer( + intermediate_layer, polygons_bottom_contact_projected_interface, std::move(polygons_top_contact_projected_interface), nullptr, + polygons_top_contact_projected_interface.empty() ? sltBottomInterface : sltTopInterface); + interface_layers[idx_intermediate_layer] = interface_layer; + } + if (! polygons_bottom_contact_projected_base.empty() || ! polygons_top_contact_projected_base.empty()) + base_interface_layers[idx_intermediate_layer] = insert_layer( + intermediate_layer, polygons_bottom_contact_projected_base, std::move(polygons_top_contact_projected_base), + interface_layer ? &interface_layer->polygons : nullptr, sltBase); } }); // Compress contact_out, remove the nullptr items. remove_nulls(interface_layers); + remove_nulls(base_interface_layers); BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_interface_layers() in parallel - start"; } - return interface_layers; + return base_and_interface_layers; +} + +static inline void fill_expolygon_generate_paths( + ExtrusionEntitiesPtr &dst, + ExPolygon &&expolygon, + Fill *filler, + const FillParams &fill_params, + float density, + ExtrusionRole role, + const Flow &flow) +{ + Surface surface(stInternal, std::move(expolygon)); + Polylines polylines; + try { + polylines = filler->fill_surface(&surface, fill_params); + } catch (InfillFailedException &) { + } + extrusion_entities_append_paths( + dst, + std::move(polylines), + role, + flow.mm3_per_mm(), flow.width, flow.height); } static inline void fill_expolygons_generate_paths( - ExtrusionEntitiesPtr &dst, - const ExPolygons &expolygons, + ExtrusionEntitiesPtr &dst, + ExPolygons &&expolygons, Fill *filler, + const FillParams &fill_params, float density, - ExtrusionRole role, + ExtrusionRole role, const Flow &flow) { - FillParams fill_params; - fill_params.density = density; - fill_params.dont_adjust = true; - for (const ExPolygon &expoly : expolygons) { - Surface surface(stInternal, expoly); - Polylines polylines; - try { - polylines = filler->fill_surface(&surface, fill_params); - } catch (InfillFailedException &) { - } - extrusion_entities_append_paths( - dst, - std::move(polylines), - role, - flow.mm3_per_mm(), flow.width, flow.height); - } + for (ExPolygon &expoly : expolygons) + fill_expolygon_generate_paths(dst, std::move(expoly), filler, fill_params, density, role, flow); } static inline void fill_expolygons_generate_paths( @@ -2351,20 +2802,53 @@ static inline void fill_expolygons_generate_paths( const Flow &flow) { FillParams fill_params; - fill_params.density = density; + fill_params.density = density; fill_params.dont_adjust = true; - for (ExPolygon &expoly : expolygons) { - Surface surface(stInternal, std::move(expoly)); + fill_expolygons_generate_paths(dst, std::move(expolygons), filler, fill_params, density, role, flow); +} + +static inline void fill_expolygons_with_sheath_generate_paths( + ExtrusionEntitiesPtr &dst, + const Polygons &polygons, + Fill *filler, + float density, + ExtrusionRole role, + const Flow &flow, + bool with_sheath) +{ + if (polygons.empty()) + return; + + if (! with_sheath) { + fill_expolygons_generate_paths(dst, offset2_ex(polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)), filler, density, role, flow); + return; + } + + FillParams fill_params; + fill_params.density = density; + fill_params.dont_adjust = true; + + double spacing = flow.scaled_spacing(); + // Clip the sheath path to avoid the extruder to get exactly on the first point of the loop. + double clip_length = spacing * 0.15; + + for (ExPolygon &expoly : offset2_ex(polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width()))) { + // Don't reorder the skirt and its infills. + auto eec = std::make_unique(); + eec->no_sort = true; + // Draw the perimeters. Polylines polylines; - try { - polylines = filler->fill_surface(&surface, fill_params); - } catch (InfillFailedException &) { - } - extrusion_entities_append_paths( - dst, - std::move(polylines), - role, - flow.mm3_per_mm(), flow.width, flow.height); + polylines.reserve(expoly.holes.size() + 1); + for (size_t i = 0; i <= expoly.holes.size(); ++ i) { + Polyline pl(i == 0 ? expoly.contour.points : expoly.holes[i - 1].points); + pl.points.emplace_back(pl.points.front()); + pl.clip_end(clip_length); + polylines.emplace_back(std::move(pl)); + } + extrusion_entities_append_paths(eec->entities, polylines, erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height); + // Fill in the rest. + fill_expolygons_generate_paths(eec->entities, offset_ex(expoly, float(-0.4 * spacing)), filler, fill_params, density, role, flow); + dst.emplace_back(eec.release()); } } @@ -2388,9 +2872,9 @@ struct MyLayerExtruded const Polygons& polygons_to_extrude() const { return (m_polygons_to_extrude == nullptr) ? layer->polygons : *m_polygons_to_extrude; } bool could_merge(const MyLayerExtruded &other) const { - return ! this->empty() && ! other.empty() && + return ! this->empty() && ! other.empty() && std::abs(this->layer->height - other.layer->height) < EPSILON && - this->layer->bridging == other.layer->bridging; + this->layer->bridging == other.layer->bridging; } // Merge regions, perform boolean union over the merged polygons. @@ -2931,12 +3415,13 @@ void modulate_extrusion_by_overlapping_layers( } void PrintObjectSupportMaterial::generate_toolpaths( - const PrintObject &object, + SupportLayerPtrs &support_layers, const MyLayersPtr &raft_layers, const MyLayersPtr &bottom_contacts, const MyLayersPtr &top_contacts, const MyLayersPtr &intermediate_layers, - const MyLayersPtr &interface_layers) const + const MyLayersPtr &interface_layers, + const MyLayersPtr &base_interface_layers) const { // Slic3r::debugf "Generating patterns\n"; // loop_interface_processor with a given circle radius. @@ -3000,13 +3485,13 @@ void PrintObjectSupportMaterial::generate_toolpaths( // Insert the raft base layers. size_t n_raft_layers = size_t(std::max(0, int(m_slicing_params.raft_layers()) - 1)); tbb::parallel_for(tbb::blocked_range(0, n_raft_layers), - [this, &object, &raft_layers, + [this, &support_layers, &raft_layers, infill_pattern, &bbox_object, support_density, interface_density, raft_angle_1st_layer, raft_angle_base, raft_angle_interface, link_max_length_factor, with_sheath] (const tbb::blocked_range& range) { for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) { assert(support_layer_id < raft_layers.size()); - SupportLayer &support_layer = *object.support_layers()[support_layer_id]; + SupportLayer &support_layer = *support_layers[support_layer_id]; assert(support_layer.support_fills.entities.empty()); MyLayer &raft_layer = *raft_layers[support_layer_id]; @@ -3017,45 +3502,26 @@ void PrintObjectSupportMaterial::generate_toolpaths( // Print the support base below the support columns, or the support base for the support columns plus the contacts. if (support_layer_id > 0) { - Polygons to_infill_polygons = (support_layer_id < m_slicing_params.base_raft_layers) ? + const Polygons &to_infill_polygons = (support_layer_id < m_slicing_params.base_raft_layers) ? raft_layer.polygons : //FIXME misusing contact_polygons for support columns. ((raft_layer.contact_polygons == nullptr) ? Polygons() : *raft_layer.contact_polygons); if (! to_infill_polygons.empty()) { Flow flow(float(m_support_material_flow.width), float(raft_layer.height), m_support_material_flow.nozzle_diameter, raft_layer.bridging); - // find centerline of the external loop/extrusions - ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ? - // union_ex(base_polygons, true) : - offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)) : - offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width())); - if (! to_infill.empty() && with_sheath) { - // Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove. - // TODO: use brim ordering algorithm - to_infill_polygons = to_polygons(to_infill); - // TODO: use offset2_ex() - to_infill = offset_ex(to_infill, float(- 0.4 * flow.scaled_spacing())); - extrusion_entities_append_paths( - support_layer.support_fills.entities, - to_polylines(std::move(to_infill_polygons)), - erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height); - } - if (! to_infill.empty()) { - // We don't use $base_flow->spacing because we need a constant spacing - // value that guarantees that all layers are correctly aligned. - Fill *filler = filler_support.get(); - filler->angle = raft_angle_base; - filler->spacing = m_support_material_flow.spacing(); - filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density)); - fill_expolygons_generate_paths( - // Destination - support_layer.support_fills.entities, - // Regions to fill - std::move(to_infill), - // Filler and its parameters - filler, float(support_density), - // Extrusion parameters - erSupportMaterial, flow); - } + Fill * filler = filler_support.get(); + filler->angle = raft_angle_base; + filler->spacing = m_support_material_flow.spacing(); + filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density)); + fill_expolygons_with_sheath_generate_paths( + // Destination + support_layer.support_fills.entities, + // Regions to fill + to_infill_polygons, + // Filler and its parameters + filler, float(support_density), + // Extrusion parameters + erSupportMaterial, flow, + with_sheath); } } @@ -3078,15 +3544,17 @@ void PrintObjectSupportMaterial::generate_toolpaths( } else continue; filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density)); - fill_expolygons_generate_paths( + fill_expolygons_with_sheath_generate_paths( // Destination support_layer.support_fills.entities, // Regions to fill - offset2_ex(raft_layer.polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)), + raft_layer.polygons, // Filler and its parameters filler, density, // Extrusion parameters - (support_layer_id < m_slicing_params.base_raft_layers) ? erSupportMaterial : erSupportMaterialInterface, flow); + (support_layer_id < m_slicing_params.base_raft_layers) ? erSupportMaterial : erSupportMaterialInterface, flow, + // sheath at first layer + support_layer_id == 0); } }); @@ -3100,26 +3568,40 @@ void PrintObjectSupportMaterial::generate_toolpaths( MyLayerExtruded top_contact_layer; MyLayerExtruded base_layer; MyLayerExtruded interface_layer; + MyLayerExtruded base_interface_layer; std::vector overlaps; }; - std::vector layer_caches(object.support_layers().size(), LayerCache()); + std::vector layer_caches(support_layers.size(), LayerCache()); - tbb::parallel_for(tbb::blocked_range(n_raft_layers, object.support_layers().size()), - [this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &layer_caches, &loop_interface_processor, + tbb::parallel_for(tbb::blocked_range(n_raft_layers, support_layers.size()), + [this, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor, infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath] (const tbb::blocked_range& range) { // Indices of the 1st layer in their respective container at the support layer height. size_t idx_layer_bottom_contact = size_t(-1); size_t idx_layer_top_contact = size_t(-1); size_t idx_layer_intermediate = size_t(-1); - size_t idx_layer_inteface = size_t(-1); - std::unique_ptr filler_interface = std::unique_ptr(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear)); - std::unique_ptr filler_support = std::unique_ptr(Fill::new_from_type(infill_pattern)); + size_t idx_layer_interface = size_t(-1); + size_t idx_layer_base_interface = size_t(-1); + const auto fill_type_interface = m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear; + const auto fill_type_first_layer = ipRectilinear; + auto filler_interface = std::unique_ptr(Fill::new_from_type(fill_type_interface)); + // Filler for the 1st layer interface, if different from filler_interface. + auto filler_first_layer_ptr = std::unique_ptr(range.begin() == 0 && fill_type_interface != fill_type_first_layer ? Fill::new_from_type(fill_type_first_layer) : nullptr); + // Pointer to the 1st layer interface filler. + auto filler_first_layer = filler_first_layer_ptr ? filler_first_layer_ptr.get() : filler_interface.get(); + // Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer). + auto filler_base_interface = std::unique_ptr(base_interface_layers.empty() ? nullptr : Fill::new_from_type(ipRectilinear)); + auto filler_support = std::unique_ptr(Fill::new_from_type(infill_pattern)); filler_interface->set_bounding_box(bbox_object); + if (filler_first_layer_ptr) + filler_first_layer_ptr->set_bounding_box(bbox_object); + if (filler_base_interface) + filler_base_interface->set_bounding_box(bbox_object); filler_support->set_bounding_box(bbox_object); for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) { - SupportLayer &support_layer = *object.support_layers()[support_layer_id]; + SupportLayer &support_layer = *support_layers[support_layer_id]; LayerCache &layer_cache = layer_caches[support_layer_id]; // Find polygons with the same print_z. @@ -3127,21 +3609,25 @@ void PrintObjectSupportMaterial::generate_toolpaths( MyLayerExtruded &top_contact_layer = layer_cache.top_contact_layer; MyLayerExtruded &base_layer = layer_cache.base_layer; MyLayerExtruded &interface_layer = layer_cache.interface_layer; + MyLayerExtruded &base_interface_layer = layer_cache.base_interface_layer; // Increment the layer indices to find a layer at support_layer.print_z. { auto fun = [&support_layer](const MyLayer *l){ return l->print_z >= support_layer.print_z - EPSILON; }; idx_layer_bottom_contact = idx_higher_or_equal(bottom_contacts, idx_layer_bottom_contact, fun); idx_layer_top_contact = idx_higher_or_equal(top_contacts, idx_layer_top_contact, fun); idx_layer_intermediate = idx_higher_or_equal(intermediate_layers, idx_layer_intermediate, fun); - idx_layer_inteface = idx_higher_or_equal(interface_layers, idx_layer_inteface, fun); + idx_layer_interface = idx_higher_or_equal(interface_layers, idx_layer_interface, fun); + idx_layer_base_interface = idx_higher_or_equal(base_interface_layers, idx_layer_base_interface,fun); } // Copy polygons from the layers. if (idx_layer_bottom_contact < bottom_contacts.size() && bottom_contacts[idx_layer_bottom_contact]->print_z < support_layer.print_z + EPSILON) bottom_contact_layer.layer = bottom_contacts[idx_layer_bottom_contact]; if (idx_layer_top_contact < top_contacts.size() && top_contacts[idx_layer_top_contact]->print_z < support_layer.print_z + EPSILON) top_contact_layer.layer = top_contacts[idx_layer_top_contact]; - if (idx_layer_inteface < interface_layers.size() && interface_layers[idx_layer_inteface]->print_z < support_layer.print_z + EPSILON) - interface_layer.layer = interface_layers[idx_layer_inteface]; + if (idx_layer_interface < interface_layers.size() && interface_layers[idx_layer_interface]->print_z < support_layer.print_z + EPSILON) + interface_layer.layer = interface_layers[idx_layer_interface]; + if (idx_layer_base_interface < base_interface_layers.size() && base_interface_layers[idx_layer_base_interface]->print_z < support_layer.print_z + EPSILON) + base_interface_layer.layer = base_interface_layers[idx_layer_base_interface]; if (idx_layer_intermediate < intermediate_layers.size() && intermediate_layers[idx_layer_intermediate]->print_z < support_layer.print_z + EPSILON) base_layer.layer = intermediate_layers[idx_layer_intermediate]; @@ -3166,7 +3652,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( top_contact_layer.merge(std::move(interface_layer)); } - if (! interface_layer.empty() && ! base_layer.empty()) { + if ( ! interface_layer.empty() && ! base_layer.empty()) { // turn base support into interface when it's contained in our holes // (this way we get wider interface anchoring) //FIXME one wants to fill in the inner most holes of the interfaces, not all the holes. @@ -3207,9 +3693,33 @@ void PrintObjectSupportMaterial::generate_toolpaths( erSupportMaterialInterface, interface_flow); } + // Base interface layers under soluble interfaces + if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()){ + Fill *filler = filler_base_interface.get(); + //FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore + // the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b) + Flow interface_flow( + float(base_interface_layer.layer->bridging ? base_interface_layer.layer->height : m_support_material_flow.width), // m_support_material_interface_flow.width)), + float(base_interface_layer.layer->height), + m_support_material_flow.nozzle_diameter, + base_interface_layer.layer->bridging); + filler->angle = interface_angle; + filler->spacing = m_support_material_interface_flow.spacing(); + filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / interface_density)); + fill_expolygons_generate_paths( + // Destination + base_interface_layer.extrusions, + //base_layer_interface.extrusions, + // Regions to fill + union_ex(base_interface_layer.polygons_to_extrude(), true), + // Filler and its parameters + filler, float(interface_density), + // Extrusion parameters + erSupportMaterial, interface_flow); + } + // Base support or flange. if (! base_layer.empty() && ! base_layer.polygons_to_extrude().empty()) { - //FIXME When paralellizing, each thread shall have its own copy of the fillers. Fill *filler = filler_support.get(); filler->angle = angles[support_layer_id % angles.size()]; // We don't use $base_flow->spacing because we need a constant spacing @@ -3222,51 +3732,47 @@ void PrintObjectSupportMaterial::generate_toolpaths( filler->spacing = m_support_material_flow.spacing(); filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density)); float density = float(support_density); - // find centerline of the external loop/extrusions - ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ? - // union_ex(base_polygons, true) : - offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON)) : - offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width())); + bool sheath = with_sheath; if (base_layer.layer->bottom_z < EPSILON) { // Base flange (the 1st layer). - filler = filler_interface.get(); + filler = filler_first_layer; filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.)); - density = 0.5f; + density = float(m_object_config->raft_first_layer_density.value * 0.01); flow = m_first_layer_flow; // use the proper spacing for first layer as we don't need to align // its pattern to the other layers //FIXME When paralellizing, each thread shall have its own copy of the fillers. filler->spacing = flow.spacing(); filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density)); - } else if (with_sheath) { - // Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove. - // TODO: use brim ordering algorithm - Polygons to_infill_polygons = to_polygons(to_infill); - // TODO: use offset2_ex() - to_infill = offset_ex(to_infill, - 0.4f * float(flow.scaled_spacing())); - extrusion_entities_append_paths( - base_layer.extrusions, - to_polylines(std::move(to_infill_polygons)), - erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height); + sheath = true; } - fill_expolygons_generate_paths( + fill_expolygons_with_sheath_generate_paths( // Destination - base_layer.extrusions, + base_layer.extrusions, // Regions to fill - std::move(to_infill), + base_layer.polygons_to_extrude(), // Filler and its parameters filler, density, // Extrusion parameters - erSupportMaterial, flow); + erSupportMaterial, flow, + sheath); + } - layer_cache.overlaps.reserve(4); + // Merge base_interface_layers to base_layers to avoid unneccessary retractions + if (! base_layer.empty() && ! base_interface_layer.empty() && ! base_layer.polygons_to_extrude().empty() && ! base_interface_layer.polygons_to_extrude().empty() && + base_layer.could_merge(base_interface_layer)) + base_layer.merge(std::move(base_interface_layer)); + + layer_cache.overlaps.reserve(5); if (! bottom_contact_layer.empty()) layer_cache.overlaps.push_back(&bottom_contact_layer); if (! top_contact_layer.empty()) layer_cache.overlaps.push_back(&top_contact_layer); if (! interface_layer.empty()) layer_cache.overlaps.push_back(&interface_layer); + if (! base_interface_layer.empty()) + layer_cache.overlaps.push_back(&base_interface_layer); if (! base_layer.empty()) layer_cache.overlaps.push_back(&base_layer); // Sort the layers with the same print_z coordinate by their heights, thickest first. @@ -3287,7 +3793,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( // where it overlaps with another support layer. //FIXME When printing a briging path, what is an equivalent height of the squished extrudate of the same width? // Collect overlapping top/bottom surfaces. - layer_cache_item.overlapping.reserve(16); + layer_cache_item.overlapping.reserve(20); coordf_t bottom_z = layer_cache_item.layer_extruded->layer->bottom_print_z() + EPSILON; for (int i = int(idx_layer_bottom_contact) - 1; i >= 0 && bottom_contacts[i]->print_z > bottom_z; -- i) layer_cache_item.overlapping.push_back(bottom_contacts[i]); @@ -3297,8 +3803,10 @@ void PrintObjectSupportMaterial::generate_toolpaths( // Bottom contact layer may overlap with a base layer, which may be changed to interface layer. for (int i = int(idx_layer_intermediate) - 1; i >= 0 && intermediate_layers[i]->print_z > bottom_z; -- i) layer_cache_item.overlapping.push_back(intermediate_layers[i]); - for (int i = int(idx_layer_inteface) - 1; i >= 0 && interface_layers[i]->print_z > bottom_z; -- i) + for (int i = int(idx_layer_interface) - 1; i >= 0 && interface_layers[i]->print_z > bottom_z; -- i) layer_cache_item.overlapping.push_back(interface_layers[i]); + for (int i = int(idx_layer_base_interface) - 1; i >= 0 && base_interface_layers[i]->print_z > bottom_z; -- i) + layer_cache_item.overlapping.push_back(base_interface_layers[i]); } std::sort(layer_cache_item.overlapping.begin(), layer_cache_item.overlapping.end(), MyLayersPtrCompare()); } @@ -3317,11 +3825,11 @@ void PrintObjectSupportMaterial::generate_toolpaths( }); // Now modulate the support layer height in parallel. - tbb::parallel_for(tbb::blocked_range(n_raft_layers, object.support_layers().size()), - [this, &object, &layer_caches] + tbb::parallel_for(tbb::blocked_range(n_raft_layers, support_layers.size()), + [&support_layers, &layer_caches] (const tbb::blocked_range& range) { for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) { - SupportLayer &support_layer = *object.support_layers()[support_layer_id]; + SupportLayer &support_layer = *support_layers[support_layer_id]; LayerCache &layer_cache = layer_caches[support_layer_id]; for (LayerCacheItem &layer_cache_item : layer_cache.overlaps) { modulate_extrusion_by_overlapping_layers(layer_cache_item.layer_extruded->extrusions, *layer_cache_item.layer_extruded->layer, layer_cache_item.overlapping); @@ -3421,7 +3929,7 @@ sub clip_with_shape { foreach my $i (keys %$support) { // don't clip bottom layer with shape so that we - // can generate a continuous base flange + // can generate a continuous base flange // also don't clip raft layers next if $i == 0; next if $i < $self->object_config->raft_layers; diff --git a/src/libslic3r/SupportMaterial.hpp b/src/libslic3r/SupportMaterial.hpp index 2e1a05946f..ddc5b944c0 100644 --- a/src/libslic3r/SupportMaterial.hpp +++ b/src/libslic3r/SupportMaterial.hpp @@ -11,10 +11,6 @@ class PrintObject; class PrintConfig; class PrintObjectConfig; -// how much we extend support around the actual contact area -//FIXME this should be dependent on the nozzle diameter! -#define SUPPORT_MATERIAL_MARGIN 1.5 - // This class manages raft and supports for a single PrintObject. // Instantiated by Slic3r::Print::Object->_support_material() // This class is instantiated before the slicing starts as Object.pm will query @@ -151,7 +147,7 @@ public: // Is raft enabled? bool has_raft() const { return m_slicing_params.has_raft(); } // Has any support? - bool has_support() const { return m_object_config->support_material.value; } + bool has_support() const { return m_object_config->support_material.value || m_object_config->support_material_enforce_layers; } bool build_plate_only() const { return this->has_support() && m_object_config->support_material_buildplate_only.value; } bool synchronize_layers() const { return m_slicing_params.soluble_interface && m_object_config->support_material_synchronize_layers.value; } @@ -196,17 +192,21 @@ private: // Generate raft layers, also expand the 1st support layer // in case there is no raft layer to improve support adhesion. MyLayersPtr generate_raft_base( + const PrintObject &object, const MyLayersPtr &top_contacts, const MyLayersPtr &interface_layers, const MyLayersPtr &base_layers, MyLayerStorage &layer_storage) const; - // Turn some of the base layers into interface layers. - MyLayersPtr generate_interface_layers( + // Turn some of the base layers into base interface layers. + // For soluble interfaces with non-soluble bases, print maximum two first interface layers with the base + // extruder to improve adhesion of the soluble filament to the base. + std::pair generate_interface_layers( const MyLayersPtr &bottom_contacts, const MyLayersPtr &top_contacts, MyLayersPtr &intermediate_layers, MyLayerStorage &layer_storage) const; + // Trim support layers by an object to leave a defined gap between // the support volume and the object. @@ -224,12 +224,13 @@ private: // Produce the actual G-code. void generate_toolpaths( - const PrintObject &object, + SupportLayerPtrs &support_layers, const MyLayersPtr &raft_layers, const MyLayersPtr &bottom_contacts, const MyLayersPtr &top_contacts, const MyLayersPtr &intermediate_layers, - const MyLayersPtr &interface_layers) const; + const MyLayersPtr &interface_layers, + const MyLayersPtr &base_interface_layers) const; // Following objects are not owned by SupportMaterial class. const PrintObject *m_object; @@ -246,7 +247,7 @@ private: bool m_can_merge_support_regions; coordf_t m_support_layer_height_min; - coordf_t m_support_layer_height_max; +// coordf_t m_support_layer_height_max; coordf_t m_gap_xy; }; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 27f6719aff..1c21e2f869 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -77,29 +77,9 @@ //=================== #define ENABLE_2_3_0_BETA1 1 -#define ENABLE_DRAG_AND_DROP_FIX (1 && ENABLE_2_3_0_BETA1) #define ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN (1 && ENABLE_2_3_0_BETA1) -//=================== -// 2.3.0.beta2 techs -//=================== -#define ENABLE_2_3_0_BETA2 1 - -#define ENABLE_ARROW_KEYS_WITH_SLIDERS (1 && ENABLE_2_3_0_BETA2) -#define ENABLE_NEW_NOTIFICATIONS_FADE_OUT (1 && ENABLE_2_3_0_BETA2) -#define ENABLE_PREVIEW_TYPE_CHANGE (1 && ENABLE_2_3_0_BETA2) - - -//=================== -// 2.3.0.beta3 techs -//=================== -#define ENABLE_2_3_0_BETA3 1 - -#define ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE (1 && ENABLE_2_3_0_BETA3) -#define ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE (1 && ENABLE_2_3_0_BETA3) - - //================= // 2.3.0.rc1 techs //================= @@ -115,6 +95,10 @@ #define ENABLE_SPLITTED_VERTEX_BUFFER (1 && ENABLE_2_3_1_ALPHA1) #define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_3_1_ALPHA1) +#define ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS (1 && ENABLE_SPLITTED_VERTEX_BUFFER) +#define ENABLE_WARNING_TEXTURE_REMOVAL (1 && ENABLE_2_3_1_ALPHA1) +#define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1) +#define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index b99a21f112..adb9be64d1 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1146,6 +1146,7 @@ TriangleMeshSlicer::FacetSliceType TriangleMeshSlicer::slice_facet( return NoSlice; } +#if 0 //FIXME Should this go away? For valid meshes the function slice_facet() returns Slicing // and sets edges of vertical triangles to produce only a single edge per pair of neighbor faces. // So the following code makes only sense now to handle degenerate meshes with more than two faces @@ -1209,7 +1210,7 @@ static inline void remove_tangent_edges(std::vector &lines) } } } - +#endif struct OpenPolyline { OpenPolyline() {}; diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 71cd231c3f..9625298f4e 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -103,7 +103,7 @@ enum FacetEdgeType { class IntersectionReference { public: - IntersectionReference() : point_id(-1), edge_id(-1) {}; + IntersectionReference() : point_id(-1), edge_id(-1) {} IntersectionReference(int point_id, int edge_id) : point_id(point_id), edge_id(edge_id) {} // Where is this intersection point located? On mesh vertex or mesh edge? // Only one of the following will be set, the other will remain set to -1. @@ -116,7 +116,7 @@ public: class IntersectionPoint : public Point, public IntersectionReference { public: - IntersectionPoint() {}; + IntersectionPoint() {} IntersectionPoint(int point_id, int edge_id, const Point &pt) : IntersectionReference(point_id, edge_id), Point(pt) {} IntersectionPoint(const IntersectionReference &ir, const Point &pt) : IntersectionReference(ir), Point(pt) {} // Inherits coord_t x, y diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index 3fe6881958..7570075e56 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -419,14 +419,17 @@ TriangleSelector::TriangleSelector(const TriangleMesh& mesh) void TriangleSelector::reset() { - if (! m_orig_size_indices != 0) // unless this is run from constructor + if (m_orig_size_indices != 0) // unless this is run from constructor garbage_collect(); m_vertices.clear(); m_triangles.clear(); for (const stl_vertex& vert : m_mesh->its.vertices) m_vertices.emplace_back(vert); - for (const stl_triangle_vertex_indices& ind : m_mesh->its.indices) - push_triangle(ind[0], ind[1], ind[2]); + for (size_t i=0; iits.indices.size(); ++i) { + const stl_triangle_vertex_indices& ind = m_mesh->its.indices[i]; + const Vec3f& normal = m_mesh->stl.facet_start[i].normal; + push_triangle(ind[0], ind[1], ind[2], normal); + } m_orig_size_vertices = m_vertices.size(); m_orig_size_indices = m_triangles.size(); m_invalid_triangles = 0; @@ -451,19 +454,20 @@ void TriangleSelector::set_edge_limit(float edge_limit) -void TriangleSelector::push_triangle(int a, int b, int c) +void TriangleSelector::push_triangle(int a, int b, int c, const Vec3f& normal) { for (int i : {a, b, c}) { assert(i >= 0 && i < int(m_vertices.size())); ++m_vertices[i].ref_cnt; } - m_triangles.emplace_back(a, b, c); + m_triangles.emplace_back(a, b, c, normal); } void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state) { Triangle* tr = &m_triangles[facet_idx]; + const Vec3f normal = tr->normal; assert(tr->is_split()); @@ -483,8 +487,8 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[1]].v + m_vertices[verts_idxs[2]].v)/2.); verts_idxs.insert(verts_idxs.begin()+2, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2]); - push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0]); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], normal); + push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], normal); } if (sides_to_split == 2) { @@ -494,9 +498,9 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[0]].v + m_vertices[verts_idxs[3]].v)/2.); verts_idxs.insert(verts_idxs.begin()+4, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4]); - push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4]); - push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4]); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], normal); + push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], normal); + push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], normal); } if (sides_to_split == 3) { @@ -507,10 +511,10 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[4]].v + m_vertices[verts_idxs[0]].v)/2.); verts_idxs.insert(verts_idxs.begin()+5, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5]); - push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3]); - push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5]); - push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5]); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], normal); + push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], normal); + push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], normal); + push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], normal); } tr = &m_triangles[facet_idx]; // may have been invalidated diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 11387c766c..9d15900704 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -63,8 +63,9 @@ protected: public: // Use TriangleSelector::push_triangle to create a new triangle. // It increments/decrements reference counter on vertices. - Triangle(int a, int b, int c) + Triangle(int a, int b, int c, const Vec3f& normal_) : verts_idxs{a, b, c}, + normal{normal_}, state{EnforcerBlockerType(0)}, number_of_splits{0}, special_side_idx{0}, @@ -73,6 +74,9 @@ protected: // Indices into m_vertices. std::array verts_idxs; + // Triangle normal (a shader might need it). + Vec3f normal; + // Is this triangle valid or marked to be removed? bool valid{true}; @@ -158,7 +162,7 @@ protected: void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant. bool is_pointer_in_triangle(int facet_idx) const; bool is_edge_inside_cursor(int facet_idx) const; - void push_triangle(int a, int b, int c); + void push_triangle(int a, int b, int c, const Vec3f& normal); void perform_split(int facet_idx, EnforcerBlockerType old_state); }; diff --git a/src/libslic3r/VoronoiOffset.cpp b/src/libslic3r/VoronoiOffset.cpp index 7ad0f7af4b..2108388f50 100644 --- a/src/libslic3r/VoronoiOffset.cpp +++ b/src/libslic3r/VoronoiOffset.cpp @@ -666,19 +666,21 @@ void annotate_inside_outside(VD &vd, const Lines &lines) // Set a VertexCategory, verify validity of the operation. auto annotate_vertex = [](const VD::vertex_type *vertex, VertexCategory new_vertex_category) { +#ifndef NDEBUG VertexCategory vc = vertex_category(vertex); assert(vc == VertexCategory::Unknown || vc == new_vertex_category); assert(new_vertex_category == VertexCategory::Inside || new_vertex_category == VertexCategory::Outside || new_vertex_category == VertexCategory::OnContour); +#endif // NDEBUG set_vertex_category(const_cast(vertex), new_vertex_category); }; // Set an EdgeCategory, verify validity of the operation. auto annotate_edge = [](const VD::edge_type *edge, EdgeCategory new_edge_category) { +#ifndef NDEBUG EdgeCategory ec = edge_category(edge); assert(ec == EdgeCategory::Unknown || ec == new_edge_category); -#ifndef NDEBUG switch (new_edge_category) { case EdgeCategory::PointsInside: assert(edge->vertex0() != nullptr); @@ -693,7 +695,6 @@ void annotate_inside_outside(VD &vd, const Lines &lines) default: assert(false); } - #endif // NDEBUG set_edge_category(const_cast(edge), new_edge_category); }; @@ -760,10 +761,12 @@ void annotate_inside_outside(VD &vd, const Lines &lines) // Only one of the two vertices may lie on input contour. const VD::vertex_type *v0 = edge.vertex0(); const VD::vertex_type *v1 = edge.vertex1(); +#ifndef NDEBUG VertexCategory v0_category = vertex_category(v0); VertexCategory v1_category = vertex_category(v1); assert(v0_category != VertexCategory::OnContour || v1_category != VertexCategory::OnContour); assert(! (on_contour(v0) && on_contour(v1))); +#endif // NDEBUG if (on_contour(v0)) annotate_vertex(v0, VertexCategory::OnContour); else { diff --git a/src/libslic3r/pchheader.hpp b/src/libslic3r/pchheader.hpp index a1d6da5fe3..9386fdf369 100644 --- a/src/libslic3r/pchheader.hpp +++ b/src/libslic3r/pchheader.hpp @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include @@ -88,8 +88,15 @@ #include #include #include + +// boost/property_tree/json_parser/detail/parser.hpp includes boost/bind.hpp, which is deprecated. +// Suppress the following boost message: +// The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. +#define BOOST_BIND_GLOBAL_PLACEHOLDERS #include #include +#undef BOOST_BIND_GLOBAL_PLACEHOLDERS + #include #include diff --git a/src/poly2tri/CMakeLists.txt b/src/poly2tri/CMakeLists.txt deleted file mode 100644 index 3cdff1221d..0000000000 --- a/src/poly2tri/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -project(poly2tri) -cmake_minimum_required(VERSION 2.6) - -add_library(poly2tri STATIC - common/shapes.cc - common/shapes.h - common/utils.h - poly2tri.h - sweep/advancing_front.cc - sweep/advancing_front.h - sweep/cdt.cc - sweep/cdt.h - sweep/sweep.cc - sweep/sweep.h - sweep/sweep_context.cc - sweep/sweep_context.h -) diff --git a/src/poly2tri/common/shapes.cc b/src/poly2tri/common/shapes.cc deleted file mode 100644 index fe99a8d1a1..0000000000 --- a/src/poly2tri/common/shapes.cc +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "shapes.h" - -#include -#include - -namespace p2t { - -std::ostream& operator<<(std::ostream& out, const Point& point) { - return out << point.x << "," << point.y; -} - -Triangle::Triangle(Point& a, Point& b, Point& c) -{ - points_[0] = &a; points_[1] = &b; points_[2] = &c; - neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL; - constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false; - delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; - interior_ = false; -} - -// Update neighbor pointers -void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t) -{ - if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2])) - neighbors_[0] = t; - else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0])) - neighbors_[1] = t; - else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0])) - neighbors_[2] = t; - else - assert(0); -} - -// Exhaustive search to update neighbor pointers -void Triangle::MarkNeighbor(Triangle& t) -{ - if (t.Contains(points_[1], points_[2])) { - neighbors_[0] = &t; - t.MarkNeighbor(points_[1], points_[2], this); - } else if (t.Contains(points_[0], points_[2])) { - neighbors_[1] = &t; - t.MarkNeighbor(points_[0], points_[2], this); - } else if (t.Contains(points_[0], points_[1])) { - neighbors_[2] = &t; - t.MarkNeighbor(points_[0], points_[1], this); - } -} - -/** - * Clears all references to all other triangles and points - */ -void Triangle::Clear() -{ - Triangle *t; - for( int i=0; i<3; i++ ) - { - t = neighbors_[i]; - if( t != NULL ) - { - t->ClearNeighbor( this ); - } - } - ClearNeighbors(); - points_[0]=points_[1]=points_[2] = NULL; -} - -void Triangle::ClearNeighbor(const Triangle *triangle ) -{ - if( neighbors_[0] == triangle ) - { - neighbors_[0] = NULL; - } - else if( neighbors_[1] == triangle ) - { - neighbors_[1] = NULL; - } - else - { - neighbors_[2] = NULL; - } -} - -void Triangle::ClearNeighbors() -{ - neighbors_[0] = NULL; - neighbors_[1] = NULL; - neighbors_[2] = NULL; -} - -void Triangle::ClearDelunayEdges() -{ - delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; -} - -Point* Triangle::OppositePoint(Triangle& t, const Point& p) -{ - Point *cw = t.PointCW(p); - return PointCW(*cw); -} - -// Legalized triangle by rotating clockwise around point(0) -void Triangle::Legalize(Point& point) -{ - points_[1] = points_[0]; - points_[0] = points_[2]; - points_[2] = &point; -} - -// Legalize triagnle by rotating clockwise around oPoint -void Triangle::Legalize(Point& opoint, Point& npoint) -{ - if (&opoint == points_[0]) { - points_[1] = points_[0]; - points_[0] = points_[2]; - points_[2] = &npoint; - } else if (&opoint == points_[1]) { - points_[2] = points_[1]; - points_[1] = points_[0]; - points_[0] = &npoint; - } else if (&opoint == points_[2]) { - points_[0] = points_[2]; - points_[2] = points_[1]; - points_[1] = &npoint; - } else { - assert(0); - } -} - -int Triangle::Index(const Point* p) -{ - if (p == points_[0]) { - return 0; - } else if (p == points_[1]) { - return 1; - } else if (p == points_[2]) { - return 2; - } - assert(0); - return -1; -} - -int Triangle::EdgeIndex(const Point* p1, const Point* p2) -{ - if (points_[0] == p1) { - if (points_[1] == p2) { - return 2; - } else if (points_[2] == p2) { - return 1; - } - } else if (points_[1] == p1) { - if (points_[2] == p2) { - return 0; - } else if (points_[0] == p2) { - return 2; - } - } else if (points_[2] == p1) { - if (points_[0] == p2) { - return 1; - } else if (points_[1] == p2) { - return 0; - } - } - return -1; -} - -void Triangle::MarkConstrainedEdge(int index) -{ - constrained_edge[index] = true; -} - -void Triangle::MarkConstrainedEdge(Edge& edge) -{ - MarkConstrainedEdge(edge.p, edge.q); -} - -// Mark edge as constrained -void Triangle::MarkConstrainedEdge(Point* p, Point* q) -{ - if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) { - constrained_edge[2] = true; - } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) { - constrained_edge[1] = true; - } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) { - constrained_edge[0] = true; - } -} - -// The point counter-clockwise to given point -Point* Triangle::PointCW(const Point& point) -{ - if (&point == points_[0]) { - return points_[2]; - } else if (&point == points_[1]) { - return points_[0]; - } else if (&point == points_[2]) { - return points_[1]; - } - assert(0); - return NULL; -} - -// The point counter-clockwise to given point -Point* Triangle::PointCCW(const Point& point) -{ - if (&point == points_[0]) { - return points_[1]; - } else if (&point == points_[1]) { - return points_[2]; - } else if (&point == points_[2]) { - return points_[0]; - } - assert(0); - return NULL; -} - -// The neighbor clockwise to given point -Triangle* Triangle::NeighborCW(const Point& point) -{ - if (&point == points_[0]) { - return neighbors_[1]; - } else if (&point == points_[1]) { - return neighbors_[2]; - } - return neighbors_[0]; -} - -// The neighbor counter-clockwise to given point -Triangle* Triangle::NeighborCCW(const Point& point) -{ - if (&point == points_[0]) { - return neighbors_[2]; - } else if (&point == points_[1]) { - return neighbors_[0]; - } - return neighbors_[1]; -} - -bool Triangle::GetConstrainedEdgeCCW(const Point& p) -{ - if (&p == points_[0]) { - return constrained_edge[2]; - } else if (&p == points_[1]) { - return constrained_edge[0]; - } - return constrained_edge[1]; -} - -bool Triangle::GetConstrainedEdgeCW(const Point& p) -{ - if (&p == points_[0]) { - return constrained_edge[1]; - } else if (&p == points_[1]) { - return constrained_edge[2]; - } - return constrained_edge[0]; -} - -void Triangle::SetConstrainedEdgeCCW(const Point& p, bool ce) -{ - if (&p == points_[0]) { - constrained_edge[2] = ce; - } else if (&p == points_[1]) { - constrained_edge[0] = ce; - } else { - constrained_edge[1] = ce; - } -} - -void Triangle::SetConstrainedEdgeCW(const Point& p, bool ce) -{ - if (&p == points_[0]) { - constrained_edge[1] = ce; - } else if (&p == points_[1]) { - constrained_edge[2] = ce; - } else { - constrained_edge[0] = ce; - } -} - -bool Triangle::GetDelunayEdgeCCW(const Point& p) -{ - if (&p == points_[0]) { - return delaunay_edge[2]; - } else if (&p == points_[1]) { - return delaunay_edge[0]; - } - return delaunay_edge[1]; -} - -bool Triangle::GetDelunayEdgeCW(const Point& p) -{ - if (&p == points_[0]) { - return delaunay_edge[1]; - } else if (&p == points_[1]) { - return delaunay_edge[2]; - } - return delaunay_edge[0]; -} - -void Triangle::SetDelunayEdgeCCW(const Point& p, bool e) -{ - if (&p == points_[0]) { - delaunay_edge[2] = e; - } else if (&p == points_[1]) { - delaunay_edge[0] = e; - } else { - delaunay_edge[1] = e; - } -} - -void Triangle::SetDelunayEdgeCW(const Point& p, bool e) -{ - if (&p == points_[0]) { - delaunay_edge[1] = e; - } else if (&p == points_[1]) { - delaunay_edge[2] = e; - } else { - delaunay_edge[0] = e; - } -} - -// The neighbor across to given point -Triangle& Triangle::NeighborAcross(const Point& opoint) -{ - if (&opoint == points_[0]) { - return *neighbors_[0]; - } else if (&opoint == points_[1]) { - return *neighbors_[1]; - } - return *neighbors_[2]; -} - -void Triangle::DebugPrint() -{ - std::cout << *points_[0] << " " << *points_[1] << " " << *points_[2] << std::endl; -} - -} diff --git a/src/poly2tri/common/shapes.h b/src/poly2tri/common/shapes.h deleted file mode 100644 index 7f0b1e76a8..0000000000 --- a/src/poly2tri/common/shapes.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Include guard -#ifndef SHAPES_H -#define SHAPES_H - -#include -#include -#include -#include - -namespace p2t { - -struct Edge; - -struct Point { - - double x, y; - - /// Default constructor does nothing (for performance). - Point() - { - x = 0.0; - y = 0.0; - } - - /// The edges this point constitutes an upper ending point - std::vector edge_list; - - /// Construct using coordinates. - Point(double x, double y) : x(x), y(y) {} - - /// Set this point to all zeros. - void set_zero() - { - x = 0.0; - y = 0.0; - } - - /// Set this point to some specified coordinates. - void set(double x_, double y_) - { - x = x_; - y = y_; - } - - /// Negate this point. - Point operator -() const - { - Point v; - v.set(-x, -y); - return v; - } - - /// Add a point to this point. - void operator +=(const Point& v) - { - x += v.x; - y += v.y; - } - - /// Subtract a point from this point. - void operator -=(const Point& v) - { - x -= v.x; - y -= v.y; - } - - /// Multiply this point by a scalar. - void operator *=(double a) - { - x *= a; - y *= a; - } - - /// Get the length of this point (the norm). - double Length() const - { - return sqrt(x * x + y * y); - } - - /// Convert this point into a unit point. Returns the Length. - double Normalize() - { - const double len = Length(); - x /= len; - y /= len; - return len; - } - -}; - -std::ostream& operator<<(std::ostream&, const Point&); - -// Represents a simple polygon's edge -struct Edge { - - Point* p, *q; - - /// Constructor - Edge(Point& p1, Point& p2) : p(&p1), q(&p2) - { - if (p1.y > p2.y) { - q = &p1; - p = &p2; - } else if (std::abs(p1.y - p2.y) < 1e-10) { - if (p1.x > p2.x) { - q = &p1; - p = &p2; - } else if (std::abs(p1.x - p2.x) < 1e-10) { - // Repeat points - throw std::runtime_error("Edge::Edge: p1 == p2"); - } - } - - q->edge_list.push_back(this); - } -}; - -// Triangle-based data structures are know to have better performance than quad-edge structures -// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator" -// "Triangulations in CGAL" -class Triangle { -public: - -/// Constructor -Triangle(Point& a, Point& b, Point& c); - -/// Flags to determine if an edge is a Constrained edge -bool constrained_edge[3]; -/// Flags to determine if an edge is a Delauney edge -bool delaunay_edge[3]; - -Point* GetPoint(int index); -Point* PointCW(const Point& point); -Point* PointCCW(const Point& point); -Point* OppositePoint(Triangle& t, const Point& p); - -Triangle* GetNeighbor(int index); -void MarkNeighbor(Point* p1, Point* p2, Triangle* t); -void MarkNeighbor(Triangle& t); - -void MarkConstrainedEdge(int index); -void MarkConstrainedEdge(Edge& edge); -void MarkConstrainedEdge(Point* p, Point* q); - -int Index(const Point* p); -int EdgeIndex(const Point* p1, const Point* p2); - -Triangle* NeighborCW(const Point& point); -Triangle* NeighborCCW(const Point& point); -bool GetConstrainedEdgeCCW(const Point& p); -bool GetConstrainedEdgeCW(const Point& p); -void SetConstrainedEdgeCCW(const Point& p, bool ce); -void SetConstrainedEdgeCW(const Point& p, bool ce); -bool GetDelunayEdgeCCW(const Point& p); -bool GetDelunayEdgeCW(const Point& p); -void SetDelunayEdgeCCW(const Point& p, bool e); -void SetDelunayEdgeCW(const Point& p, bool e); - -bool Contains(const Point* p); -bool Contains(const Edge& e); -bool Contains(const Point* p, const Point* q); -void Legalize(Point& point); -void Legalize(Point& opoint, Point& npoint); -/** - * Clears all references to all other triangles and points - */ -void Clear(); -void ClearNeighbor(const Triangle *triangle); -void ClearNeighbors(); -void ClearDelunayEdges(); - -inline bool IsInterior(); -inline void IsInterior(bool b); - -Triangle& NeighborAcross(const Point& opoint); - -void DebugPrint(); - -private: - -/// Triangle points -Point* points_[3]; -/// Neighbor list -Triangle* neighbors_[3]; - -/// Has this triangle been marked as an interior triangle? -bool interior_; -}; - -inline bool cmp(const Point* a, const Point* b) -{ - if (a->y < b->y) { - return true; - } else if (a->y == b->y) { - // Make sure q is point with greater x value - if (a->x < b->x) { - return true; - } - } - return false; -} - -/// Add two points_ component-wise. -inline Point operator +(const Point& a, const Point& b) -{ - return Point(a.x + b.x, a.y + b.y); -} - -/// Subtract two points_ component-wise. -inline Point operator -(const Point& a, const Point& b) -{ - return Point(a.x - b.x, a.y - b.y); -} - -/// Multiply point by scalar -inline Point operator *(double s, const Point& a) -{ - return Point(s * a.x, s * a.y); -} - -inline bool operator ==(const Point& a, const Point& b) -{ - return a.x == b.x && a.y == b.y; -} - -inline bool operator !=(const Point& a, const Point& b) -{ - return !(a.x == b.x) && !(a.y == b.y); -} - -/// Peform the dot product on two vectors. -inline double Dot(const Point& a, const Point& b) -{ - return a.x * b.x + a.y * b.y; -} - -/// Perform the cross product on two vectors. In 2D this produces a scalar. -inline double Cross(const Point& a, const Point& b) -{ - return a.x * b.y - a.y * b.x; -} - -/// Perform the cross product on a point and a scalar. In 2D this produces -/// a point. -inline Point Cross(const Point& a, double s) -{ - return Point(s * a.y, -s * a.x); -} - -/// Perform the cross product on a scalar and a point. In 2D this produces -/// a point. -inline Point Cross(double s, const Point& a) -{ - return Point(-s * a.y, s * a.x); -} - -inline Point* Triangle::GetPoint(int index) -{ - return points_[index]; -} - -inline Triangle* Triangle::GetNeighbor(int index) -{ - return neighbors_[index]; -} - -inline bool Triangle::Contains(const Point* p) -{ - return p == points_[0] || p == points_[1] || p == points_[2]; -} - -inline bool Triangle::Contains(const Edge& e) -{ - return Contains(e.p) && Contains(e.q); -} - -inline bool Triangle::Contains(const Point* p, const Point* q) -{ - return Contains(p) && Contains(q); -} - -inline bool Triangle::IsInterior() -{ - return interior_; -} - -inline void Triangle::IsInterior(bool b) -{ - interior_ = b; -} - -} - -#endif diff --git a/src/poly2tri/common/utils.h b/src/poly2tri/common/utils.h deleted file mode 100644 index 9a9e14a8a9..0000000000 --- a/src/poly2tri/common/utils.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef UTILS_H -#define UTILS_H - -// Otherwise #defines like M_PI are undeclared under Visual Studio -#ifndef _USE_MATH_DEFINES - #define _USE_MATH_DEFINES -#endif /* _USE_MATH_DEFINES */ - -#include "shapes.h" - -#include -#include - -// C99 removes M_PI from math.h -#ifndef M_PI -#define M_PI 3.14159265358979323846264338327 -#endif - -namespace p2t { - -const double PI_3div4 = 3 * M_PI / 4; -const double PI_div2 = 1.57079632679489661923; -const double EPSILON = 1e-12; - -enum Orientation { CW, CCW, COLLINEAR }; - -/** - * Forumla to calculate signed area
- * Positive if CCW
- * Negative if CW
- * 0 if collinear
- *
- * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
- *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
- * 
- */ -Orientation Orient2d(const Point& pa, const Point& pb, const Point& pc) -{ - double detleft = (pa.x - pc.x) * (pb.y - pc.y); - double detright = (pa.y - pc.y) * (pb.x - pc.x); - double val = detleft - detright; - if (val > -EPSILON && val < EPSILON) { - return COLLINEAR; - } else if (val > 0) { - return CCW; - } - return CW; -} - -/* -bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd) -{ - double pdx = pd.x; - double pdy = pd.y; - double adx = pa.x - pdx; - double ady = pa.y - pdy; - double bdx = pb.x - pdx; - double bdy = pb.y - pdy; - - double adxbdy = adx * bdy; - double bdxady = bdx * ady; - double oabd = adxbdy - bdxady; - - if (oabd <= EPSILON) { - return false; - } - - double cdx = pc.x - pdx; - double cdy = pc.y - pdy; - - double cdxady = cdx * ady; - double adxcdy = adx * cdy; - double ocad = cdxady - adxcdy; - - if (ocad <= EPSILON) { - return false; - } - - return true; -} - -*/ - -bool InScanArea(const Point& pa, const Point& pb, const Point& pc, const Point& pd) -{ - double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y); - if (oadb >= -EPSILON) { - return false; - } - - double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y); - if (oadc <= EPSILON) { - return false; - } - return true; -} - -} - -#endif diff --git a/src/poly2tri/poly2tri.h b/src/poly2tri/poly2tri.h deleted file mode 100644 index c959d131f9..0000000000 --- a/src/poly2tri/poly2tri.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef POLY2TRI_H -#define POLY2TRI_H - -#include "common/shapes.h" -#include "sweep/cdt.h" - -#endif diff --git a/src/poly2tri/sweep/advancing_front.cc b/src/poly2tri/sweep/advancing_front.cc deleted file mode 100644 index 66e2a5d0d3..0000000000 --- a/src/poly2tri/sweep/advancing_front.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "advancing_front.h" - -#include - -namespace p2t { - -AdvancingFront::AdvancingFront(Node& head, Node& tail) -{ - head_ = &head; - tail_ = &tail; - search_node_ = &head; -} - -Node* AdvancingFront::LocateNode(double x) -{ - Node* node = search_node_; - - if (x < node->value) { - while ((node = node->prev) != NULL) { - if (x >= node->value) { - search_node_ = node; - return node; - } - } - } else { - while ((node = node->next) != NULL) { - if (x < node->value) { - search_node_ = node->prev; - return node->prev; - } - } - } - return NULL; -} - -Node* AdvancingFront::FindSearchNode(double x) -{ - (void)x; // suppress compiler warnings "unused parameter 'x'" - // TODO: implement BST index - return search_node_; -} - -Node* AdvancingFront::LocatePoint(const Point* point) -{ - const double px = point->x; - Node* node = FindSearchNode(px); - const double nx = node->point->x; - - if (px == nx) { - if (point != node->point) { - // We might have two nodes with same x value for a short time - if (point == node->prev->point) { - node = node->prev; - } else if (point == node->next->point) { - node = node->next; - } else { - assert(0); - } - } - } else if (px < nx) { - while ((node = node->prev) != NULL) { - if (point == node->point) { - break; - } - } - } else { - while ((node = node->next) != NULL) { - if (point == node->point) - break; - } - } - if(node) search_node_ = node; - return node; -} - -AdvancingFront::~AdvancingFront() -{ -} - -} diff --git a/src/poly2tri/sweep/advancing_front.h b/src/poly2tri/sweep/advancing_front.h deleted file mode 100644 index 3de0708243..0000000000 --- a/src/poly2tri/sweep/advancing_front.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ADVANCED_FRONT_H -#define ADVANCED_FRONT_H - -#include "../common/shapes.h" - -namespace p2t { - -struct Node; - -// Advancing front node -struct Node { - Point* point; - Triangle* triangle; - - Node* next; - Node* prev; - - double value; - - Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), value(p.x) - { - } - - Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), prev(NULL), value(p.x) - { - } - -}; - -// Advancing front -class AdvancingFront { -public: - -AdvancingFront(Node& head, Node& tail); -// Destructor -~AdvancingFront(); - -Node* head(); -void set_head(Node* node); -Node* tail(); -void set_tail(Node* node); -Node* search(); -void set_search(Node* node); - -/// Locate insertion point along advancing front -Node* LocateNode(double x); - -Node* LocatePoint(const Point* point); - -private: - -Node* head_, *tail_, *search_node_; - -Node* FindSearchNode(double x); -}; - -inline Node* AdvancingFront::head() -{ - return head_; -} -inline void AdvancingFront::set_head(Node* node) -{ - head_ = node; -} - -inline Node* AdvancingFront::tail() -{ - return tail_; -} -inline void AdvancingFront::set_tail(Node* node) -{ - tail_ = node; -} - -inline Node* AdvancingFront::search() -{ - return search_node_; -} - -inline void AdvancingFront::set_search(Node* node) -{ - search_node_ = node; -} - -} - -#endif diff --git a/src/poly2tri/sweep/cdt.cc b/src/poly2tri/sweep/cdt.cc deleted file mode 100644 index 8496aa1da4..0000000000 --- a/src/poly2tri/sweep/cdt.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "cdt.h" - -namespace p2t { - -CDT::CDT(const std::vector& polyline) -{ - sweep_context_ = new SweepContext(polyline); - sweep_ = new Sweep; -} - -void CDT::AddHole(const std::vector& polyline) -{ - sweep_context_->AddHole(polyline); -} - -void CDT::AddPoint(Point* point) { - sweep_context_->AddPoint(point); -} - -void CDT::Triangulate() -{ - sweep_->Triangulate(*sweep_context_); -} - -std::vector CDT::GetTriangles() -{ - return sweep_context_->GetTriangles(); -} - -std::list CDT::GetMap() -{ - return sweep_context_->GetMap(); -} - -CDT::~CDT() -{ - delete sweep_context_; - delete sweep_; -} - -} diff --git a/src/poly2tri/sweep/cdt.h b/src/poly2tri/sweep/cdt.h deleted file mode 100644 index efeeda3889..0000000000 --- a/src/poly2tri/sweep/cdt.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CDT_H -#define CDT_H - -#include "advancing_front.h" -#include "sweep_context.h" -#include "sweep.h" - -/** - * - * @author Mason Green - * - */ - -namespace p2t { - -class CDT -{ -public: - - /** - * Constructor - add polyline with non repeating points - * - * @param polyline - */ - CDT(const std::vector& polyline); - - /** - * Destructor - clean up memory - */ - ~CDT(); - - /** - * Add a hole - * - * @param polyline - */ - void AddHole(const std::vector& polyline); - - /** - * Add a steiner point - * - * @param point - */ - void AddPoint(Point* point); - - /** - * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points - */ - void Triangulate(); - - /** - * Get CDT triangles - */ - std::vector GetTriangles(); - - /** - * Get triangle map - */ - std::list GetMap(); - - private: - - /** - * Internals - */ - - SweepContext* sweep_context_; - Sweep* sweep_; - -}; - -} - -#endif diff --git a/src/poly2tri/sweep/sweep.cc b/src/poly2tri/sweep/sweep.cc deleted file mode 100644 index 45aa1db3b6..0000000000 --- a/src/poly2tri/sweep/sweep.cc +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "sweep.h" -#include "sweep_context.h" -#include "advancing_front.h" -#include "../common/utils.h" - -#include -#include - -namespace p2t { - -// Triangulate simple polygon with holes -void Sweep::Triangulate(SweepContext& tcx) -{ - tcx.InitTriangulation(); - tcx.CreateAdvancingFront(); - // Sweep points; build mesh - SweepPoints(tcx); - // Clean up - FinalizationPolygon(tcx); -} - -void Sweep::SweepPoints(SweepContext& tcx) -{ - for (size_t i = 1; i < tcx.point_count(); i++) { - Point& point = *tcx.GetPoint(i); - Node* node = &PointEvent(tcx, point); - for (unsigned int i = 0; i < point.edge_list.size(); i++) { - EdgeEvent(tcx, point.edge_list[i], node); - } - } -} - -void Sweep::FinalizationPolygon(SweepContext& tcx) -{ - // Get an Internal triangle to start with - Triangle* t = tcx.front()->head()->next->triangle; - Point* p = tcx.front()->head()->next->point; - while (!t->GetConstrainedEdgeCW(*p)) { - t = t->NeighborCCW(*p); - } - - // Collect interior triangles constrained by edges - tcx.MeshClean(*t); -} - -Node& Sweep::PointEvent(SweepContext& tcx, Point& point) -{ - Node& node = tcx.LocateNode(point); - Node& new_node = NewFrontTriangle(tcx, point, node); - - // Only need to check +epsilon since point never have smaller - // x value than node due to how we fetch nodes from the front - if (point.x <= node.point->x + EPSILON) { - Fill(tcx, node); - } - - //tcx.AddNode(new_node); - - FillAdvancingFront(tcx, new_node); - return new_node; -} - -void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node) -{ - tcx.edge_event.constrained_edge = edge; - tcx.edge_event.right = (edge->p->x > edge->q->x); - - if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) { - return; - } - - // For now we will do all needed filling - // TODO: integrate with flip process might give some better performance - // but for now this avoid the issue with cases that needs both flips and fills - FillEdgeEvent(tcx, edge, node); - EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q); -} - -void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point) -{ - if (IsEdgeSideOfTriangle(*triangle, ep, eq)) { - return; - } - - Point* p1 = triangle->PointCCW(point); - Orientation o1 = Orient2d(eq, *p1, ep); - if (o1 == COLLINEAR) { - if( triangle->Contains(&eq, p1)) { - triangle->MarkConstrainedEdge(&eq, p1 ); - // We are modifying the constraint maybe it would be better to - // not change the given constraint and just keep a variable for the new constraint - tcx.edge_event.constrained_edge->q = p1; - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p1, triangle, *p1 ); - } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - assert(0); - } - return; - } - - Point* p2 = triangle->PointCW(point); - Orientation o2 = Orient2d(eq, *p2, ep); - if (o2 == COLLINEAR) { - if( triangle->Contains(&eq, p2)) { - triangle->MarkConstrainedEdge(&eq, p2 ); - // We are modifying the constraint maybe it would be better to - // not change the given constraint and just keep a variable for the new constraint - tcx.edge_event.constrained_edge->q = p2; - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p2, triangle, *p2 ); - } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - assert(0); - } - return; - } - - if (o1 == o2) { - // Need to decide if we are rotating CW or CCW to get to a triangle - // that will cross edge - if (o1 == CW) { - triangle = triangle->NeighborCCW(point); - } else{ - triangle = triangle->NeighborCW(point); - } - EdgeEvent(tcx, ep, eq, triangle, point); - } else { - // This triangle crosses constraint so lets flippin start! - FlipEdgeEvent(tcx, ep, eq, triangle, point); - } -} - -bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq) -{ - const int index = triangle.EdgeIndex(&ep, &eq); - - if (index != -1) { - triangle.MarkConstrainedEdge(index); - Triangle* t = triangle.GetNeighbor(index); - if (t) { - t->MarkConstrainedEdge(&ep, &eq); - } - return true; - } - return false; -} - -Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node) -{ - Triangle* triangle = new Triangle(point, *node.point, *node.next->point); - - triangle->MarkNeighbor(*node.triangle); - tcx.AddToMap(triangle); - - Node* new_node = new Node(point); - nodes_.push_back(new_node); - - new_node->next = node.next; - new_node->prev = &node; - node.next->prev = new_node; - node.next = new_node; - - if (!Legalize(tcx, *triangle)) { - tcx.MapTriangleToNodes(*triangle); - } - - return *new_node; -} - -void Sweep::Fill(SweepContext& tcx, Node& node) -{ - Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point); - - // TODO: should copy the constrained_edge value from neighbor triangles - // for now constrained_edge values are copied during the legalize - triangle->MarkNeighbor(*node.prev->triangle); - triangle->MarkNeighbor(*node.triangle); - - tcx.AddToMap(triangle); - - // Update the advancing front - node.prev->next = node.next; - node.next->prev = node.prev; - - // If it was legalized the triangle has already been mapped - if (!Legalize(tcx, *triangle)) { - tcx.MapTriangleToNodes(*triangle); - } - -} - -void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) -{ - - // Fill right holes - Node* node = n.next; - - while (node->next) { - // if HoleAngle exceeds 90 degrees then break. - if (LargeHole_DontFill(node)) break; - Fill(tcx, *node); - node = node->next; - } - - // Fill left holes - node = n.prev; - - while (node->prev) { - // if HoleAngle exceeds 90 degrees then break. - if (LargeHole_DontFill(node)) break; - Fill(tcx, *node); - node = node->prev; - } - - // Fill right basins - if (n.next && n.next->next) { - const double angle = BasinAngle(n); - if (angle < PI_3div4) { - FillBasin(tcx, n); - } - } -} - -// True if HoleAngle exceeds 90 degrees. -bool Sweep::LargeHole_DontFill(const Node* node) const { - - const Node* nextNode = node->next; - const Node* prevNode = node->prev; - if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point)) - return false; - - // Check additional points on front. - const Node* next2Node = nextNode->next; - // "..Plus.." because only want angles on same side as point being added. - if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point)) - return false; - - const Node* prev2Node = prevNode->prev; - // "..Plus.." because only want angles on same side as point being added. - if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point)) - return false; - - return true; -} - -bool Sweep::AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const { - const double angle = Angle(origin, pa, pb); - return ((angle > PI_div2) || (angle < -PI_div2)); -} - -bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const { - const double angle = Angle(origin, pa, pb); - return (angle > PI_div2) || (angle < 0); -} - -double Sweep::Angle(const Point* origin, const Point* pa, const Point* pb) const { - /* Complex plane - * ab = cosA +i*sinA - * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx) - * atan2(y,x) computes the principal value of the argument function - * applied to the complex number x+iy - * Where x = ax*bx + ay*by - * y = ax*by - ay*bx - */ - const double px = origin->x; - const double py = origin->y; - const double ax = pa->x- px; - const double ay = pa->y - py; - const double bx = pb->x - px; - const double by = pb->y - py; - const double x = ax * by - ay * bx; - const double y = ax * bx + ay * by; - return atan2(x, y); -} - -double Sweep::BasinAngle(const Node& node) const -{ - const double ax = node.point->x - node.next->next->point->x; - const double ay = node.point->y - node.next->next->point->y; - return atan2(ay, ax); -} - -double Sweep::HoleAngle(const Node& node) const -{ - /* Complex plane - * ab = cosA +i*sinA - * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx) - * atan2(y,x) computes the principal value of the argument function - * applied to the complex number x+iy - * Where x = ax*bx + ay*by - * y = ax*by - ay*bx - */ - const double ax = node.next->point->x - node.point->x; - const double ay = node.next->point->y - node.point->y; - const double bx = node.prev->point->x - node.point->x; - const double by = node.prev->point->y - node.point->y; - return atan2(ax * by - ay * bx, ax * bx + ay * by); -} - -bool Sweep::Legalize(SweepContext& tcx, Triangle& t) -{ - // To legalize a triangle we start by finding if any of the three edges - // violate the Delaunay condition - for (int i = 0; i < 3; i++) { - if (t.delaunay_edge[i]) - continue; - - Triangle* ot = t.GetNeighbor(i); - - if (ot) { - Point* p = t.GetPoint(i); - Point* op = ot->OppositePoint(t, *p); - int oi = ot->Index(op); - - // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization) - // then we should not try to legalize - if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) { - t.constrained_edge[i] = ot->constrained_edge[oi]; - continue; - } - - bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op); - - if (inside) { - // Lets mark this shared edge as Delaunay - t.delaunay_edge[i] = true; - ot->delaunay_edge[oi] = true; - - // Lets rotate shared edge one vertex CW to legalize it - RotateTrianglePair(t, *p, *ot, *op); - - // We now got one valid Delaunay Edge shared by two triangles - // This gives us 4 new edges to check for Delaunay - - // Make sure that triangle to node mapping is done only one time for a specific triangle - bool not_legalized = !Legalize(tcx, t); - if (not_legalized) { - tcx.MapTriangleToNodes(t); - } - - not_legalized = !Legalize(tcx, *ot); - if (not_legalized) - tcx.MapTriangleToNodes(*ot); - - // Reset the Delaunay edges, since they only are valid Delaunay edges - // until we add a new triangle or point. - // XXX: need to think about this. Can these edges be tried after we - // return to previous recursive level? - t.delaunay_edge[i] = false; - ot->delaunay_edge[oi] = false; - - // If triangle have been legalized no need to check the other edges since - // the recursive legalization will handles those so we can end here. - return true; - } - } - } - return false; -} - -bool Sweep::Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const -{ - const double adx = pa.x - pd.x; - const double ady = pa.y - pd.y; - const double bdx = pb.x - pd.x; - const double bdy = pb.y - pd.y; - - const double adxbdy = adx * bdy; - const double bdxady = bdx * ady; - const double oabd = adxbdy - bdxady; - - if (oabd <= 0) - return false; - - const double cdx = pc.x - pd.x; - const double cdy = pc.y - pd.y; - - const double cdxady = cdx * ady; - const double adxcdy = adx * cdy; - const double ocad = cdxady - adxcdy; - - if (ocad <= 0) - return false; - - const double bdxcdy = bdx * cdy; - const double cdxbdy = cdx * bdy; - - const double alift = adx * adx + ady * ady; - const double blift = bdx * bdx + bdy * bdy; - const double clift = cdx * cdx + cdy * cdy; - - const double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd; - - return det > 0; -} - -void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const -{ - Triangle* n1, *n2, *n3, *n4; - n1 = t.NeighborCCW(p); - n2 = t.NeighborCW(p); - n3 = ot.NeighborCCW(op); - n4 = ot.NeighborCW(op); - - bool ce1, ce2, ce3, ce4; - ce1 = t.GetConstrainedEdgeCCW(p); - ce2 = t.GetConstrainedEdgeCW(p); - ce3 = ot.GetConstrainedEdgeCCW(op); - ce4 = ot.GetConstrainedEdgeCW(op); - - bool de1, de2, de3, de4; - de1 = t.GetDelunayEdgeCCW(p); - de2 = t.GetDelunayEdgeCW(p); - de3 = ot.GetDelunayEdgeCCW(op); - de4 = ot.GetDelunayEdgeCW(op); - - t.Legalize(p, op); - ot.Legalize(op, p); - - // Remap delaunay_edge - ot.SetDelunayEdgeCCW(p, de1); - t.SetDelunayEdgeCW(p, de2); - t.SetDelunayEdgeCCW(op, de3); - ot.SetDelunayEdgeCW(op, de4); - - // Remap constrained_edge - ot.SetConstrainedEdgeCCW(p, ce1); - t.SetConstrainedEdgeCW(p, ce2); - t.SetConstrainedEdgeCCW(op, ce3); - ot.SetConstrainedEdgeCW(op, ce4); - - // Remap neighbors - // XXX: might optimize the markNeighbor by keeping track of - // what side should be assigned to what neighbor after the - // rotation. Now mark neighbor does lots of testing to find - // the right side. - t.ClearNeighbors(); - ot.ClearNeighbors(); - if (n1) ot.MarkNeighbor(*n1); - if (n2) t.MarkNeighbor(*n2); - if (n3) t.MarkNeighbor(*n3); - if (n4) ot.MarkNeighbor(*n4); - t.MarkNeighbor(ot); -} - -void Sweep::FillBasin(SweepContext& tcx, Node& node) -{ - if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { - tcx.basin.left_node = node.next->next; - } else { - tcx.basin.left_node = node.next; - } - - // Find the bottom and right node - tcx.basin.bottom_node = tcx.basin.left_node; - while (tcx.basin.bottom_node->next - && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) { - tcx.basin.bottom_node = tcx.basin.bottom_node->next; - } - if (tcx.basin.bottom_node == tcx.basin.left_node) { - // No valid basin - return; - } - - tcx.basin.right_node = tcx.basin.bottom_node; - while (tcx.basin.right_node->next - && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) { - tcx.basin.right_node = tcx.basin.right_node->next; - } - if (tcx.basin.right_node == tcx.basin.bottom_node) { - // No valid basins - return; - } - - tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x; - tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y; - - FillBasinReq(tcx, tcx.basin.bottom_node); -} - -void Sweep::FillBasinReq(SweepContext& tcx, Node* node) -{ - // if shallow stop filling - if (IsShallow(tcx, *node)) { - return; - } - - Fill(tcx, *node); - - if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) { - return; - } else if (node->prev == tcx.basin.left_node) { - Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point); - if (o == CW) { - return; - } - node = node->next; - } else if (node->next == tcx.basin.right_node) { - Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point); - if (o == CCW) { - return; - } - node = node->prev; - } else { - // Continue with the neighbor node with lowest Y value - if (node->prev->point->y < node->next->point->y) { - node = node->prev; - } else { - node = node->next; - } - } - - FillBasinReq(tcx, node); -} - -bool Sweep::IsShallow(SweepContext& tcx, Node& node) -{ - double height; - - if (tcx.basin.left_highest) { - height = tcx.basin.left_node->point->y - node.point->y; - } else { - height = tcx.basin.right_node->point->y - node.point->y; - } - - // if shallow stop filling - if (tcx.basin.width > height) { - return true; - } - return false; -} - -void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) -{ - if (tcx.edge_event.right) { - FillRightAboveEdgeEvent(tcx, edge, node); - } else { - FillLeftAboveEdgeEvent(tcx, edge, node); - } -} - -void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) -{ - while (node->next->point->x < edge->p->x) { - // Check if next node is below the edge - if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) { - FillRightBelowEdgeEvent(tcx, edge, *node); - } else { - node = node->next; - } - } -} - -void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - if (node.point->x < edge->p->x) { - if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { - // Concave - FillRightConcaveEdgeEvent(tcx, edge, node); - } else{ - // Convex - FillRightConvexEdgeEvent(tcx, edge, node); - // Retry this one - FillRightBelowEdgeEvent(tcx, edge, node); - } - } -} - -void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - Fill(tcx, *node.next); - if (node.next->point != edge->p) { - // Next above or below edge? - if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) { - // Below - if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { - // Next is concave - FillRightConcaveEdgeEvent(tcx, edge, node); - } else { - // Next is convex - } - } - } - -} - -void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - // Next concave or convex? - if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) { - // Concave - FillRightConcaveEdgeEvent(tcx, edge, *node.next); - } else{ - // Convex - // Next above or below edge? - if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) { - // Below - FillRightConvexEdgeEvent(tcx, edge, *node.next); - } else{ - // Above - } - } -} - -void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) -{ - while (node->prev->point->x > edge->p->x) { - // Check if next node is below the edge - if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) { - FillLeftBelowEdgeEvent(tcx, edge, *node); - } else { - node = node->prev; - } - } -} - -void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - if (node.point->x > edge->p->x) { - if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { - // Concave - FillLeftConcaveEdgeEvent(tcx, edge, node); - } else { - // Convex - FillLeftConvexEdgeEvent(tcx, edge, node); - // Retry this one - FillLeftBelowEdgeEvent(tcx, edge, node); - } - } -} - -void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - // Next concave or convex? - if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) { - // Concave - FillLeftConcaveEdgeEvent(tcx, edge, *node.prev); - } else{ - // Convex - // Next above or below edge? - if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) { - // Below - FillLeftConvexEdgeEvent(tcx, edge, *node.prev); - } else{ - // Above - } - } -} - -void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) -{ - Fill(tcx, *node.prev); - if (node.prev->point != edge->p) { - // Next above or below edge? - if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) { - // Below - if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { - // Next is concave - FillLeftConcaveEdgeEvent(tcx, edge, node); - } else{ - // Next is convex - } - } - } - -} - -void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p) -{ - Triangle& ot = t->NeighborAcross(p); - Point& op = *ot.OppositePoint(*t, p); - - if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) { - // Lets rotate shared edge one vertex CW - RotateTrianglePair(*t, p, ot, op); - tcx.MapTriangleToNodes(*t); - tcx.MapTriangleToNodes(ot); - - if (p == eq && op == ep) { - if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) { - t->MarkConstrainedEdge(&ep, &eq); - ot.MarkConstrainedEdge(&ep, &eq); - Legalize(tcx, *t); - Legalize(tcx, ot); - } else { - // XXX: I think one of the triangles should be legalized here? - } - } else { - Orientation o = Orient2d(eq, op, ep); - t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op); - FlipEdgeEvent(tcx, ep, eq, t, p); - } - } else { - Point& newP = NextFlipPoint(ep, eq, ot, op); - FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP); - EdgeEvent(tcx, ep, eq, t, p); - } -} - -Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op) -{ - if (o == CCW) { - // ot is not crossing edge after flip - int edge_index = ot.EdgeIndex(&p, &op); - ot.delaunay_edge[edge_index] = true; - Legalize(tcx, ot); - ot.ClearDelunayEdges(); - return t; - } - - // t is not crossing edge after flip - int edge_index = t.EdgeIndex(&p, &op); - - t.delaunay_edge[edge_index] = true; - Legalize(tcx, t); - t.ClearDelunayEdges(); - return ot; -} - -Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op) -{ - Orientation o2d = Orient2d(eq, op, ep); - if (o2d == CW) { - // Right - return *ot.PointCCW(op); - } else if (o2d == CCW) { - // Left - return *ot.PointCW(op); - } - throw std::runtime_error("[Unsupported] Opposing point on constrained edge"); -} - -void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, - Triangle& t, Point& p) -{ - Triangle& ot = t.NeighborAcross(p); - Point& op = *ot.OppositePoint(t, p); - - if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) { - // flip with new edge op->eq - FlipEdgeEvent(tcx, eq, op, &ot, op); - // TODO: Actually I just figured out that it should be possible to - // improve this by getting the next ot and op before the the above - // flip and continue the flipScanEdgeEvent here - // set new ot and op here and loop back to inScanArea test - // also need to set a new flip_triangle first - // Turns out at first glance that this is somewhat complicated - // so it will have to wait. - } else{ - Point& newP = NextFlipPoint(ep, eq, ot, op); - FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP); - } -} - -Sweep::~Sweep() { - - // Clean up memory - for(size_t i = 0; i < nodes_.size(); i++) { - delete nodes_[i]; - } - -} - -} - diff --git a/src/poly2tri/sweep/sweep.h b/src/poly2tri/sweep/sweep.h deleted file mode 100644 index ccf4ef7b02..0000000000 --- a/src/poly2tri/sweep/sweep.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and - * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation', - * International Journal of Geographical Information Science - * - * "FlipScan" Constrained Edge Algorithm invented by Thomas ?hl?n, thahlen@gmail.com - */ - -#ifndef SWEEP_H -#define SWEEP_H - -#include - -namespace p2t { - -class SweepContext; -struct Node; -struct Point; -struct Edge; -class Triangle; - -class Sweep -{ -public: - - /** - * Triangulate - * - * @param tcx - */ - void Triangulate(SweepContext& tcx); - - /** - * Destructor - clean up memory - */ - ~Sweep(); - -private: - - /** - * Start sweeping the Y-sorted point set from bottom to top - * - * @param tcx - */ - void SweepPoints(SweepContext& tcx); - - /** - * Find closes node to the left of the new point and - * create a new triangle. If needed new holes and basins - * will be filled to. - * - * @param tcx - * @param point - * @return - */ - Node& PointEvent(SweepContext& tcx, Point& point); - - /** - * - * - * @param tcx - * @param edge - * @param node - */ - void EdgeEvent(SweepContext& tcx, Edge* edge, Node* node); - - void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point); - - /** - * Creates a new front triangle and legalize it - * - * @param tcx - * @param point - * @param node - * @return - */ - Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node); - - /** - * Adds a triangle to the advancing front to fill a hole. - * @param tcx - * @param node - middle node, that is the bottom of the hole - */ - void Fill(SweepContext& tcx, Node& node); - - /** - * Returns true if triangle was legalized - */ - bool Legalize(SweepContext& tcx, Triangle& t); - - /** - * Requirement:
- * 1. a,b and c form a triangle.
- * 2. a and d is know to be on opposite side of bc
- *
-   *                a
-   *                +
-   *               / \
-   *              /   \
-   *            b/     \c
-   *            +-------+
-   *           /    d    \
-   *          /           \
-   * 
- * Fact: d has to be in area B to have a chance to be inside the circle formed by - * a,b and c
- * d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW
- * This preknowledge gives us a way to optimize the incircle test - * @param a - triangle point, opposite d - * @param b - triangle point - * @param c - triangle point - * @param d - point opposite a - * @return true if d is inside circle, false if on circle edge - */ - bool Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const; - - /** - * Rotates a triangle pair one vertex CW - *
-   *       n2                    n2
-   *  P +-----+             P +-----+
-   *    | t  /|               |\  t |
-   *    |   / |               | \   |
-   *  n1|  /  |n3           n1|  \  |n3
-   *    | /   |    after CW   |   \ |
-   *    |/ oT |               | oT \|
-   *    +-----+ oP            +-----+
-   *       n4                    n4
-   * 
- */ - void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const; - - /** - * Fills holes in the Advancing Front - * - * - * @param tcx - * @param n - */ - void FillAdvancingFront(SweepContext& tcx, Node& n); - - // Decision-making about when to Fill hole. - // Contributed by ToolmakerSteve2 - bool LargeHole_DontFill(const Node* node) const; - bool AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const; - bool AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const; - double Angle(const Point* origin, const Point* pa, const Point* pb) const; - - /** - * - * @param node - middle node - * @return the angle between 3 front nodes - */ - double HoleAngle(const Node& node) const; - - /** - * The basin angle is decided against the horizontal line [1,0] - */ - double BasinAngle(const Node& node) const; - - /** - * Fills a basin that has formed on the Advancing Front to the right - * of given node.
- * First we decide a left,bottom and right node that forms the - * boundaries of the basin. Then we do a reqursive fill. - * - * @param tcx - * @param node - starting node, this or next node will be left node - */ - void FillBasin(SweepContext& tcx, Node& node); - - /** - * Recursive algorithm to fill a Basin with triangles - * - * @param tcx - * @param node - bottom_node - * @param cnt - counter used to alternate on even and odd numbers - */ - void FillBasinReq(SweepContext& tcx, Node* node); - - bool IsShallow(SweepContext& tcx, Node& node); - - bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq); - - void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); - - void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); - - void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); - - void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); - - void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p); - - /** - * After a flip we have two triangles and know that only one will still be - * intersecting the edge. So decide which to contiune with and legalize the other - * - * @param tcx - * @param o - should be the result of an orient2d( eq, op, ep ) - * @param t - triangle 1 - * @param ot - triangle 2 - * @param p - a point shared by both triangles - * @param op - another point shared by both triangles - * @return returns the triangle still intersecting the edge - */ - Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op); - - /** - * When we need to traverse from one triangle to the next we need - * the point in current triangle that is the opposite point to the next - * triangle. - * - * @param ep - * @param eq - * @param ot - * @param op - * @return - */ - Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op); - - /** - * Scan part of the FlipScan algorithm
- * When a triangle pair isn't flippable we will scan for the next - * point that is inside the flip triangle scan area. When found - * we generate a new flipEdgeEvent - * - * @param tcx - * @param ep - last point on the edge we are traversing - * @param eq - first point on the edge we are traversing - * @param flipTriangle - the current triangle sharing the point eq with edge - * @param t - * @param p - */ - void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p); - - void FinalizationPolygon(SweepContext& tcx); - - std::vector nodes_; - -}; - -} - -#endif diff --git a/src/poly2tri/sweep/sweep_context.cc b/src/poly2tri/sweep/sweep_context.cc deleted file mode 100644 index 4a220dc828..0000000000 --- a/src/poly2tri/sweep/sweep_context.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "sweep_context.h" -#include -#include "advancing_front.h" - -namespace p2t { - -SweepContext::SweepContext(const std::vector& polyline) : points_(polyline), - front_(0), - head_(0), - tail_(0), - af_head_(0), - af_middle_(0), - af_tail_(0) -{ - InitEdges(points_); -} - -void SweepContext::AddHole(const std::vector& polyline) -{ - InitEdges(polyline); - for(unsigned int i = 0; i < polyline.size(); i++) { - points_.push_back(polyline[i]); - } -} - -void SweepContext::AddPoint(Point* point) { - points_.push_back(point); -} - -std::vector &SweepContext::GetTriangles() -{ - return triangles_; -} - -std::list &SweepContext::GetMap() -{ - return map_; -} - -void SweepContext::InitTriangulation() -{ - double xmax(points_[0]->x), xmin(points_[0]->x); - double ymax(points_[0]->y), ymin(points_[0]->y); - - // Calculate bounds. - for (unsigned int i = 0; i < points_.size(); i++) { - Point& p = *points_[i]; - if (p.x > xmax) - xmax = p.x; - if (p.x < xmin) - xmin = p.x; - if (p.y > ymax) - ymax = p.y; - if (p.y < ymin) - ymin = p.y; - } - - double dx = kAlpha * (xmax - xmin); - double dy = kAlpha * (ymax - ymin); - head_ = new Point(xmax + dx, ymin - dy); - tail_ = new Point(xmin - dx, ymin - dy); - - // Sort points along y-axis - std::sort(points_.begin(), points_.end(), cmp); - -} - -void SweepContext::InitEdges(const std::vector& polyline) -{ - size_t num_points = polyline.size(); - for (size_t i = 0; i < num_points; i++) { - size_t j = i < num_points - 1 ? i + 1 : 0; - edge_list.push_back(new Edge(*polyline[i], *polyline[j])); - } -} - -Point* SweepContext::GetPoint(size_t index) -{ - return points_[index]; -} - -void SweepContext::AddToMap(Triangle* triangle) -{ - map_.push_back(triangle); -} - -Node& SweepContext::LocateNode(const Point& point) -{ - // TODO implement search tree - return *front_->LocateNode(point.x); -} - -void SweepContext::CreateAdvancingFront() -{ - - // Initial triangle - Triangle* triangle = new Triangle(*points_[0], *tail_, *head_); - - map_.push_back(triangle); - - af_head_ = new Node(*triangle->GetPoint(1), *triangle); - af_middle_ = new Node(*triangle->GetPoint(0), *triangle); - af_tail_ = new Node(*triangle->GetPoint(2)); - front_ = new AdvancingFront(*af_head_, *af_tail_); - - // TODO: More intuitive if head is middles next and not previous? - // so swap head and tail - af_head_->next = af_middle_; - af_middle_->next = af_tail_; - af_middle_->prev = af_head_; - af_tail_->prev = af_middle_; -} - -void SweepContext::RemoveNode(Node* node) -{ - delete node; -} - -void SweepContext::MapTriangleToNodes(Triangle& t) -{ - for (int i = 0; i < 3; i++) { - if (!t.GetNeighbor(i)) { - Node* n = front_->LocatePoint(t.PointCW(*t.GetPoint(i))); - if (n) - n->triangle = &t; - } - } -} - -void SweepContext::RemoveFromMap(Triangle* triangle) -{ - map_.remove(triangle); -} - -void SweepContext::MeshClean(Triangle& triangle) -{ - std::vector triangles; - triangles.push_back(&triangle); - - while(!triangles.empty()){ - Triangle *t = triangles.back(); - triangles.pop_back(); - - if (t != NULL && !t->IsInterior()) { - t->IsInterior(true); - triangles_.push_back(t); - for (int i = 0; i < 3; i++) { - if (!t->constrained_edge[i]) - triangles.push_back(t->GetNeighbor(i)); - } - } - } -} - -SweepContext::~SweepContext() -{ - - // Clean up memory - - delete head_; - delete tail_; - delete front_; - delete af_head_; - delete af_middle_; - delete af_tail_; - - typedef std::list type_list; - - for(type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) { - Triangle* ptr = *iter; - delete ptr; - } - - for(unsigned int i = 0; i < edge_list.size(); i++) { - delete edge_list[i]; - } - -} - -} diff --git a/src/poly2tri/sweep/sweep_context.h b/src/poly2tri/sweep/sweep_context.h deleted file mode 100644 index b6bc1cd828..0000000000 --- a/src/poly2tri/sweep/sweep_context.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Poly2Tri Copyright (c) 2009-2018, Poly2Tri Contributors - * https://github.com/jhasse/poly2tri - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SWEEP_CONTEXT_H -#define SWEEP_CONTEXT_H - -#include -#include -#include - -namespace p2t { - -// Inital triangle factor, seed triangle will extend 30% of -// PointSet width to both left and right. -const double kAlpha = 0.3; - -struct Point; -class Triangle; -struct Node; -struct Edge; -class AdvancingFront; - -class SweepContext { -public: - -/// Constructor -SweepContext(const std::vector& polyline); -/// Destructor -~SweepContext(); - -void set_head(Point* p1); - -Point* head() const; - -void set_tail(Point* p1); - -Point* tail() const; - -size_t point_count() const; - -Node& LocateNode(const Point& point); - -void RemoveNode(Node* node); - -void CreateAdvancingFront(); - -/// Try to map a node to all sides of this triangle that don't have a neighbor -void MapTriangleToNodes(Triangle& t); - -void AddToMap(Triangle* triangle); - -Point* GetPoint(size_t index); - -Point* GetPoints(); - -void RemoveFromMap(Triangle* triangle); - -void AddHole(const std::vector& polyline); - -void AddPoint(Point* point); - -AdvancingFront* front() const; - -void MeshClean(Triangle& triangle); - -std::vector &GetTriangles(); -std::list &GetMap(); - -std::vector edge_list; - -struct Basin { - Node* left_node; - Node* bottom_node; - Node* right_node; - double width; - bool left_highest; - - Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false) - { - } - - void Clear() - { - left_node = NULL; - bottom_node = NULL; - right_node = NULL; - width = 0.0; - left_highest = false; - } -}; - -struct EdgeEvent { - Edge* constrained_edge; - bool right; - - EdgeEvent() : constrained_edge(NULL), right(false) - { - } -}; - -Basin basin; -EdgeEvent edge_event; - -private: - -friend class Sweep; - -std::vector triangles_; -std::list map_; -std::vector points_; - -// Advancing front -AdvancingFront* front_; -// head point used with advancing front -Point* head_; -// tail point used with advancing front -Point* tail_; - -Node *af_head_, *af_middle_, *af_tail_; - -void InitTriangulation(); -void InitEdges(const std::vector& polyline); - -}; - -inline AdvancingFront* SweepContext::front() const -{ - return front_; -} - -inline size_t SweepContext::point_count() const -{ - return points_.size(); -} - -inline void SweepContext::set_head(Point* p1) -{ - head_ = p1; -} - -inline Point* SweepContext::head() const -{ - return head_; -} - -inline void SweepContext::set_tail(Point* p1) -{ - tail_ = p1; -} - -inline Point* SweepContext::tail() const -{ - return tail_; -} - -} - -#endif diff --git a/src/polypartition/CMakeLists.txt b/src/polypartition/CMakeLists.txt deleted file mode 100644 index 07b92840b8..0000000000 --- a/src/polypartition/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(polypartition) -cmake_minimum_required(VERSION 2.6) - -add_library(polypartition STATIC - polypartition.cpp - polypartition.h -) diff --git a/src/polypartition/polypartition.cpp b/src/polypartition/polypartition.cpp deleted file mode 100644 index c1d6a4c83f..0000000000 --- a/src/polypartition/polypartition.cpp +++ /dev/null @@ -1,1574 +0,0 @@ -//Copyright (C) 2011 by Ivan Fratric -// -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files (the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions: -// -//The above copyright notice and this permission notice shall be included in -//all copies or substantial portions of the Software. -// -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -//THE SOFTWARE. - - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -#include "polypartition.h" - -#define TPPL_VERTEXTYPE_REGULAR 0 -#define TPPL_VERTEXTYPE_START 1 -#define TPPL_VERTEXTYPE_END 2 -#define TPPL_VERTEXTYPE_SPLIT 3 -#define TPPL_VERTEXTYPE_MERGE 4 - -TPPLPoly::TPPLPoly() { - hole = false; - numpoints = 0; - points = NULL; -} - -TPPLPoly::~TPPLPoly() { - if(points) delete [] points; -} - -void TPPLPoly::Clear() { - if(points) delete [] points; - hole = false; - numpoints = 0; - points = NULL; -} - -void TPPLPoly::Init(long numpoints) { - Clear(); - this->numpoints = numpoints; - points = new TPPLPoint[numpoints]; -} - -void TPPLPoly::Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) { - Init(3); - points[0] = p1; - points[1] = p2; - points[2] = p3; -} - -TPPLPoly::TPPLPoly(const TPPLPoly &src) : TPPLPoly() { - hole = src.hole; - numpoints = src.numpoints; - - if(numpoints > 0) { - points = new TPPLPoint[numpoints]; - memcpy(points, src.points, numpoints*sizeof(TPPLPoint)); - } -} - -TPPLPoly& TPPLPoly::operator=(const TPPLPoly &src) { - Clear(); - hole = src.hole; - numpoints = src.numpoints; - - if(numpoints > 0) { - points = new TPPLPoint[numpoints]; - memcpy(points, src.points, numpoints*sizeof(TPPLPoint)); - } - - return *this; -} - -int TPPLPoly::GetOrientation() const { - long i1,i2; - tppl_float area = 0; - for(i1=0; i10) return TPPL_CCW; - if(area<0) return TPPL_CW; - return 0; -} - -void TPPLPoly::SetOrientation(int orientation) { - int polyorientation = GetOrientation(); - if(polyorientation&&(polyorientation!=orientation)) { - Invert(); - } -} - -void TPPLPoly::Invert() { - std::reverse(points, points + numpoints); -} - -TPPLPartition::PartitionVertex::PartitionVertex() : previous(NULL), next(NULL) { - -} - -TPPLPoint TPPLPartition::Normalize(const TPPLPoint &p) { - TPPLPoint r; - tppl_float n = sqrt(p.x*p.x + p.y*p.y); - if(n!=0) { - r = p/n; - } else { - r.x = 0; - r.y = 0; - } - return r; -} - -tppl_float TPPLPartition::Distance(const TPPLPoint &p1, const TPPLPoint &p2) { - tppl_float dx,dy; - dx = p2.x - p1.x; - dy = p2.y - p1.y; - return(sqrt(dx*dx + dy*dy)); -} - -//checks if two lines intersect -int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22) { - if((p11.x == p21.x)&&(p11.y == p21.y)) return 0; - if((p11.x == p22.x)&&(p11.y == p22.y)) return 0; - if((p12.x == p21.x)&&(p12.y == p21.y)) return 0; - if((p12.x == p22.x)&&(p12.y == p22.y)) return 0; - - TPPLPoint v1ort,v2ort,v; - tppl_float dot11,dot12,dot21,dot22; - - v1ort.x = p12.y-p11.y; - v1ort.y = p11.x-p12.x; - - v2ort.x = p22.y-p21.y; - v2ort.y = p21.x-p22.x; - - v = p21-p11; - dot21 = v.x*v1ort.x + v.y*v1ort.y; - v = p22-p11; - dot22 = v.x*v1ort.x + v.y*v1ort.y; - - v = p11-p21; - dot11 = v.x*v2ort.x + v.y*v2ort.y; - v = p12-p21; - dot12 = v.x*v2ort.x + v.y*v2ort.y; - - if(dot11*dot12>0) return 0; - if(dot21*dot22>0) return 0; - - return 1; -} - -//removes holes from inpolys by merging them with non-holes -int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { - TPPLPolyList polys; - TPPLPolyList::iterator holeiter,polyiter,iter,iter2; - long i,i2,holepointindex,polypointindex; - TPPLPoint holepoint,polypoint,bestpolypoint; - TPPLPoint linep1,linep2; - TPPLPoint v1,v2; - TPPLPoly newpoly; - bool hasholes; - bool pointvisible; - bool pointfound; - - //check for trivial case (no holes) - hasholes = false; - for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { - if(iter->IsHole()) { - hasholes = true; - break; - } - } - if(!hasholes) { - for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { - outpolys->push_back(*iter); - } - return 1; - } - - polys = *inpolys; - - while(1) { - //find the hole point with the largest x - hasholes = false; - for(iter = polys.begin(); iter!=polys.end(); iter++) { - if(!iter->IsHole()) continue; - - if(!hasholes) { - hasholes = true; - holeiter = iter; - holepointindex = 0; - } - - for(i=0; i < iter->GetNumPoints(); i++) { - if(iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) { - holeiter = iter; - holepointindex = i; - } - } - } - if(!hasholes) break; - holepoint = holeiter->GetPoint(holepointindex); - - pointfound = false; - for(iter = polys.begin(); iter!=polys.end(); iter++) { - if(iter->IsHole()) continue; - for(i=0; i < iter->GetNumPoints(); i++) { - if(iter->GetPoint(i).x <= holepoint.x) continue; - if(!InCone(iter->GetPoint((i+iter->GetNumPoints()-1)%(iter->GetNumPoints())), - iter->GetPoint(i), - iter->GetPoint((i+1)%(iter->GetNumPoints())), - holepoint)) - continue; - polypoint = iter->GetPoint(i); - if(pointfound) { - v1 = Normalize(polypoint-holepoint); - v2 = Normalize(bestpolypoint-holepoint); - if(v2.x > v1.x) continue; - } - pointvisible = true; - for(iter2 = polys.begin(); iter2!=polys.end(); iter2++) { - if(iter2->IsHole()) continue; - for(i2=0; i2 < iter2->GetNumPoints(); i2++) { - linep1 = iter2->GetPoint(i2); - linep2 = iter2->GetPoint((i2+1)%(iter2->GetNumPoints())); - if(Intersects(holepoint,polypoint,linep1,linep2)) { - pointvisible = false; - break; - } - } - if(!pointvisible) break; - } - if(pointvisible) { - pointfound = true; - bestpolypoint = polypoint; - polyiter = iter; - polypointindex = i; - } - } - } - - if(!pointfound) return 0; - - newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2); - i2 = 0; - for(i=0;i<=polypointindex;i++) { - newpoly[i2] = polyiter->GetPoint(i); - i2++; - } - for(i=0;i<=holeiter->GetNumPoints();i++) { - newpoly[i2] = holeiter->GetPoint((i+holepointindex)%holeiter->GetNumPoints()); - i2++; - } - for(i=polypointindex;iGetNumPoints();i++) { - newpoly[i2] = polyiter->GetPoint(i); - i2++; - } - - polys.erase(holeiter); - polys.erase(polyiter); - polys.push_back(newpoly); - } - - for(iter = polys.begin(); iter!=polys.end(); iter++) { - outpolys->push_back(*iter); - } - - return 1; -} - -bool TPPLPartition::IsConvex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3) { - tppl_float tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp>0) return 1; - else return 0; -} - -bool TPPLPartition::IsReflex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3) { - tppl_float tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp<0) return 1; - else return 0; -} - -bool TPPLPartition::IsInside(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3, TPPLPoint &p) { - if(IsConvex(p1,p,p2)) return false; - if(IsConvex(p2,p,p3)) return false; - if(IsConvex(p3,p,p1)) return false; - return true; -} - -bool TPPLPartition::InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) { - bool convex; - - convex = IsConvex(p1,p2,p3); - - if(convex) { - if(!IsConvex(p1,p2,p)) return false; - if(!IsConvex(p2,p3,p)) return false; - return true; - } else { - if(IsConvex(p1,p2,p)) return true; - if(IsConvex(p2,p3,p)) return true; - return false; - } -} - -bool TPPLPartition::InCone(PartitionVertex *v, TPPLPoint &p) { - TPPLPoint p1,p2,p3; - - p1 = v->previous->p; - p2 = v->p; - p3 = v->next->p; - - return InCone(p1,p2,p3,p); -} - -void TPPLPartition::UpdateVertexReflexity(PartitionVertex *v) { - PartitionVertex *v1 = NULL,*v3 = NULL; - v1 = v->previous; - v3 = v->next; - v->isConvex = !IsReflex(v1->p,v->p,v3->p); -} - -void TPPLPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) { - long i; - PartitionVertex *v1 = NULL,*v3 = NULL; - TPPLPoint vec1,vec3; - - v1 = v->previous; - v3 = v->next; - - v->isConvex = IsConvex(v1->p,v->p,v3->p); - - vec1 = Normalize(v1->p - v->p); - vec3 = Normalize(v3->p - v->p); - v->angle = vec1.x*vec3.x + vec1.y*vec3.y; - - if(v->isConvex) { - v->isEar = true; - for(i=0;ip.x)&&(vertices[i].p.y==v->p.y)) continue; - if((vertices[i].p.x==v1->p.x)&&(vertices[i].p.y==v1->p.y)) continue; - if((vertices[i].p.x==v3->p.x)&&(vertices[i].p.y==v3->p.y)) continue; - if(IsInside(v1->p,v->p,v3->p,vertices[i].p)) { - v->isEar = false; - break; - } - } - } else { - v->isEar = false; - } -} - -//triangulation by ear removal -int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) { - if(!poly->Valid()) return 0; - - long numvertices; - PartitionVertex *vertices = NULL; - PartitionVertex *ear = NULL; - TPPLPoly triangle; - long i,j; - bool earfound; - - if(poly->GetNumPoints() < 3) return 0; - if(poly->GetNumPoints() == 3) { - triangles->push_back(*poly); - return 1; - } - - numvertices = poly->GetNumPoints(); - - vertices = new PartitionVertex[numvertices]; - for(i=0;iGetPoint(i); - if(i==(numvertices-1)) vertices[i].next=&(vertices[0]); - else vertices[i].next=&(vertices[i+1]); - if(i==0) vertices[i].previous = &(vertices[numvertices-1]); - else vertices[i].previous = &(vertices[i-1]); - } - for(i=0;i ear->angle) { - ear = &(vertices[j]); - } - } - } - if(!earfound) { - delete [] vertices; - return 0; - } - - triangle.Triangle(ear->previous->p,ear->p,ear->next->p); - triangles->push_back(triangle); - - ear->isActive = false; - ear->previous->next = ear->next; - ear->next->previous = ear->previous; - - if(i==numvertices-4) break; - - UpdateVertex(ear->previous,vertices,numvertices); - UpdateVertex(ear->next,vertices,numvertices); - } - for(i=0;ip,vertices[i].p,vertices[i].next->p); - triangles->push_back(triangle); - break; - } - } - - delete [] vertices; - - return 1; -} - -int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) { - TPPLPolyList outpolys; - TPPLPolyList::iterator iter; - - if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.begin();iter!=outpolys.end();iter++) { - if(!Triangulate_EC(&(*iter),triangles)) return 0; - } - return 1; -} - -int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { - if(!poly->Valid()) return 0; - - TPPLPolyList triangles; - TPPLPolyList::iterator iter1,iter2; - TPPLPoly *poly1 = NULL,*poly2 = NULL; - TPPLPoly newpoly; - TPPLPoint d1,d2,p1,p2,p3; - long i11,i12,i21,i22,i13,i23,j,k; - bool isdiagonal; - long numreflex; - - //check if the poly is already convex - numreflex = 0; - for(i11=0;i11GetNumPoints();i11++) { - if(i11==0) i12 = poly->GetNumPoints()-1; - else i12=i11-1; - if(i11==(poly->GetNumPoints()-1)) i13=0; - else i13=i11+1; - if(IsReflex(poly->GetPoint(i12),poly->GetPoint(i11),poly->GetPoint(i13))) { - numreflex = 1; - break; - } - } - if(numreflex == 0) { - parts->push_back(*poly); - return 1; - } - - if(!Triangulate_EC(poly,&triangles)) return 0; - - for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { - poly1 = &(*iter1); - for(i11=0;i11GetNumPoints();i11++) { - d1 = poly1->GetPoint(i11); - i12 = (i11+1)%(poly1->GetNumPoints()); - d2 = poly1->GetPoint(i12); - - isdiagonal = false; - for(iter2 = iter1; iter2 != triangles.end(); iter2++) { - if(iter1 == iter2) continue; - poly2 = &(*iter2); - - for(i21=0;i21GetNumPoints();i21++) { - if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue; - i22 = (i21+1)%(poly2->GetNumPoints()); - if((d1.x != poly2->GetPoint(i22).x)||(d1.y != poly2->GetPoint(i22).y)) continue; - isdiagonal = true; - break; - } - if(isdiagonal) break; - } - - if(!isdiagonal) continue; - - p2 = poly1->GetPoint(i11); - if(i11 == 0) i13 = poly1->GetNumPoints()-1; - else i13 = i11-1; - p1 = poly1->GetPoint(i13); - if(i22 == (poly2->GetNumPoints()-1)) i23 = 0; - else i23 = i22+1; - p3 = poly2->GetPoint(i23); - - if(!IsConvex(p1,p2,p3)) continue; - - p2 = poly1->GetPoint(i12); - if(i12 == (poly1->GetNumPoints()-1)) i13 = 0; - else i13 = i12+1; - p3 = poly1->GetPoint(i13); - if(i21 == 0) i23 = poly2->GetNumPoints()-1; - else i23 = i21-1; - p1 = poly2->GetPoint(i23); - - if(!IsConvex(p1,p2,p3)) continue; - - newpoly.Init(poly1->GetNumPoints()+poly2->GetNumPoints()-2); - k = 0; - for(j=i12;j!=i11;j=(j+1)%(poly1->GetNumPoints())) { - newpoly[k] = poly1->GetPoint(j); - k++; - } - for(j=i22;j!=i21;j=(j+1)%(poly2->GetNumPoints())) { - newpoly[k] = poly2->GetPoint(j); - k++; - } - - triangles.erase(iter2); - *iter1 = newpoly; - poly1 = &(*iter1); - i11 = -1; - - continue; - } - } - - for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { - parts->push_back(*iter1); - } - - return 1; -} - -int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) { - TPPLPolyList outpolys; - TPPLPolyList::iterator iter; - - if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.begin();iter!=outpolys.end();iter++) { - if(!ConvexPartition_HM(&(*iter),parts)) return 0; - } - return 1; -} - -//minimum-weight polygon triangulation by dynamic programming -//O(n^3) time complexity -//O(n^2) space complexity -int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) { - if(!poly->Valid()) return 0; - - long i,j,k,gap,n; - DPState **dpstates = NULL; - TPPLPoint p1,p2,p3,p4; - long bestvertex; - tppl_float weight,minweight,d1,d2; - Diagonal diagonal,newdiagonal; - DiagonalList diagonals; - TPPLPoly triangle; - int ret = 1; - - n = poly->GetNumPoints(); - dpstates = new DPState *[n]; - for(i=1;iGetPoint(i); - for(j=i+1;jGetPoint(j); - - //visibility check - if(i==0) p3 = poly->GetPoint(n-1); - else p3 = poly->GetPoint(i-1); - if(i==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(i+1); - if(!InCone(p3,p1,p4,p2)) { - dpstates[j][i].visible = false; - continue; - } - - if(j==0) p3 = poly->GetPoint(n-1); - else p3 = poly->GetPoint(j-1); - if(j==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(j+1); - if(!InCone(p3,p2,p4,p1)) { - dpstates[j][i].visible = false; - continue; - } - - for(k=0;kGetPoint(k); - if(k==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(k+1); - if(Intersects(p1,p2,p3,p4)) { - dpstates[j][i].visible = false; - break; - } - } - } - } - } - dpstates[n-1][0].visible = true; - dpstates[n-1][0].weight = 0; - dpstates[n-1][0].bestvertex = -1; - - for(gap = 2; gapGetPoint(i),poly->GetPoint(k)); - if(j<=(k+1)) d2=0; - else d2 = Distance(poly->GetPoint(k),poly->GetPoint(j)); - - weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2; - - if((bestvertex == -1)||(weightGetPoint(diagonal.index1),poly->GetPoint(bestvertex),poly->GetPoint(diagonal.index2)); - triangles->push_back(triangle); - if(bestvertex > (diagonal.index1+1)) { - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = bestvertex; - diagonals.push_back(newdiagonal); - } - if(diagonal.index2 > (bestvertex+1)) { - newdiagonal.index1 = bestvertex; - newdiagonal.index2 = diagonal.index2; - diagonals.push_back(newdiagonal); - } - } - - for(i=1;iw2) return; - - pairs = &(dpstates[a][b].pairs); - newdiagonal.index1 = i; - newdiagonal.index2 = j; - - if(wclear(); - pairs->push_front(newdiagonal); - dpstates[a][b].weight = w; - } else { - if((!pairs->empty())&&(i <= pairs->begin()->index1)) return; - while((!pairs->empty())&&(pairs->begin()->index2 >= j)) pairs->pop_front(); - pairs->push_front(newdiagonal); - } -} - -void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - DiagonalList *pairs = NULL; - DiagonalList::iterator iter,lastiter; - long top; - long w; - - if(!dpstates[i][j].visible) return; - top = j; - w = dpstates[i][j].weight; - if(k-j > 1) { - if (!dpstates[j][k].visible) return; - w += dpstates[j][k].weight + 1; - } - if(j-i > 1) { - pairs = &(dpstates[i][j].pairs); - iter = pairs->end(); - lastiter = pairs->end(); - while(iter!=pairs->begin()) { - iter--; - if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; - else break; - } - if(lastiter == pairs->end()) w++; - else { - if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->index1].p)) w++; - else top = lastiter->index1; - } - } - UpdateState(i,k,w,top,j,dpstates); -} - -void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - DiagonalList *pairs = NULL; - DiagonalList::iterator iter,lastiter; - long top; - long w; - - if(!dpstates[j][k].visible) return; - top = j; - w = dpstates[j][k].weight; - - if (j-i > 1) { - if (!dpstates[i][j].visible) return; - w += dpstates[i][j].weight + 1; - } - if (k-j > 1) { - pairs = &(dpstates[j][k].pairs); - - iter = pairs->begin(); - if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p))) { - lastiter = iter; - while(iter!=pairs->end()) { - if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) { - lastiter = iter; - iter++; - } - else break; - } - if(IsReflex(vertices[lastiter->index2].p,vertices[k].p,vertices[i].p)) w++; - else top = lastiter->index2; - } else w++; - } - UpdateState(i,k,w,j,top,dpstates); -} - -int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { - if(!poly->Valid()) return 0; - - TPPLPoint p1,p2,p3,p4; - PartitionVertex *vertices = NULL; - DPState2 **dpstates = NULL; - long i,j,k,n,gap; - DiagonalList diagonals,diagonals2; - Diagonal diagonal,newdiagonal; - DiagonalList *pairs = NULL,*pairs2 = NULL; - DiagonalList::iterator iter,iter2; - int ret; - TPPLPoly newpoly; - vector indices; - vector::iterator iiter; - bool ijreal,jkreal; - - n = poly->GetNumPoints(); - vertices = new PartitionVertex[n]; - - dpstates = new DPState2 *[n]; - for(i=0;iGetPoint(i); - vertices[i].isActive = true; - if(i==0) vertices[i].previous = &(vertices[n-1]); - else vertices[i].previous = &(vertices[i-1]); - if(i==(poly->GetNumPoints()-1)) vertices[i].next = &(vertices[0]); - else vertices[i].next = &(vertices[i+1]); - } - for(i=1;iGetPoint(i); - for(j=i+1;jGetPoint(j); - - //visibility check - if(!InCone(&vertices[i],p2)) { - dpstates[i][j].visible = false; - continue; - } - if(!InCone(&vertices[j],p1)) { - dpstates[i][j].visible = false; - continue; - } - - for(k=0;kGetPoint(k); - if(k==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(k+1); - if(Intersects(p1,p2,p3,p4)) { - dpstates[i][j].visible = false; - break; - } - } - } - } - } - for(i=0;i<(n-2);i++) { - j = i+2; - if(dpstates[i][j].visible) { - dpstates[i][j].weight = 0; - newdiagonal.index1 = i+1; - newdiagonal.index2 = i+1; - dpstates[i][j].pairs.push_back(newdiagonal); - } - } - - dpstates[0][n-1].visible = true; - vertices[0].isConvex = false; //by convention - - for(gap=3; gapempty()) { - ret = 0; - break; - } - if(!vertices[diagonal.index1].isConvex) { - iter = pairs->end(); - iter--; - j = iter->index2; - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - diagonals.push_front(newdiagonal); - if((j - diagonal.index1)>1) { - if(iter->index1 != iter->index2) { - pairs2 = &(dpstates[diagonal.index1][j].pairs); - while(1) { - if(pairs2->empty()) { - ret = 0; - break; - } - iter2 = pairs2->end(); - iter2--; - if(iter->index1 != iter2->index1) pairs2->pop_back(); - else break; - } - if(ret == 0) break; - } - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - diagonals.push_front(newdiagonal); - } - } else { - iter = pairs->begin(); - j = iter->index1; - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - diagonals.push_front(newdiagonal); - if((diagonal.index2 - j) > 1) { - if(iter->index1 != iter->index2) { - pairs2 = &(dpstates[j][diagonal.index2].pairs); - while(1) { - if(pairs2->empty()) { - ret = 0; - break; - } - iter2 = pairs2->begin(); - if(iter->index2 != iter2->index2) pairs2->pop_front(); - else break; - } - if(ret == 0) break; - } - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - diagonals.push_front(newdiagonal); - } - } - } - - if(ret == 0) { - for(i=0;iend(); - iter--; - j = iter->index2; - if(iter->index1 != iter->index2) ijreal = false; - } else { - iter = pairs->begin(); - j = iter->index1; - if(iter->index1 != iter->index2) jkreal = false; - } - - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - if(ijreal) { - diagonals.push_back(newdiagonal); - } else { - diagonals2.push_back(newdiagonal); - } - - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - if(jkreal) { - diagonals.push_back(newdiagonal); - } else { - diagonals2.push_back(newdiagonal); - } - - indices.push_back(j); - } - - std::sort(indices.begin(), indices.end()); - newpoly.Init((long)indices.size()); - k=0; - for(iiter = indices.begin();iiter!=indices.end();iiter++) { - newpoly[k] = vertices[*iiter].p; - k++; - } - parts->push_back(newpoly); - } - - for(i=0;ibegin(); iter != inpolys->end(); iter++) { - if(!iter->Valid()) return 0; - numvertices += iter->GetNumPoints(); - } - - maxnumvertices = numvertices*3; - vertices = new MonotoneVertex[maxnumvertices]; - newnumvertices = numvertices; - - polystartindex = 0; - for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { - poly = &(*iter); - polyendindex = polystartindex + poly->GetNumPoints()-1; - for(i=0;iGetNumPoints();i++) { - vertices[i+polystartindex].p = poly->GetPoint(i); - if(i==0) vertices[i+polystartindex].previous = polyendindex; - else vertices[i+polystartindex].previous = i+polystartindex-1; - if(i==(poly->GetNumPoints()-1)) vertices[i+polystartindex].next = polystartindex; - else vertices[i+polystartindex].next = i+polystartindex+1; - } - polystartindex = polyendindex+1; - } - - //construct the priority queue - long *priority = new long [numvertices]; - for(i=0;iprevious]); - vnext = &(vertices[v->next]); - - if(Below(vprev->p,v->p)&&Below(vnext->p,v->p)) { - if(IsConvex(vnext->p,vprev->p,v->p)) { - vertextypes[i] = TPPL_VERTEXTYPE_START; - } else { - vertextypes[i] = TPPL_VERTEXTYPE_SPLIT; - } - } else if(Below(v->p,vprev->p)&&Below(v->p,vnext->p)) { - if(IsConvex(vnext->p,vprev->p,v->p)) - { - vertextypes[i] = TPPL_VERTEXTYPE_END; - } else { - vertextypes[i] = TPPL_VERTEXTYPE_MERGE; - } - } else { - vertextypes[i] = TPPL_VERTEXTYPE_REGULAR; - } - } - - //helpers - long *helpers = new long[maxnumvertices]; - - //binary search tree that holds edges intersecting the scanline - //note that while set doesn't actually have to be implemented as a tree - //complexity requirements for operations are the same as for the balanced binary search tree - set edgeTree; - //store iterators to the edge tree elements - //this makes deleting existing edges much faster - set::iterator *edgeTreeIterators,edgeIter; - edgeTreeIterators = new set::iterator[maxnumvertices]; - pair::iterator,bool> edgeTreeRet; - for(i = 0; ip; - newedge.p2 = vertices[v->next].p; - newedge.index = vindex; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex] = edgeTreeRet.first; - helpers[vindex] = vindex; - break; - - case TPPL_VERTEXTYPE_END: - if (edgeTreeIterators[v->previous] == edgeTree.end()) { - error = true; - break; - } - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TPPL_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //Delete ei-1 from T - edgeTree.erase(edgeTreeIterators[v->previous]); - break; - - case TPPL_VERTEXTYPE_SPLIT: - //Search in T to find the edge e j directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { - error = true; - break; - } - edgeIter--; - //Insert the diagonal connecting vi to helper(ej) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - //helper(e j)�vi - helpers[edgeIter->index] = vindex; - //Insert ei in T and set helper(ei) to vi. - newedge.p1 = v2->p; - newedge.p2 = vertices[v2->next].p; - newedge.index = vindex2; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex2] = edgeTreeRet.first; - helpers[vindex2] = vindex2; - break; - - case TPPL_VERTEXTYPE_MERGE: - if (edgeTreeIterators[v->previous] == edgeTree.end()) { - error = true; - break; - } - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TPPL_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - } - //Delete ei-1 from T. - edgeTree.erase(edgeTreeIterators[v->previous]); - //Search in T to find the edge e j directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { - error = true; - break; - } - edgeIter--; - //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //helper(e j)�vi - helpers[edgeIter->index] = vindex2; - break; - - case TPPL_VERTEXTYPE_REGULAR: - //if the interior of P lies to the right of vi - if(Below(v->p,vertices[v->previous].p)) { - if (edgeTreeIterators[v->previous] == edgeTree.end()) { - error = true; - break; - } - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TPPL_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - } - //Delete ei-1 from T. - edgeTree.erase(edgeTreeIterators[v->previous]); - //Insert ei in T and set helper(ei) to vi. - newedge.p1 = v2->p; - newedge.p2 = vertices[v2->next].p; - newedge.index = vindex2; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex2] = edgeTreeRet.first; - helpers[vindex2] = vindex; - } else { - //Search in T to find the edge ej directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { - error = true; - break; - } - edgeIter--; - //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //helper(e j)�vi - helpers[edgeIter->index] = vindex; - } - break; - } - - if(error) break; - } - - char *used = new char[newnumvertices]; - memset(used,0,newnumvertices*sizeof(char)); - - if(!error) { - //return result - long size; - TPPLPoly mpoly; - for(i=0;inext]); - size = 1; - while(vnext!=v) { - vnext = &(vertices[vnext->next]); - size++; - } - mpoly.Init(size); - v = &(vertices[i]); - mpoly[0] = v->p; - vnext = &(vertices[v->next]); - size = 1; - used[i] = 1; - used[v->next] = 1; - while(vnext!=v) { - mpoly[size] = vnext->p; - used[vnext->next] = 1; - vnext = &(vertices[vnext->next]); - size++; - } - monotonePolys->push_back(mpoly); - } - } - - //cleanup - delete [] vertices; - delete [] priority; - delete [] vertextypes; - delete [] edgeTreeIterators; - delete [] helpers; - delete [] used; - - if(error) { - return 0; - } else { - return 1; - } -} - -//adds a diagonal to the doubly-connected list of vertices -void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, set::iterator *edgeTreeIterators, - set *edgeTree, long *helpers) -{ - long newindex1,newindex2; - - newindex1 = *numvertices; - (*numvertices)++; - newindex2 = *numvertices; - (*numvertices)++; - - vertices[newindex1].p = vertices[index1].p; - vertices[newindex2].p = vertices[index2].p; - - vertices[newindex2].next = vertices[index2].next; - vertices[newindex1].next = vertices[index1].next; - - vertices[vertices[index2].next].previous = newindex2; - vertices[vertices[index1].next].previous = newindex1; - - vertices[index1].next = newindex2; - vertices[newindex2].previous = index1; - - vertices[index2].next = newindex1; - vertices[newindex1].previous = index2; - - //update all relevant structures - vertextypes[newindex1] = vertextypes[index1]; - edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; - helpers[newindex1] = helpers[index1]; - if(edgeTreeIterators[newindex1] != edgeTree->end()) - edgeTreeIterators[newindex1]->index = newindex1; - vertextypes[newindex2] = vertextypes[index2]; - edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; - helpers[newindex2] = helpers[index2]; - if(edgeTreeIterators[newindex2] != edgeTree->end()) - edgeTreeIterators[newindex2]->index = newindex2; -} - -bool TPPLPartition::Below(TPPLPoint &p1, TPPLPoint &p2) { - if(p1.y < p2.y) return true; - else if(p1.y == p2.y) { - if(p1.x < p2.x) return true; - } - return false; -} - -//sorts in the falling order of y values, if y is equal, x is used instead -bool TPPLPartition::VertexSorter::operator() (long index1, long index2) { - if(vertices[index1].p.y > vertices[index2].p.y) return true; - else if(vertices[index1].p.y == vertices[index2].p.y) { - if(vertices[index1].p.x > vertices[index2].p.x) return true; - } - return false; -} - -bool TPPLPartition::ScanLineEdge::IsConvex(const TPPLPoint& p1, const TPPLPoint& p2, const TPPLPoint& p3) const { - tppl_float tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp>0) return 1; - else return 0; -} - -bool TPPLPartition::ScanLineEdge::operator < (const ScanLineEdge & other) const { - if(other.p1.y == other.p2.y) { - if(p1.y == p2.y) { - if(p1.y < other.p1.y) return true; - else return false; - } - if(IsConvex(p1,p2,other.p1)) return true; - else return false; - } else if(p1.y == p2.y) { - if(IsConvex(other.p1,other.p2,p1)) return false; - else return true; - } else if(p1.y < other.p1.y) { - if(IsConvex(other.p1,other.p2,p1)) return false; - else return true; - } else { - if(IsConvex(p1,p2,other.p1)) return true; - else return false; - } -} - -//triangulates monotone polygon -//O(n) time, O(n) space complexity -int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles) { - if(!inPoly->Valid()) return 0; - - long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex; - TPPLPoint *points = NULL; - long numpoints; - TPPLPoly triangle; - - numpoints = inPoly->GetNumPoints(); - points = inPoly->GetPoints(); - - //trivial case - if(numpoints == 3) { - triangles->push_back(*inPoly); - return 1; - } - - topindex = 0; bottomindex=0; - for(i=1;i=numpoints) i2 = 0; - if(!Below(points[i2],points[i])) return 0; - i = i2; - } - i = bottomindex; - while(i!=topindex) { - i2 = i+1; if(i2>=numpoints) i2 = 0; - if(!Below(points[i],points[i2])) return 0; - i = i2; - } - - char *vertextypes = new char[numpoints]; - long *priority = new long[numpoints]; - - //merge left and right vertex chains - priority[0] = topindex; - vertextypes[topindex] = 0; - leftindex = topindex+1; if(leftindex>=numpoints) leftindex = 0; - rightindex = topindex-1; if(rightindex<0) rightindex = numpoints-1; - for(i=1;i<(numpoints-1);i++) { - if(leftindex==bottomindex) { - priority[i] = rightindex; - rightindex--; if(rightindex<0) rightindex = numpoints-1; - vertextypes[priority[i]] = -1; - } else if(rightindex==bottomindex) { - priority[i] = leftindex; - leftindex++; if(leftindex>=numpoints) leftindex = 0; - vertextypes[priority[i]] = 1; - } else { - if(Below(points[leftindex],points[rightindex])) { - priority[i] = rightindex; - rightindex--; if(rightindex<0) rightindex = numpoints-1; - vertextypes[priority[i]] = -1; - } else { - priority[i] = leftindex; - leftindex++; if(leftindex>=numpoints) leftindex = 0; - vertextypes[priority[i]] = 1; - } - } - } - priority[i] = bottomindex; - vertextypes[bottomindex] = 0; - - long *stack = new long[numpoints]; - long stackptr = 0; - - stack[0] = priority[0]; - stack[1] = priority[1]; - stackptr = 2; - - //for each vertex from top to bottom trim as many triangles as possible - for(i=2;i<(numpoints-1);i++) { - vindex = priority[i]; - if(vertextypes[vindex]!=vertextypes[stack[stackptr-1]]) { - for(j=0;j<(stackptr-1);j++) { - if(vertextypes[vindex]==1) { - triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); - } else { - triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); - } - triangles->push_back(triangle); - } - stack[0] = priority[i-1]; - stack[1] = priority[i]; - stackptr = 2; - } else { - stackptr--; - while(stackptr>0) { - if(vertextypes[vindex]==1) { - if(IsConvex(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]])) { - triangle.Triangle(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]]); - triangles->push_back(triangle); - stackptr--; - } else { - break; - } - } else { - if(IsConvex(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]])) { - triangle.Triangle(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]]); - triangles->push_back(triangle); - stackptr--; - } else { - break; - } - } - } - stackptr++; - stack[stackptr] = vindex; - stackptr++; - } - } - vindex = priority[i]; - for(j=0;j<(stackptr-1);j++) { - if(vertextypes[stack[j+1]]==1) { - triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); - } else { - triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); - } - triangles->push_back(triangle); - } - - delete [] priority; - delete [] vertextypes; - delete [] stack; - - return 1; -} - -int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) { - TPPLPolyList monotone; - TPPLPolyList::iterator iter; - - if(!MonotonePartition(inpolys,&monotone)) return 0; - for(iter = monotone.begin(); iter!=monotone.end();iter++) { - if(!TriangulateMonotone(&(*iter),triangles)) return 0; - } - return 1; -} - -int TPPLPartition::Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles) { - TPPLPolyList polys; - polys.push_back(*poly); - - return Triangulate_MONO(&polys, triangles); -} diff --git a/src/polypartition/polypartition.h b/src/polypartition/polypartition.h deleted file mode 100644 index a89873296d..0000000000 --- a/src/polypartition/polypartition.h +++ /dev/null @@ -1,379 +0,0 @@ -//Copyright (C) 2011 by Ivan Fratric -// -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files (the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions: -// -//The above copyright notice and this permission notice shall be included in -//all copies or substantial portions of the Software. -// -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -//THE SOFTWARE. - -#ifndef POLYPARTITION_H -#define POLYPARTITION_H - -#include -#include - -typedef double tppl_float; - -#define TPPL_CCW 1 -#define TPPL_CW -1 - -//2D point structure -struct TPPLPoint { - tppl_float x; - tppl_float y; - // User-specified vertex identifier. Note that this isn't used internally - // by the library, but will be faithfully copied around. - int id; - - TPPLPoint operator + (const TPPLPoint& p) const { - TPPLPoint r; - r.x = x + p.x; - r.y = y + p.y; - return r; - } - - TPPLPoint operator - (const TPPLPoint& p) const { - TPPLPoint r; - r.x = x - p.x; - r.y = y - p.y; - return r; - } - - TPPLPoint operator * (const tppl_float f ) const { - TPPLPoint r; - r.x = x*f; - r.y = y*f; - return r; - } - - TPPLPoint operator / (const tppl_float f ) const { - TPPLPoint r; - r.x = x/f; - r.y = y/f; - return r; - } - - bool operator==(const TPPLPoint& p) const { - if((x == p.x)&&(y==p.y)) return true; - else return false; - } - - bool operator!=(const TPPLPoint& p) const { - if((x == p.x)&&(y==p.y)) return false; - else return true; - } -}; - - -//Polygon implemented as an array of points with a 'hole' flag -class TPPLPoly { - protected: - - TPPLPoint *points; - long numpoints; - bool hole; - - public: - - //constructors/destructors - TPPLPoly(); - ~TPPLPoly(); - - TPPLPoly(const TPPLPoly &src); - TPPLPoly& operator=(const TPPLPoly &src); - - //getters and setters - long GetNumPoints() const { - return numpoints; - } - - bool IsHole() const { - return hole; - } - - void SetHole(bool hole) { - this->hole = hole; - } - - TPPLPoint &GetPoint(long i) { - return points[i]; - } - - const TPPLPoint &GetPoint(long i) const { - return points[i]; - } - - TPPLPoint *GetPoints() { - return points; - } - - TPPLPoint& operator[] (int i) { - return points[i]; - } - - const TPPLPoint& operator[] (int i) const { - return points[i]; - } - - //clears the polygon points - void Clear(); - - //inits the polygon with numpoints vertices - void Init(long numpoints); - - //creates a triangle with points p1,p2,p3 - void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3); - - //inverts the orfer of vertices - void Invert(); - - //returns the orientation of the polygon - //possible values: - // TPPL_CCW : polygon vertices are in counter-clockwise order - // TPPL_CW : polygon vertices are in clockwise order - // 0 : the polygon has no (measurable) area - int GetOrientation() const; - - //sets the polygon orientation - //orientation can be - // TPPL_CCW : sets vertices in counter-clockwise order - // TPPL_CW : sets vertices in clockwise order - void SetOrientation(int orientation); - - //checks whether a polygon is valid or not - inline bool Valid() const { return this->numpoints >= 3; } -}; - -#ifdef TPPL_ALLOCATOR -typedef std::list TPPLPolyList; -#else -typedef std::list TPPLPolyList; -#endif - -class TPPLPartition { - protected: - struct PartitionVertex { - bool isActive; - bool isConvex; - bool isEar; - - TPPLPoint p; - tppl_float angle; - PartitionVertex *previous; - PartitionVertex *next; - - PartitionVertex(); - }; - - struct MonotoneVertex { - TPPLPoint p; - long previous; - long next; - }; - - class VertexSorter{ - MonotoneVertex *vertices; - public: - VertexSorter(MonotoneVertex *v) : vertices(v) {} - bool operator() (long index1, long index2); - }; - - struct Diagonal { - long index1; - long index2; - }; - -#ifdef TPPL_ALLOCATOR - typedef std::list DiagonalList; -#else - typedef std::list DiagonalList; -#endif - - //dynamic programming state for minimum-weight triangulation - struct DPState { - bool visible; - tppl_float weight; - long bestvertex; - }; - - //dynamic programming state for convex partitioning - struct DPState2 { - bool visible; - long weight; - DiagonalList pairs; - }; - - //edge that intersects the scanline - struct ScanLineEdge { - mutable long index; - TPPLPoint p1; - TPPLPoint p2; - - //determines if the edge is to the left of another edge - bool operator< (const ScanLineEdge & other) const; - - bool IsConvex(const TPPLPoint& p1, const TPPLPoint& p2, const TPPLPoint& p3) const; - }; - - //standard helper functions - bool IsConvex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3); - bool IsReflex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3); - bool IsInside(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3, TPPLPoint &p); - - bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p); - bool InCone(PartitionVertex *v, TPPLPoint &p); - - int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22); - - TPPLPoint Normalize(const TPPLPoint &p); - tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2); - - //helper functions for Triangulate_EC - void UpdateVertexReflexity(PartitionVertex *v); - void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices); - - //helper functions for ConvexPartition_OPT - void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates); - void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); - void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); - - //helper functions for MonotonePartition - bool Below(TPPLPoint &p1, TPPLPoint &p2); - void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, std::set::iterator *edgeTreeIterators, - std::set *edgeTree, long *helpers); - - //triangulates a monotone polygon, used in Triangulate_MONO - int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles); - - public: - - //simple heuristic procedure for removing holes from a list of polygons - //works by creating a diagonal from the rightmost hole vertex to some visible vertex - //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons that can contain holes - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // outpolys : a list of polygons without holes - //returns 1 on success, 0 on failure - int RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys); - - //triangulates a polygon by ear clipping - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles); - - //triangulates a list of polygons that may contain holes by ear clipping algorithm - //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon - //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles); - - //creates an optimal polygon triangulation in terms of minimal edge length - //time complexity: O(n^3), n is the number of vertices - //space complexity: O(n^2) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles); - - //triangulates a polygons by firstly partitioning it into monotone polygons - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles); - - //triangulates a list of polygons by firstly partitioning them into monotone polygons - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles); - - //creates a monotone partition of a list of polygons that can contain holes - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // monotonePolys : a list of monotone polygons (result) - //returns 1 on success, 0 on failure - int MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys); - - //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm - //the algorithm gives at most four times the number of parts as the optimal algorithm - //however, in practice it works much better than that and often gives optimal partition - //uses triangulation obtained by ear clipping as intermediate result - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be partitioned - // vertices have to be in counter-clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts); - - //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm - //the algorithm gives at most four times the number of parts as the optimal algorithm - //however, in practice it works much better than that and often gives optimal partition - //uses triangulation obtained by ear clipping as intermediate result - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : an input list of polygons to be partitioned - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts); - - //optimal convex partitioning (in terms of number of resulting convex polygons) - //using the Keil-Snoeyink algorithm - //M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998 - //time complexity O(n^3), n is the number of vertices - //space complexity: O(n^3) - // poly : an input polygon to be partitioned - // vertices have to be in counter-clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts); -}; - - -#endif diff --git a/src/qhull/src/libqhull_r/geom2_r.c b/src/qhull/src/libqhull_r/geom2_r.c index 48addba1cf..0345440be2 100644 --- a/src/qhull/src/libqhull_r/geom2_r.c +++ b/src/qhull/src/libqhull_r/geom2_r.c @@ -2054,7 +2054,7 @@ pointT *qh_voronoi_center(qhT *qh, int dim, setT *points) { factor= qh_divzero(0.5, det, qh->MINdenom, &infinite); if (infinite) { for (k=dim; k--; ) - center[k]= qh_INFINITE; + center[k]= (float)qh_INFINITE; if (qh->IStracing) qh_printpoints(qh, qh->ferr, "qh_voronoi_center: at infinity for ", simplex); }else { diff --git a/src/slic3r/Config/Snapshot.cpp b/src/slic3r/Config/Snapshot.cpp index 900172d3eb..ecfc32b58f 100644 --- a/src/slic3r/Config/Snapshot.cpp +++ b/src/slic3r/Config/Snapshot.cpp @@ -251,7 +251,7 @@ bool Snapshot::equal_to_active(const AppConfig &app_config) const return false; matched.insert(vc.name); } - for (const std::pair>> &v : app_config.vendors()) + for (const auto &v : app_config.vendors()) if (matched.find(v.first) == matched.end() && ! v.second.empty()) // There are more vendors currently installed than enabled in the snapshot. return false; @@ -402,7 +402,7 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot: snapshot.filaments.emplace_back(app_config.get("presets", name)); } // Vendor specific config bundles and installed printers. - for (const std::pair>> &vendor : app_config.vendors()) { + for (const auto &vendor : app_config.vendors()) { Snapshot::VendorConfig cfg; cfg.name = vendor.first; cfg.models_variants_installed = vendor.second; diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4277aeb364..74b58b052a 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -6,6 +6,7 @@ #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/BoundingBox.hpp" #include "libslic3r/Geometry.hpp" +#include "libslic3r/Tesselate.hpp" #include "GUI_App.hpp" #include "libslic3r/PresetBundle.hpp" @@ -23,59 +24,36 @@ static const float GROUND_Z = -0.02f; namespace Slic3r { namespace GUI { -bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool generate_tex_coords) +bool GeometryBuffer::set_from_triangles(const std::vector &triangles, float z) { - m_vertices.clear(); - unsigned int v_size = 3 * (unsigned int)triangles.size(); - - if (v_size == 0) + if (triangles.empty()) { + m_vertices.clear(); return false; - - m_vertices = std::vector(v_size, Vertex()); - - float min_x = unscale(triangles[0].points[0](0)); - float min_y = unscale(triangles[0].points[0](1)); - float max_x = min_x; - float max_y = min_y; - - unsigned int v_count = 0; - for (const Polygon& t : triangles) { - for (unsigned int i = 0; i < 3; ++i) { - Vertex& v = m_vertices[v_count]; - - const Point& p = t.points[i]; - float x = unscale(p(0)); - float y = unscale(p(1)); - - v.position[0] = x; - v.position[1] = y; - v.position[2] = z; - - if (generate_tex_coords) { - v.tex_coords[0] = x; - v.tex_coords[1] = y; - - min_x = std::min(min_x, x); - max_x = std::max(max_x, x); - min_y = std::min(min_y, y); - max_y = std::max(max_y, y); - } - - ++v_count; - } } - if (generate_tex_coords) { - float size_x = max_x - min_x; - float size_y = max_y - min_y; + assert(triangles.size() % 3 == 0); + m_vertices = std::vector(triangles.size(), Vertex()); - if ((size_x != 0.0f) && (size_y != 0.0f)) { - float inv_size_x = 1.0f / size_x; - float inv_size_y = -1.0f / size_y; - for (Vertex& v : m_vertices) { - v.tex_coords[0] = (v.tex_coords[0] - min_x) * inv_size_x; - v.tex_coords[1] = (v.tex_coords[1] - min_y) * inv_size_y; - } + Vec2f min = triangles.front(); + Vec2f max = min; + + for (size_t v_count = 0; v_count < triangles.size(); ++ v_count) { + const Vec2f &p = triangles[v_count]; + Vertex &v = m_vertices[v_count]; + v.position = Vec3f(p.x(), p.y(), z); + v.tex_coords = p; + min = min.cwiseMin(p).eval(); + max = max.cwiseMax(p).eval(); + } + + Vec2f size = max - min; + if (size.x() != 0.f && size.y() != 0.f) { + Vec2f inv_size = size.cwiseInverse(); + inv_size.y() *= -1; + for (Vertex& v : m_vertices) { + v.tex_coords -= min; + v.tex_coords.x() *= inv_size.x(); + v.tex_coords.y() *= inv_size.y(); } } @@ -290,11 +268,8 @@ void Bed3D::calc_bounding_boxes() const void Bed3D::calc_triangles(const ExPolygon& poly) { - Polygons triangles; - poly.triangulate_p2t(&triangles); - - if (!m_triangles.set_from_triangles(triangles, GROUND_Z, true)) - printf("Unable to create bed triangles\n"); + if (! m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) + BOOST_LOG_TRIVIAL(error) << "Unable to create bed triangles"; } void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) @@ -321,7 +296,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines)); if (!m_gridlines.set_from_lines(gridlines, GROUND_Z)) - printf("Unable to create bed grid lines\n"); + BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n"; } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index b5b063e6f9..6266304bee 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -17,20 +17,14 @@ class GeometryBuffer { struct Vertex { - float position[3]; - float tex_coords[2]; - - Vertex() - { - position[0] = 0.0f; position[1] = 0.0f; position[2] = 0.0f; - tex_coords[0] = 0.0f; tex_coords[1] = 0.0f; - } + Vec3f position = Vec3f::Zero(); + Vec2f tex_coords = Vec2f::Zero(); }; std::vector m_vertices; public: - bool set_from_triangles(const Polygons& triangles, float z, bool generate_tex_coords); + bool set_from_triangles(const std::vector &triangles, float z); bool set_from_lines(const Lines& lines, float z); const float* get_vertices_data() const; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ddfbca4367..3aafc9a3b9 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -34,8 +34,6 @@ #include #include -#include - #include #ifdef HAS_GLSAFE diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 5152260f54..c760b6ad12 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -99,8 +99,6 @@ void CopyrightsDialog::fill_entries() "2002 - 2007, Marcelo E.Magallon; " "2002, Lev Povalahev" , "http://glew.sourceforge.net/" }, { "Libigl" , "2013 Alec Jacobson and others" , "https://libigl.github.io/" }, - { "Poly2Tri" , "2009-2018, Poly2Tri Contributors" , "https://github.com/jhasse/poly2tri" }, - { "PolyPartition" , "2011 Ivan Fratric" , "https://github.com/ivanfratric/polypartition" }, { "Qhull" , "1993-2015 C.B.Barber Arlington and " "University of Minnesota" , "http://qhull.org/" }, { "SemVer" , "2015-2017 Tomas Aparicio" , "https://semver.org/" }, diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 2cc9f84a3d..87a3220232 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -149,9 +149,13 @@ void BackgroundSlicingProcess::process_fff() if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id)); - //FIXME localize the messages - // Perform the final post-processing of the export path by applying the print statistics over the file name. - std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path); + + m_print->set_status(95, _utf8(L("Running post-processing scripts"))); + run_post_process_scripts(m_temp_output_path, m_fff_print->full_print_config()); + + //FIXME localize the messages + // Perform the final post-processing of the export path by applying the print statistics over the file name. + std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path); std::string error_message; int copy_ret_val = CopyFileResult::SUCCESS; try @@ -184,8 +188,7 @@ void BackgroundSlicingProcess::process_fff() BOOST_LOG_TRIVIAL(error) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << "."; break; } - m_print->set_status(95, _utf8(L("Running post-processing scripts"))); - run_post_process_scripts(export_path, m_fff_print->full_print_config()); + m_print->set_status(100, (boost::format(_utf8(L("G-code file exported to %1%"))) % export_path).str()); } else if (! m_upload_job.empty()) { wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id)); diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 7818382331..0a10f47530 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -12,7 +12,6 @@ #include "libslic3r/Model.hpp" #include "libslic3r/Polygon.hpp" -#include "boost/nowide/iostream.hpp" #include #include diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index c553f37289..0a6f3e4f9f 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -338,7 +338,7 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_ } //we make scaled solid bitmaps only for the cases, when its will be used with scaled SVG icon in one output bitmap -wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling/* = false*/) +wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling/* = false*/, size_t border_width /*= 0*/, bool dark_mode/* = false*/) { double scale = suppress_scaling ? 1.0f : m_scale; width *= scale; @@ -354,6 +354,30 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi *imgdata ++ = b; *imgalpha ++ = transparency; } + + // Add border, make white/light spools easier to see + if (border_width > 0) { + + // Restrict to width of image + if (border_width > height) border_width = height - 1; + if (border_width > width) border_width = width - 1; + + auto px_data = (uint8_t*)image.GetData(); + auto a_data = (uint8_t*)image.GetAlpha(); + + for (size_t x = 0; x < width; ++x) { + for (size_t y = 0; y < height; ++y) { + if (x < border_width || y < border_width || + x >= (width - border_width) || y >= (height - border_width)) { + const size_t idx = (x + y * width); + const size_t idx_rgb = (x + y * width) * 3; + px_data[idx_rgb] = px_data[idx_rgb + 1] = px_data[idx_rgb + 2] = dark_mode ? 245u : 110u; + a_data[idx] = 255u; + } + } + } + } + return wxImage_to_wxBitmap_with_alpha(std::move(image), scale); } diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 429b7dfd92..8147de9963 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -35,8 +35,8 @@ public: // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width. wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false); - wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false); - wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling = false) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling); } + wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false); + wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); } wxBitmap mkclear(size_t width, size_t height) { return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); } static bool parse_color(const std::string& scolor, unsigned char* rgb_out); diff --git a/src/slic3r/GUI/BonjourDialog.cpp b/src/slic3r/GUI/BonjourDialog.cpp index 51f18dce72..65d5524c2d 100644 --- a/src/slic3r/GUI/BonjourDialog.cpp +++ b/src/slic3r/GUI/BonjourDialog.cpp @@ -119,7 +119,7 @@ bool BonjourDialog::show_and_lookup() // Note: More can be done here when we support discovery of hosts other than Octoprint and SL1 Bonjour::TxtKeys txt_keys { "version", "model" }; - bonjour = std::move(Bonjour("octoprint") + bonjour = Bonjour("octoprint") .set_txt_keys(std::move(txt_keys)) .set_retries(3) .set_timeout(4) @@ -139,8 +139,7 @@ bool BonjourDialog::show_and_lookup() wxQueueEvent(dialog, evt); } }) - .lookup() - ); + .lookup(); bool res = ShowModal() == wxID_OK && list->GetFirstSelected() >= 0; { diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 1e589f1a15..ade1d40437 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -10,15 +10,6 @@ #include -// phi / theta angles to orient the camera. -static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f }; -static const float VIEW_LEFT[2] = { 90.0f, 90.0f }; -static const float VIEW_RIGHT[2] = { -90.0f, 90.0f }; -static const float VIEW_TOP[2] = { 0.0f, 0.0f }; -static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; -static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; -static const float VIEW_REAR[2] = { 180.0f, 90.0f }; - namespace Slic3r { namespace GUI { diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index aba26b2031..309dc57288 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -267,7 +267,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) for (auto el : { "skirt_distance", "draft_shield", "min_skirt_length" }) toggle_field(el, have_skirt); - bool have_brim = config->opt_float("brim_width") > 0; + bool have_brim = config->opt_enum("brim_type") != btNoBrim; + for (auto el : { "brim_width", "brim_offset" }) + toggle_field(el, have_brim); // perimeter_extruder uses the same logic as in Print::extruders() toggle_field("perimeter_extruder", have_perimeters || have_brim); @@ -292,6 +294,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) toggle_field("support_material_extruder", have_support_material || have_skirt); toggle_field("support_material_speed", have_support_material || have_brim || have_skirt); + toggle_field("raft_contact_distance", have_raft && !have_support_soluble); + toggle_field("raft_expansion", have_raft); + bool has_ironing = config->opt_bool("ironing"); for (auto el : { "ironing_type", "ironing_flowrate", "ironing_spacing", "ironing_speed" }) toggle_field(el, has_ironing); diff --git a/src/slic3r/GUI/ConfigSnapshotDialog.cpp b/src/slic3r/GUI/ConfigSnapshotDialog.cpp index 487604b1c0..9f996d378b 100644 --- a/src/slic3r/GUI/ConfigSnapshotDialog.cpp +++ b/src/slic3r/GUI/ConfigSnapshotDialog.cpp @@ -68,7 +68,7 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve if (vc.version.max_slic3r_version != Semver::inf()) text += ", " + _(L("max PrusaSlicer version")) + ": " + vc.version.max_slic3r_version.to_string(); text += "
"; - for (const std::pair> &model : vc.models_variants_installed) { + for (const auto& model : vc.models_variants_installed) { text += _(L("model")) + ": " + model.first + ", " + _(L("variants")) + ": "; for (const std::string &variant : model.second) { if (&variant != &*model.second.begin()) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 568c15a165..59908bd806 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -304,21 +304,28 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt } title_sizer->AddStretchSpacer(); - if (/*titles.size() > 1*/is_variants) { + if (titles.size() > 1 || is_variants) { // It only makes sense to add the All / None buttons if there's multiple printers - + // All Standard button is added when there are more variants for at least one printer auto *sel_all_std = new wxButton(this, wxID_ANY, titles.size() > 1 ? _L("All standard") : _L("Standard")); auto *sel_all = new wxButton(this, wxID_ANY, _L("All")); auto *sel_none = new wxButton(this, wxID_ANY, _L("None")); - sel_all_std->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, false); }); + if (is_variants) + sel_all_std->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& event) { this->select_all(true, false); }); sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, true); }); sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); }); - title_sizer->Add(sel_all_std, 0, wxRIGHT, BTN_SPACING); + if (is_variants) + title_sizer->Add(sel_all_std, 0, wxRIGHT, BTN_SPACING); title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING); title_sizer->Add(sel_none); // fill button indexes used later for buttons rescaling - m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() }; + if (is_variants) + m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() }; + else { + sel_all_std->Destroy(); + m_button_indexes = { sel_all->GetId(), sel_none->GetId() }; + } } sizer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, BTN_SPACING); @@ -1494,6 +1501,7 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) sizer->AddStretchSpacer(); sizer->Add(logo); SetSizer(sizer); + logo_height = logo->GetBitmap().GetHeight(); Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this); Bind(wxEVT_MOTION, &ConfigWizardIndex::on_mouse_move, this); @@ -1610,15 +1618,15 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) { const auto size = GetClientSize(); if (size.GetHeight() == 0 || size.GetWidth() == 0) { return; } - + wxPaintDC dc(this); - + const auto bullet_w = bullet_black.bmp().GetSize().GetWidth(); const auto bullet_h = bullet_black.bmp().GetSize().GetHeight(); const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0; const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0; const int yinc = item_height(); - + int index_width = 0; unsigned y = 0; @@ -1646,6 +1654,11 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) Refresh(); }); } + + if ((int)y + logo_height > size.GetHeight()) + logo->Hide(); + else + logo->Show(); } void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt) @@ -1872,7 +1885,7 @@ void ConfigWizard::priv::load_vendors() std::map section_new; if (app_config->has_section(section_name)) { const std::map §ion_old = app_config->get_section(section_name); - for (const std::pair &material_name_and_installed : section_old) + for (const auto& material_name_and_installed : section_old) if (material_name_and_installed.second == "1") { // Material is installed. Resolve it in bundles. size_t num_found = 0; @@ -2248,7 +2261,7 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo if ((only_for_model_id.empty() || only_for_model_id == printer_model->id) && printer_models_without_material.find(printer_model) == printer_models_without_material.end()) { bool has_material = false; - for (const std::pair &preset : appconfig_presets) { + for (const auto& preset : appconfig_presets) { if (preset.second == "1") { const Preset *material = materials.find_preset(preset.first, false); if (material != nullptr && is_compatible_with_printer(PresetWithVendorProfile(*material, nullptr), PresetWithVendorProfile(printer, nullptr))) { diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index 62ec6b18b2..d9c0e2dc15 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -518,6 +518,8 @@ private: ssize_t item_hover; size_t last_page; + int logo_height; + int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; } void on_paint(wxPaintEvent &evt); diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 1e4eed1e8c..57ad4cc9c7 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -646,8 +646,16 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer if (value >= m_values.size()) return "ErrVal"; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (m_draw_mode == dmSequentialGCodeView) { + return (Slic3r::GUI::get_app_config()->get("seq_top_gcode_indices") == "1") ? + wxString::Format("%lu", static_cast(m_alternate_values[value])) : + wxString::Format("%lu", static_cast(m_values[value])); + } +#else if (m_draw_mode == dmSequentialGCodeView) return wxString::Format("%lu", static_cast(m_values[value])); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER else { if (label_type == ltEstimatedTime) { return (value < m_layers_times.size()) ? short_and_splitted_time(get_time_dhms(m_layers_times[value])) : ""; @@ -1550,9 +1558,8 @@ void Control::move_current_thumb(const bool condition) if (accelerator > 0) delta *= accelerator; -#if ENABLE_ARROW_KEYS_WITH_SLIDERS - if (m_selection == ssUndef) m_selection = ssHigher; -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS + if (m_selection == ssUndef) + m_selection = ssHigher; if (m_selection == ssLower) { m_lower_value -= delta; @@ -1614,26 +1621,17 @@ void Control::OnKeyDown(wxKeyEvent &event) if (key == WXK_LEFT || key == WXK_RIGHT) move_current_thumb(key == WXK_LEFT); else if (key == WXK_UP || key == WXK_DOWN) { -#if ENABLE_ARROW_KEYS_WITH_SLIDERS if (key == WXK_DOWN) m_selection = ssHigher; else if (key == WXK_UP && is_lower_thumb_editable()) m_selection = ssLower; -#else - if (key == WXK_UP) - m_selection = ssHigher; - else if (key == WXK_DOWN && is_lower_thumb_editable()) - m_selection = ssLower; -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS Refresh(); } } -#if ENABLE_ARROW_KEYS_WITH_SLIDERS else { if (key == WXK_LEFT || key == WXK_RIGHT) move_current_thumb(key == WXK_LEFT); } -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS } else { if (m_is_focused) { @@ -1647,12 +1645,10 @@ void Control::OnKeyDown(wxKeyEvent &event) else if (key == WXK_UP || key == WXK_DOWN) move_current_thumb(key == WXK_UP); } -#if ENABLE_ARROW_KEYS_WITH_SLIDERS else { if (key == WXK_UP || key == WXK_DOWN) move_current_thumb(key == WXK_UP); } -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS } event.Skip(); // !Needed to have EVT_CHAR generated as well @@ -1889,7 +1885,7 @@ void Control::show_cog_icon_context_menu() []() { return true; }, [this]() { return m_extra_style & wxSL_VALUE_LABEL; }, GUI::wxGetApp().plater()); append_submenu(&menu, ruler_mode_menu, wxID_ANY, _L("Ruler mode"), _L("Set ruler mode"), "", - [this]() { return true; }, this); + []() { return true; }, this); } if (m_mode == MultiAsSingle && m_draw_mode == dmRegular) diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index 0d90367c0a..ae12fb4c6e 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -215,6 +215,9 @@ public: void SetKoefForLabels(const double koef) { m_label_koef = koef; } void SetSliderValues(const std::vector& values); void ChangeOneLayerLock(); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + void SetSliderAlternateValues(const std::vector& values) { m_alternate_values = values; } +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER Info GetTicksValues() const; void SetTicksValues(const Info &custom_gcode_per_print_z); @@ -383,14 +386,17 @@ private: int m_cog_icon_dim; long m_style; long m_extra_style; - float m_label_koef = 1.0; + float m_label_koef{ 1.0 }; std::vector m_values; TickCodeInfo m_ticks; std::vector m_layers_times; - std::vector m_extruder_colors; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + std::vector m_alternate_values; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + // control's view variables wxCoord SLIDER_MARGIN; // margin around slider diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index fc8b25efad..02847c40de 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -16,6 +16,7 @@ #include #include #include "OG_CustomCtrl.hpp" +#include "MsgDialog.hpp" #ifdef __WXOSX__ #define wxOSX true @@ -92,8 +93,8 @@ void Field::PostInitialize() { case coPercents: case coFloats: - case coStrings: - case coBools: + case coStrings: + case coBools: case coInts: { auto tag_pos = m_opt_id.find("#"); if (tag_pos != std::string::npos) @@ -111,7 +112,7 @@ void Field::PostInitialize() BUILD(); // For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected. - // So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed + // So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed if (getWindow()) getWindow()->Bind(wxEVT_KEY_UP, [](wxKeyEvent& evt) { if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) { @@ -135,7 +136,7 @@ void Field::PostInitialize() // tab panel should be focused for correct navigation between tabs wxGetApp().tab_panel()->SetFocus(); } - + evt.Skip(); }); } @@ -148,7 +149,7 @@ int Field::def_width_thinner() { return 4; } void Field::on_kill_focus() { // call the registered function if it is available - if (m_on_kill_focus!=nullptr) + if (m_on_kill_focus!=nullptr) m_on_kill_focus(m_opt_id); } @@ -157,7 +158,7 @@ void Field::on_set_focus(wxEvent& event) // to allow the default behavior event.Skip(); // call the registered function if it is available - if (m_on_set_focus!=nullptr) + if (m_on_set_focus!=nullptr) m_on_set_focus(m_opt_id); } @@ -196,7 +197,7 @@ wxString Field::get_tooltip_text(const wxString& default_string) if (tooltip.length() > 0) tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " + (boost::iends_with(opt_id, "_gcode") ? "\n" : "") + default_string + - (boost::iends_with(opt_id, "_gcode") ? "" : "\n") + + (boost::iends_with(opt_id, "_gcode") ? "" : "\n") + _(L("parameter name")) + "\t: " + opt_id; return tooltip_text; @@ -220,7 +221,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true case coPercents: case coFloats: case coFloat:{ - if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%') + if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%') str.RemoveLast(); else if (!str.IsEmpty() && str.Last() == '%') { @@ -263,7 +264,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true if (m_value.empty() || boost::any_cast(m_value) != val) { wxString msg_text = format_wxstr(_L("Input value is out of range\n" "Are you sure that %s is a correct value and that you want to continue?"), str); - wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO); +// wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO); + WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO); if (dialog.ShowModal() == wxID_NO) { if (m_value.empty()) { if (m_opt.min > val) val = m_opt.min; @@ -323,7 +325,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n" "Select YES if you want to change this value to %s%%, \n" "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str()); - wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO); +// wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO); + WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO); if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) { set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/); str += "%%"; @@ -332,7 +335,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "." } } - + m_value = std::string(str.ToUTF8().data()); break; } @@ -359,8 +362,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true out_of_range_val = true; break; } - } - } + } + } invalid_val = true; break; } @@ -370,8 +373,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true if (!m_value.empty()) text_value = get_thumbnails_string(boost::any_cast>(m_value)); set_value(text_value, true); - show_error(m_parent, _L("Input value is out of range") - ); + show_error(m_parent, _L("Input value is out of range")); } else if (invalid_val) { wxString text_value; @@ -413,7 +415,7 @@ void TextCtrl::BUILD() { if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); - wxString text_value = wxString(""); + wxString text_value = wxString(""); switch (m_opt.type) { case coFloatOrPercent: @@ -428,21 +430,21 @@ void TextCtrl::BUILD() { text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat())); text_value += "%"; break; - } + } case coPercents: case coFloats: case coFloat: { double val = m_opt.type == coFloats ? m_opt.get_default_value()->get_at(m_opt_idx) : - m_opt.type == coFloat ? + m_opt.type == coFloat ? m_opt.default_value->getFloat() : m_opt.get_default_value()->get_at(m_opt_idx); text_value = double_to_string(val); m_last_meaningful_value = text_value; break; } - case coString: + case coString: text_value = m_opt.get_default_value()->value; break; case coStrings: @@ -456,7 +458,7 @@ void TextCtrl::BUILD() { text_value = get_thumbnails_string(m_opt.get_default_value()->values); break; default: - break; + break; } const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; @@ -490,7 +492,7 @@ void TextCtrl::BUILD() { } temp->Bind(wxEVT_SET_FOCUS, ([this](wxEvent& e) { on_set_focus(e); }), temp->GetId()); - + temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event) { //! to allow the default handling @@ -508,7 +510,7 @@ void TextCtrl::BUILD() { { e.Skip(); #ifdef __WXOSX__ - // OSX issue: For some unknown reason wxEVT_KILL_FOCUS is emitted twice in a row in some cases + // OSX issue: For some unknown reason wxEVT_KILL_FOCUS is emitted twice in a row in some cases // (like when information dialog is shown during an update of the option value) // Thus, suppress its second call if (bKilledFocus) @@ -539,7 +541,7 @@ void TextCtrl::BUILD() { */ // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); -} +} bool TextCtrl::value_was_changed() { @@ -559,7 +561,7 @@ bool TextCtrl::value_was_changed() case coPercents: case coFloats: case coFloat: { - if (m_opt.nullable && std::isnan(boost::any_cast(m_value)) && + if (m_opt.nullable && std::isnan(boost::any_cast(m_value)) && std::isnan(boost::any_cast(val))) return false; return boost::any_cast(m_value) != boost::any_cast(val); @@ -597,9 +599,9 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) if (!change_event) { wxString ret_str = static_cast(window)->GetValue(); - /* Update m_value to correct work of next value_was_changed(). - * But after checking of entered value, don't fix the "incorrect" value and don't show a warning message, - * just clear m_value in this case. + /* Update m_value to correct work of next value_was_changed(). + * But after checking of entered value, don't fix the "incorrect" value and don't show a warning message, + * just clear m_value in this case. */ get_value_by_opt_type(ret_str, false); } @@ -631,7 +633,7 @@ void TextCtrl::msw_rescale() Field::msw_rescale(); auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord); - if (m_opt.height >= 0) + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); else if (parent_is_custom_ctrl && opt_height > 0) size.SetHeight(lround(opt_height*m_em_unit)); @@ -665,15 +667,15 @@ void CheckBox::BUILD() { if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); - bool check_value = m_opt.type == coBool ? - m_opt.default_value->getBool() : m_opt.type == coBools ? - m_opt.get_default_value()->get_at(m_opt_idx) : + bool check_value = m_opt.type == coBool ? + m_opt.default_value->getBool() : m_opt.type == coBools ? + m_opt.get_default_value()->get_at(m_opt_idx) : false; m_last_meaningful_value = static_cast(check_value); - // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox - auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size); + // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox + auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); @@ -684,7 +686,7 @@ void CheckBox::BUILD() { on_change_field(); }), temp->GetId()); - temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false")); + temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false")); // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -770,14 +772,14 @@ void SpinCtrl::BUILD() { break; } - const int min_val = m_opt.min == INT_MIN + const int min_val = m_opt.min == INT_MIN #ifdef __WXOSX__ - // We will forcibly set the input value for SpinControl, since the value + // We will forcibly set the input value for SpinControl, since the value // inserted from the keyboard is not updated under OSX. // So, we can't set min control value bigger then 0. - // Otherwise, it couldn't be possible to input from keyboard value + // Otherwise, it couldn't be possible to input from keyboard value // less then min_val. - || m_opt.min > 0 + || m_opt.min > 0 #endif ? 0 : m_opt.min; const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647; @@ -813,8 +815,8 @@ void SpinCtrl::BUILD() { propagate_value(); })); - temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId()); - + temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId()); + temp->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) { e.Skip(); @@ -835,7 +837,7 @@ void SpinCtrl::BUILD() { tmp_value = parsed && value >= INT_MIN && value <= INT_MAX ? (int)value : UNDEF_VALUE; #ifdef __WXOSX__ - // Forcibly set the input value for SpinControl, since the value + // Forcibly set the input value for SpinControl, since the value // inserted from the keyboard or clipboard is not updated under OSX if (tmp_value != UNDEF_VALUE) { wxSpinCtrl* spin = static_cast(window); @@ -847,7 +849,7 @@ void SpinCtrl::BUILD() { } #endif }), temp->GetId()); - + temp->SetToolTip(get_tooltip_text(text_value)); // recast as a wxWindow to fit the calling convention @@ -899,7 +901,7 @@ void Choice::BUILD() { if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); - choice_ctrl* temp; + choice_ctrl* temp; if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { m_is_editable = true; temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); @@ -1051,10 +1053,10 @@ void Choice::set_value(const std::string& value, bool change_event) //! Redunda } choice_ctrl* field = dynamic_cast(window); - idx == m_opt.enum_values.size() ? + idx == m_opt.enum_values.size() ? field->SetValue(value) : field->SetSelection(idx); - + m_disable_change_event = false; } @@ -1072,7 +1074,7 @@ void Choice::set_value(const boost::any& value, bool change_event) case coString: case coStrings: { wxString text_value; - if (m_opt.type == coInt) + if (m_opt.type == coInt) text_value = wxString::Format(_T("%i"), int(boost::any_cast(value))); else text_value = boost::any_cast(value); @@ -1100,7 +1102,7 @@ void Choice::set_value(const boost::any& value, bool change_event) { if (!m_opt.enum_values.empty()) { std::string key; - t_config_enum_values map_names = ConfigOptionEnum::get_enum_values(); + t_config_enum_values map_names = ConfigOptionEnum::get_enum_values(); for (auto it : map_names) { if (val == it.second) { key = it.first; @@ -1175,7 +1177,7 @@ boost::any& Choice::get_value() { choice_ctrl* field = dynamic_cast(window); - wxString ret_str = field->GetValue(); + wxString ret_str = field->GetValue(); // options from right panel std::vector right_panel_options{ "support", "pad", "scale_unit" }; @@ -1185,7 +1187,7 @@ boost::any& Choice::get_value() if (m_opt.type == coEnum) { - int ret_enum = field->GetSelection(); + int ret_enum = field->GetSelection(); if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern") { if (!m_opt.enum_values.empty()) { @@ -1200,10 +1202,8 @@ boost::any& Choice::get_value() } else if (m_opt_id.compare("ironing_type") == 0) m_value = static_cast(ret_enum); - else if (m_opt_id.compare("fuzzy_skin_perimeter_mode") == 0) - m_value = static_cast(ret_enum); -// else if (m_opt_id.compare("fuzzy_skin_shape") == 0) -// m_value = static_cast(ret_enum); + else if (m_opt_id.compare("fuzzy_skin") == 0) + m_value = static_cast(ret_enum); else if (m_opt_id.compare("gcode_flavor") == 0) m_value = static_cast(ret_enum); else if (m_opt_id.compare("machine_limits_usage") == 0) @@ -1220,6 +1220,8 @@ boost::any& Choice::get_value() m_value = static_cast(ret_enum); else if (m_opt_id == "printhost_authorization_type") m_value = static_cast(ret_enum); + else if (m_opt_id == "brim_type") + m_value = static_cast(ret_enum); } else if (m_opt.gui_type == "f_enum_open") { const int ret_enum = field->GetSelection(); @@ -1232,7 +1234,7 @@ boost::any& Choice::get_value() else m_value = atof(m_opt.enum_values[ret_enum].c_str()); } - else + else // modifies ret_string! get_value_by_opt_type(ret_str); @@ -1250,8 +1252,8 @@ void Choice::msw_rescale() #ifdef __WXOSX__ const wxString selection = field->GetValue();// field->GetString(index); - /* To correct scaling (set new controll size) of a wxBitmapCombobox - * we need to refill control with new bitmaps. So, in our case : + /* To correct scaling (set new controll size) of a wxBitmapCombobox + * we need to refill control with new bitmaps. So, in our case : * 1. clear control * 2. add content * 3. add scaled "empty" bitmap to the at least one item @@ -1259,7 +1261,7 @@ void Choice::msw_rescale() field->Clear(); wxSize size(wxDefaultSize); size.SetWidth((m_opt.width > 0 ? m_opt.width : def_width_wider()) * m_em_unit); - + // Set rescaled min height to correct layout field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y + 0.5f))); // Set rescaled size @@ -1371,7 +1373,7 @@ void ColourPicker::msw_rescale() wxColourPickerCtrl* field = dynamic_cast(window); auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord); - if (m_opt.height >= 0) + if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit); else if (parent_is_custom_ctrl && opt_height > 0) size.SetHeight(lround(opt_height * m_em_unit)); @@ -1507,7 +1509,7 @@ boost::any& PointCtrl::get_value() else if (m_opt.min > x || x > m_opt.max || m_opt.min > y || y > m_opt.max) - { + { if (m_opt.min > x) x = m_opt.min; if (x > m_opt.max) x = m_opt.max; if (m_opt.min > y) y = m_opt.min; @@ -1573,7 +1575,7 @@ void SliderCtrl::BUILD() m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT); wxSize field_size(40, -1); - m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), + m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), wxDefaultPosition, field_size); m_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); @@ -1623,5 +1625,3 @@ boost::any& SliderCtrl::get_value() } // GUI } // Slic3r - - diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 5b01c92c95..1b35032412 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -113,8 +113,8 @@ public: void field_changed() { on_change_field(); } - Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {}; - Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {}; + Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {} + Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {} virtual ~Field(); /// If you don't know what you are getting back, check both methods for nullptr. @@ -315,12 +315,12 @@ public: /// Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER void propagate_value() ; - void set_value(const std::string& value, bool change_event = false) { + void set_value(const std::string& value, bool change_event = false) { m_disable_change_event = !change_event; dynamic_cast(window)->SetValue(value); m_disable_change_event = false; - } - void set_value(const boost::any& value, bool change_event = false) { + } + void set_value(const boost::any& value, bool change_event = false) override { m_disable_change_event = !change_event; tmp_value = boost::any_cast(value); m_value = value; @@ -395,8 +395,8 @@ public: boost::any& get_value() override; void msw_rescale() override; - void enable() override { dynamic_cast(window)->Enable(); }; - void disable() override{ dynamic_cast(window)->Disable(); }; + void enable() override { dynamic_cast(window)->Enable(); } + void disable() override{ dynamic_cast(window)->Disable(); } wxWindow* getWindow() override { return window; } }; @@ -456,8 +456,8 @@ public: void msw_rescale() override; - void enable() override { dynamic_cast(window)->Enable(); }; - void disable() override{ dynamic_cast(window)->Disable(); }; + void enable() override { dynamic_cast(window)->Enable(); } + void disable() override{ dynamic_cast(window)->Disable(); } wxWindow* getWindow() override { return window; } }; diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 879e7fe34e..15f0551328 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -648,7 +648,12 @@ void FirmwareDialog::priv::perform_upload() } } }) - .on_message(std::move([q, extra_verbose](const char *msg, unsigned /* size */) { + .on_message([ +#ifndef __APPLE__ + // clang complains when capturing constants. + extra_verbose, +#endif // __APPLE__ + q](const char* msg, unsigned /* size */) { if (extra_verbose) { BOOST_LOG_TRIVIAL(debug) << "avrdude: " << msg; } @@ -665,19 +670,19 @@ void FirmwareDialog::priv::perform_upload() evt->SetExtraLong(AE_MESSAGE); evt->SetString(std::move(wxmsg)); wxQueueEvent(q, evt); - })) - .on_progress(std::move([q](const char * /* task */, unsigned progress) { + }) + .on_progress([q](const char * /* task */, unsigned progress) { auto evt = new wxCommandEvent(EVT_AVRDUDE, q->GetId()); evt->SetExtraLong(AE_PROGRESS); evt->SetInt(progress); wxQueueEvent(q, evt); - })) - .on_complete(std::move([this]() { + }) + .on_complete([this]() { auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId()); evt->SetExtraLong(AE_EXIT); evt->SetInt(this->avrdude->exit_code()); wxQueueEvent(this->q, evt); - })) + }) .run(); } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8fac137333..71441e037c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -127,11 +127,9 @@ void GCodeViewer::IBuffer::reset() bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const { -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE auto matches_percent = [](float value1, float value2, float max_percent) { return std::abs(value2 - value1) / value1 <= max_percent; }; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE switch (move.type) { @@ -144,29 +142,15 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const case EMoveType::Extrude: { // use rounding to reduce the number of generated paths #if ENABLE_SPLITTED_VERTEX_BUFFER -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && move.position[2] <= sub_paths.front().first.position[2] && feedrate == move.feedrate && fan_speed == move.fan_speed && height == round_to_nearest(move.height, 2) && width == round_to_nearest(move.width, 2) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); #else - return type == move.type && move.position[2] <= sub_paths.front().position[2] && role == move.extrusion_role && height == round_to_nearest(move.height, 2) && - width == round_to_nearest(move.width, 2) && feedrate == move.feedrate && fan_speed == move.fan_speed && - volumetric_rate == round_to_nearest(move.volumetric_rate(), 2) && extruder_id == move.extruder_id && - cp_color_id == move.cp_color_id; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE -#else -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && move.position[2] <= first.position[2] && feedrate == move.feedrate && fan_speed == move.fan_speed && height == round_to_nearest(move.height, 2) && width == round_to_nearest(move.width, 2) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); -#else - return type == move.type && move.position[2] <= first.position[2] && role == move.extrusion_role && height == round_to_nearest(move.height, 2) && - width == round_to_nearest(move.width, 2) && feedrate == move.feedrate && fan_speed == move.fan_speed && - volumetric_rate == round_to_nearest(move.volumetric_rate(), 2) && extruder_id == move.extruder_id && - cp_color_id == move.cp_color_id; -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_SPLITTED_VERTEX_BUFFER } case EMoveType::Travel: { @@ -195,25 +179,13 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsi Path::Endpoint endpoint = { b_id, i_id, s_id, move.position }; // use rounding to reduce the number of generated paths #if ENABLE_SPLITTED_VERTEX_BUFFER -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); #else - paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, - round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, - round_to_nearest(move.volumetric_rate(), 2), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE -#else -#if ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); -#else - paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, - round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, - round_to_nearest(move.volumetric_rate(), 2), move.extruder_id, move.cp_color_id }); -#endif // ENABLE_TOOLPATHS_WIDTH_HEIGHT_FROM_GCODE #endif // ENABLE_SPLITTED_VERTEX_BUFFER } @@ -240,6 +212,23 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con return ret; } +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS +GCodeViewer::SequentialRangeCap::~SequentialRangeCap() { + if (ibo > 0) + glsafe(::glDeleteBuffers(1, &ibo)); +} + +void GCodeViewer::SequentialRangeCap::reset() { + if (ibo > 0) + glsafe(::glDeleteBuffers(1, &ibo)); + + buffer = nullptr; + ibo = 0; + vbo = 0; + color = { 0.0f, 0.0f, 0.0f }; +} +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); @@ -522,21 +511,14 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: #endif // ENABLE_GCODE_VIEWER_STATISTICS // update buffers' render paths -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE refresh_render_paths(); -#else - refresh_render_paths(false, false); -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE - log_memory_used("Refreshed G-code extrusion paths, "); } -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void GCodeViewer::refresh_render_paths() { refresh_render_paths(false, false); } -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void GCodeViewer::update_shells_color_by_extruder(const DynamicPrintConfig* config) { @@ -574,7 +556,7 @@ void GCodeViewer::render() const auto init_gl_data = [this]() { // initializes opengl data of TBuffers for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& buffer = m_buffers[i]; + TBuffer& buffer = const_cast(m_buffers[i]); switch (buffer_type(i)) { default: { break; } @@ -600,17 +582,17 @@ void GCodeViewer::render() const } // initializes tool marker - m_sequential_view.marker.init(); + const_cast(&m_sequential_view)->marker.init(); // initializes point sizes std::array point_sizes; ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data()); - m_detected_point_sizes = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; - m_gl_data_initialized = true; + *const_cast*>(&m_detected_point_sizes) = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; + *const_cast(&m_gl_data_initialized) = true; }; #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.reset_opengl(); + const_cast(&m_statistics)->reset_opengl(); #endif // ENABLE_GCODE_VIEWER_STATISTICS // OpenGL data must be initialized after the glContext has been created. @@ -623,9 +605,10 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); - if (m_sequential_view.current.last != m_sequential_view.endpoints.last) { - m_sequential_view.marker.set_world_position(m_sequential_view.current_position); - m_sequential_view.marker.render(); + SequentialView* sequential_view = const_cast(&m_sequential_view); + if (sequential_view->current.last != sequential_view->endpoints.last) { + sequential_view->marker.set_world_position(sequential_view->current_position); + sequential_view->marker.render(); } render_shells(); render_legend(); @@ -870,7 +853,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const if (render_path.color != color) continue; - const IBuffer& ibuffer = t_buffer.indices[render_path.index_buffer_id]; + const IBuffer& ibuffer = t_buffer.indices[render_path.ibuffer_id]; size_t vertices_offset = 0; for (size_t j = 0; j < vertices_offsets.size(); ++j) { const VerticesOffset& offset = vertices_offsets[j]; @@ -975,7 +958,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const size_t i = 0; for (const RenderPath& render_path : t_buffer.render_paths) { // get paths segments from buffer paths - const IndexBuffer& ibuffer = indices[render_path.index_buffer_id]; + const IndexBuffer& ibuffer = indices[render_path.ibuffer_id]; const Path& path = t_buffer.paths[render_path.path_id]; float half_width = 0.5f * path.width; @@ -1279,8 +1262,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) last_path.sub_paths.back().last = { vbuffer_id, vertices.size(), move_id, curr.position }; }; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + auto add_indices_as_solid = [&](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, const GCodeProcessor::MoveVertex* next, + TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { +#else auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS static Vec3f prev_dir; static Vec3f prev_up; static float sq_prev_length; @@ -1293,7 +1281,40 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) store_triangle(indices, id, id, id); store_triangle(indices, id, id, id); }; - auto store_main_triangles = [&](IndexBuffer& indices, size_t vbuffer_size, const std::array& v_offsets) { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + auto convert_vertices_offset = [](size_t vbuffer_size, const std::array& v_offsets) { + std::array ret = { + static_cast(static_cast(vbuffer_size) + v_offsets[0]), + static_cast(static_cast(vbuffer_size) + v_offsets[1]), + static_cast(static_cast(vbuffer_size) + v_offsets[2]), + static_cast(static_cast(vbuffer_size) + v_offsets[3]), + static_cast(static_cast(vbuffer_size) + v_offsets[4]), + static_cast(static_cast(vbuffer_size) + v_offsets[5]), + static_cast(static_cast(vbuffer_size) + v_offsets[6]), + static_cast(static_cast(vbuffer_size) + v_offsets[7]) + }; + return ret; + }; + auto append_starting_cap_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { + store_triangle(indices, v_offsets[0], v_offsets[2], v_offsets[1]); + store_triangle(indices, v_offsets[0], v_offsets[3], v_offsets[2]); + }; + auto append_stem_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { + store_triangle(indices, v_offsets[0], v_offsets[1], v_offsets[4]); + store_triangle(indices, v_offsets[1], v_offsets[5], v_offsets[4]); + store_triangle(indices, v_offsets[1], v_offsets[2], v_offsets[5]); + store_triangle(indices, v_offsets[2], v_offsets[6], v_offsets[5]); + store_triangle(indices, v_offsets[2], v_offsets[3], v_offsets[6]); + store_triangle(indices, v_offsets[3], v_offsets[7], v_offsets[6]); + store_triangle(indices, v_offsets[3], v_offsets[0], v_offsets[7]); + store_triangle(indices, v_offsets[0], v_offsets[4], v_offsets[7]); + }; + auto append_ending_cap_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { + store_triangle(indices, v_offsets[4], v_offsets[6], v_offsets[7]); + store_triangle(indices, v_offsets[4], v_offsets[5], v_offsets[6]); + }; +#else + auto append_stem_triangles = [&](IndexBuffer& indices, size_t vbuffer_size, const std::array& v_offsets) { std::array v_ids; for (size_t i = 0; i < v_ids.size(); ++i) { v_ids[i] = static_cast(static_cast(vbuffer_size) + v_offsets[i]); @@ -1317,6 +1338,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) store_triangle(indices, v_ids[4], v_ids[6], v_ids[7]); store_triangle(indices, v_ids[4], v_ids[5], v_ids[6]); }; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); @@ -1330,14 +1352,28 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) Vec3f up = right.cross(dir); float sq_length = (curr.position - prev.position).squaredNorm(); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + const std::array first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); + const std::array non_first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (last_path.vertices_count() == 1 || vbuffer_size == 0) { // 1st segment or restart into a new vertex buffer // =============================================== +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (last_path.vertices_count() == 1) + // starting cap triangles + append_starting_cap_triangles(indices, first_seg_v_offsets); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS // dummy triangles outer corner cap append_dummy_cap(indices, vbuffer_size); // stem triangles - store_main_triangles(indices, vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + append_stem_triangles(indices, first_seg_v_offsets); +#else + append_stem_triangles(indices, vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS vbuffer_size += 8; } @@ -1391,11 +1427,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } // stem triangles - store_main_triangles(indices, vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + append_stem_triangles(indices, non_first_seg_v_offsets); +#else + append_stem_triangles(indices, vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS vbuffer_size += 6; } +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (next != nullptr && (curr.type != next->type || !last_path.matches(*next))) + // ending cap triangles + append_ending_cap_triangles(indices, non_first_seg_v_offsets); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; prev_dir = dir; prev_up = up; @@ -1412,6 +1458,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (m_moves_count == 0) return; + m_extruders_count = gcode_result.extruders_count; + unsigned int progress_count = 0; static const unsigned int progress_threshold = 1000; wxProgressDialog* progress_dialog = wxGetApp().is_gcode_viewer() ? @@ -1435,6 +1483,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_max_bounding_box = m_paths_bounding_box; m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_sequential_view.gcode_ids.clear(); + for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { + m_sequential_view.gcode_ids.push_back(move.gcode_id); + } +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); std::vector options_zs; @@ -1635,6 +1690,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } }; +#if ENABLE_GCODE_VIEWER_STATISTICS + auto load_vertices_time = std::chrono::high_resolution_clock::now(); + m_statistics.load_vertices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + // smooth toolpaths corners for TBuffers using triangles for (size_t i = 0; i < m_buffers.size(); ++i) { const TBuffer& t_buffer = m_buffers[i]; @@ -1684,6 +1744,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_GCODE_VIEWER_STATISTICS + auto smooth_vertices_time = std::chrono::high_resolution_clock::now(); + m_statistics.smooth_vertices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - load_vertices_time).count(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS log_memory_usage("Loaded G-code generated vertex buffers ", vertices, indices); // dismiss vertices data, no more needed @@ -1712,6 +1776,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) continue; const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + const GCodeProcessor::MoveVertex* next = nullptr; + if (i < m_moves_count - 1) + next = &gcode_result.moves[i + 1]; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS ++progress_count; if (progress_dialog != nullptr && progress_count % progress_threshold == 0) { @@ -1735,7 +1804,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // if adding the indices for the current segment exceeds the threshold size of the current index buffer // create another index buffer +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - t_buffer.max_indices_per_segment_size_bytes()) { +#else if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - t_buffer.indices_per_segment_size_bytes()) { +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS i_multibuffer.push_back(IndexBuffer()); vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) { @@ -1774,7 +1847,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) break; } case TBuffer::ERenderPrimitiveType::Triangle: { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, i); +#else add_indices_as_solid(prev, curr, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, i); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS break; } } @@ -1826,14 +1903,28 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) auto update_segments_count = [&](EMoveType type, int64_t& count) { unsigned int id = buffer_id(type); const MultiIndexBuffer& buffers = indices[id]; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + int64_t indices_count = 0; + for (const IndexBuffer& buffer : buffers) { + indices_count += buffer.size(); + } + const TBuffer& t_buffer = m_buffers[id]; + if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) + indices_count -= static_cast(12 * t_buffer.paths.size()); // remove the starting + ending caps = 4 triangles + + count += indices_count / t_buffer.indices_per_segment(); +#else for (const IndexBuffer& buffer : buffers) { count += buffer.size() / m_buffers[id].indices_per_segment(); } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS }; update_segments_count(EMoveType::Travel, m_statistics.travel_segments_count); update_segments_count(EMoveType::Wipe, m_statistics.wipe_segments_count); update_segments_count(EMoveType::Extrude, m_statistics.extrude_segments_count); + + m_statistics.load_indices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - smooth_vertices_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS log_memory_usage("Loaded G-code generated indices buffers ", vertices, indices); @@ -1956,8 +2047,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) vertices.push_back(curr.position[2]); }; auto add_indices_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - unsigned int index_buffer_id, IndexBuffer& indices, size_t move_id) { - buffer.add_path(curr, index_buffer_id, indices.size(), move_id); + unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { + buffer.add_path(curr, ibuffer_id, indices.size(), move_id); indices.push_back(static_cast(indices.size())); }; @@ -1982,11 +2073,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) add_vertex(curr); }; auto add_indices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - unsigned int index_buffer_id, IndexBuffer& indices, size_t move_id) { + unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { // add starting index indices.push_back(static_cast(indices.size())); - buffer.add_path(curr, index_buffer_id, indices.size() - 1, move_id - 1); + buffer.add_path(curr, ibuffer_id, indices.size() - 1, move_id - 1); buffer.paths.back().first.position = prev.position; } @@ -1998,7 +2089,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // add current index indices.push_back(static_cast(indices.size())); - last_path.last = { index_buffer_id, indices.size() - 1, move_id, curr.position }; + last_path.last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; }; // format data into the buffers to be rendered as solid @@ -2148,7 +2239,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) prev_length = length; }; auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - size_t& buffer_vertices_size, unsigned int index_buffer_id, IndexBuffer& indices, size_t move_id) { + size_t& buffer_vertices_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { static Vec3f prev_dir; static Vec3f prev_up; static float prev_length; @@ -2163,7 +2254,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) }; if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, index_buffer_id, indices.size(), move_id - 1); + buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); buffer.paths.back().first.position = prev.position; } @@ -2276,7 +2367,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer_vertices_size += 6; } - last_path.last = { index_buffer_id, indices.size() - 1, move_id, curr.position }; + last_path.last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; prev_dir = dir; prev_up = up; prev_length = length; @@ -2654,7 +2745,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool return color; }; - auto travel_color = [this](const Path& path) { + auto travel_color = [](const Path& path) { return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : Travel_Colors[0] /* Move */); @@ -2669,14 +2760,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool }; auto is_travel_in_layers_range = [this](size_t path_id, size_t min_id, size_t max_id) { - // auto is_in_z_range = [](const Path& path, double min_z, double max_z) { - // auto in_z_range = [min_z, max_z](double z) { - // return min_z - EPSILON < z && z < max_z + EPSILON; - // }; - // - // return in_z_range(path.sub_paths.front().first.position[2]) || in_z_range(path.sub_paths.back().last.position[2]); - // }; - const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Travel)]; if (path_id >= buffer.paths.size()) return false; @@ -2703,19 +2786,26 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool }; #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.render_paths_size = 0; + Statistics* statistics = const_cast(&m_statistics); + statistics->render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; SequentialView::Endpoints global_endpoints = { m_moves_count , 0 }; SequentialView::Endpoints top_layer_endpoints = global_endpoints; - if (top_layer_only || !keep_sequential_current_first) m_sequential_view.current.first = 0; - if (!keep_sequential_current_last) m_sequential_view.current.last = m_moves_count; + SequentialView* sequential_view = const_cast(&m_sequential_view); + if (top_layer_only || !keep_sequential_current_first) sequential_view->current.first = 0; + if (!keep_sequential_current_last) sequential_view->current.last = m_moves_count; // first pass: collect visible paths and update sequential view data +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + std::vector> paths; +#else std::vector> paths; - for (TBuffer& buffer : m_buffers) { +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + for (size_t b = 0; b < m_buffers.size(); ++b) { + TBuffer& buffer = const_cast(m_buffers[b]); // reset render paths buffer.render_paths.clear(); @@ -2736,7 +2826,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // store valid path for (size_t j = 0; j < path.sub_paths.size(); ++j) { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + paths.push_back({ static_cast(b), path.sub_paths[j].first.b_id, static_cast(i), static_cast(j) }); +#else paths.push_back({ &buffer, path.sub_paths[j].first.b_id, static_cast(i), static_cast(j) }); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } global_endpoints.first = std::min(global_endpoints.first, path.sub_paths.front().first.s_id); @@ -2758,8 +2852,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } // update current sequential position - m_sequential_view.current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; - m_sequential_view.current.last = keep_sequential_current_last ? std::clamp(m_sequential_view.current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; + sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; + sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; // get the world position from gpu bool found = false; @@ -2776,7 +2870,13 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool offset = 2 * offset - 1; else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { unsigned int indices_count = buffer.indices_per_segment(); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + offset = indices_count * (offset - 1) + (indices_count - 2); + if (sub_path_id == 0) + offset += 6; // add 2 triangles for starting cap +#else offset = indices_count * (offset - 1) + (indices_count - 6); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } } offset += static_cast(sub_path.first.i_id); @@ -2790,7 +2890,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // gets the position from the vertices buffer on gpu glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); found = true; @@ -2805,8 +2905,14 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // second pass: filter paths by sequential data and collect them by color RenderPath* render_path = nullptr; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + for (const auto& [tbuffer_id, ibuffer_id, path_id, sub_path_id] : paths) { + TBuffer& buffer = const_cast(m_buffers[tbuffer_id]); + const Path& path = buffer.paths[path_id]; +#else for (const auto& [buffer, ibuffer_id, path_id, sub_path_id] : paths) { const Path& path = buffer->paths[path_id]; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; if (m_sequential_view.current.last <= sub_path.first.s_id || sub_path.last.s_id <= m_sequential_view.current.first) continue; @@ -2839,42 +2945,92 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool break; } case EMoveType::Wipe: { color = Wipe_Color; break; } - default: { color = { 0.0f, 0.0f, 0.0f }; break; } + default: { color = { 0.0f, 0.0f, 0.0f }; break; } } +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + RenderPath key{ tbuffer_id, color, static_cast(ibuffer_id), path_id }; + if (render_path == nullptr || !RenderPathPropertyEqual()(*render_path, key)) + render_path = const_cast(&(*buffer.render_paths.emplace(key).first)); + + unsigned int delta_1st = 0; + if (sub_path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= sub_path.last.s_id) + delta_1st = static_cast(m_sequential_view.current.first - sub_path.first.s_id); +#else RenderPath key{ color, static_cast(ibuffer_id), path_id }; if (render_path == nullptr || !RenderPathPropertyEqual()(*render_path, key)) render_path = const_cast(&(*buffer->render_paths.emplace(key).first)); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS unsigned int size_in_indices = 0; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + switch (buffer.render_primitive_type) +#else switch (buffer->render_primitive_type) +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS { case TBuffer::ERenderPrimitiveType::Point: { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + size_in_indices = buffer.indices_per_segment(); +#else size_in_indices = buffer->indices_per_segment(); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS break; } case TBuffer::ERenderPrimitiveType::Line: case TBuffer::ERenderPrimitiveType::Triangle: { unsigned int segments_count = std::min(m_sequential_view.current.last, sub_path.last.s_id) - std::max(m_sequential_view.current.first, sub_path.first.s_id); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + size_in_indices = buffer.indices_per_segment() * segments_count; +#else size_in_indices = buffer->indices_per_segment() * segments_count; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS break; } } + +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (size_in_indices == 0) + continue; + + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { + if (sub_path_id == 0 && delta_1st == 0) + size_in_indices += 6; // add 2 triangles for starting cap + if (sub_path_id == path.sub_paths.size() - 1 && path.sub_paths.back().last.s_id <= m_sequential_view.current.last) + size_in_indices += 6; // add 2 triangles for ending cap + if (delta_1st > 0) + size_in_indices -= 6; // remove 2 triangles for corner cap + } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + render_path->sizes.push_back(size_in_indices); +#if !ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS unsigned int delta_1st = 0; if (sub_path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= sub_path.last.s_id) delta_1st = m_sequential_view.current.first - sub_path.first.s_id; +#endif // !ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { + delta_1st *= buffer.indices_per_segment(); + if (delta_1st > 0) { + delta_1st += 6; // skip 2 triangles for corner cap + if (sub_path_id == 0) + delta_1st += 6; // skip 2 triangles for starting cap + } + } +#else if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) delta_1st *= buffer->indices_per_segment(); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS render_path->offsets.push_back(static_cast((sub_path.first.i_id + delta_1st) * sizeof(IBufferType))); #if 0 // check sizes and offsets against index buffer size on gpu GLint buffer_size; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->indices[render_path->index_buffer_id].ibo)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->indices[render_path->ibuffer_id].ibo)); glsafe(::glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &buffer_size)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); if (render_path->offsets.back() + render_path->sizes.back() * sizeof(IBufferType) > buffer_size) @@ -2883,20 +3039,133 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } // set sequential data to their final value - m_sequential_view.endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; - m_sequential_view.current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.first; + sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; + sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; + +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + // updates sequential range caps + std::array* sequential_range_caps = const_cast*>(&m_sequential_range_caps); + (*sequential_range_caps)[0].reset(); + (*sequential_range_caps)[1].reset(); + + if (m_sequential_view.current.first != m_sequential_view.current.last) { + for (const auto& [tbuffer_id, ibuffer_id, path_id, sub_path_id] : paths) { + TBuffer& buffer = const_cast(m_buffers[tbuffer_id]); + if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Triangle) + continue; + + const Path& path = buffer.paths[path_id]; + const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; + if (m_sequential_view.current.last <= sub_path.first.s_id || sub_path.last.s_id <= m_sequential_view.current.first) + continue; + + // update cap for first endpoint of current range + if (m_sequential_view.current.first > sub_path.first.s_id) { + SequentialRangeCap& cap = (*sequential_range_caps)[0]; + const IBuffer& i_buffer = buffer.indices[ibuffer_id]; + cap.buffer = &buffer; + cap.vbo = i_buffer.vbo; + + // calculate offset into the index buffer + unsigned int offset = sub_path.first.i_id; + offset += 6; // add 2 triangles for corner cap + offset += static_cast(m_sequential_view.current.first - sub_path.first.s_id) * buffer.indices_per_segment(); + if (sub_path_id == 0) + offset += 6; // add 2 triangles for starting cap + + // extract indices from index buffer + std::array indices{ 0, 0, 0, 0, 0, 0 }; + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 0) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 7) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 1) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 13) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[4]))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + indices[3] = indices[0]; + indices[5] = indices[1]; + + // send indices to gpu + glsafe(::glGenBuffers(1, &cap.ibo)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(IBufferType), indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + // extract color from render path + size_t offset_bytes = offset * sizeof(IBufferType); + for (const RenderPath& render_path : buffer.render_paths) { + if (render_path.ibuffer_id == ibuffer_id) { + for (size_t j = 0; j < render_path.offsets.size(); ++j) { + if (render_path.contains(offset_bytes)) { + cap.color = render_path.color; + break; + } + } + } + } + } + + // update cap for last endpoint of current range + if (m_sequential_view.current.last < sub_path.last.s_id) { + SequentialRangeCap& cap = (*sequential_range_caps)[1]; + const IBuffer& i_buffer = buffer.indices[ibuffer_id]; + cap.buffer = &buffer; + cap.vbo = i_buffer.vbo; + + // calculate offset into the index buffer + unsigned int offset = sub_path.first.i_id; + offset += 6; // add 2 triangles for corner cap + offset += static_cast(m_sequential_view.current.last - 1 - sub_path.first.s_id) * buffer.indices_per_segment(); + if (sub_path_id == 0) + offset += 6; // add 2 triangles for starting cap + + // extract indices from index buffer + std::array indices{ 0, 0, 0, 0, 0, 0 }; + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 2) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 4) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 10) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 16) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[5]))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + indices[3] = indices[0]; + indices[4] = indices[2]; + + // send indices to gpu + glsafe(::glGenBuffers(1, &cap.ibo)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(IBufferType), indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + // extract color from render path + size_t offset_bytes = offset * sizeof(IBufferType); + for (const RenderPath& render_path : buffer.render_paths) { + if (render_path.ibuffer_id == ibuffer_id) { + for (size_t j = 0; j < render_path.offsets.size(); ++j) { + if (render_path.contains(offset_bytes)) { + cap.color = render_path.color; + break; + } + } + } + } + } + + if ((*sequential_range_caps)[0].is_renderable() && (*sequential_range_caps)[1].is_renderable()) + break; + } + } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS wxGetApp().plater()->enable_preview_moves_slider(!paths.empty()); #if ENABLE_GCODE_VIEWER_STATISTICS for (const TBuffer& buffer : m_buffers) { - m_statistics.render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); + statistics->render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); for (const RenderPath& path : buffer.render_paths) { - m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); - m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); + statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); + statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } } - m_statistics.refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); + statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } #else @@ -2984,19 +3253,22 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool }; #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.render_paths_size = 0; + Statistics* statistics = const_cast(&m_statistics); + statistics->render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; SequentialView::Endpoints global_endpoints = { m_moves_count , 0 }; SequentialView::Endpoints top_layer_endpoints = global_endpoints; - if (top_layer_only || !keep_sequential_current_first) m_sequential_view.current.first = 0; - if (!keep_sequential_current_last) m_sequential_view.current.last = m_moves_count; + SequentialView* sequential_view = const_cast(&m_sequential_view); + if (top_layer_only || !keep_sequential_current_first) sequential_view->current.first = 0; + if (!keep_sequential_current_last) sequential_view->current.last = m_moves_count; // first pass: collect visible paths and update sequential view data std::vector> paths; - for (TBuffer& buffer : m_buffers) { + for (size_t b = 0; b < m_buffers.size(); ++b) { + TBuffer& buffer = const_cast(m_buffers[b]); // reset render paths buffer.render_paths.clear(); @@ -3037,8 +3309,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } // update current sequential position - m_sequential_view.current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; - m_sequential_view.current.last = keep_sequential_current_last ? std::clamp(m_sequential_view.current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; + sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; + sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; // get the world position from gpu bool found = false; @@ -3065,7 +3337,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // gets the position from the vertices buffer on gpu glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); found = true; break; @@ -3077,7 +3349,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // second pass: filter paths by sequential data and collect them by color RenderPath *render_path = nullptr; - for (const auto& [buffer, index_buffer_id, path_id] : paths) { + for (const auto& [buffer, ibuffer_id, path_id] : paths) { const Path& path = buffer->paths[path_id]; if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first) continue; @@ -3107,7 +3379,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool default: { color = { 0.0f, 0.0f, 0.0f }; break; } } - RenderPath key{ color, static_cast(index_buffer_id), path_id }; + RenderPath key{ color, static_cast(ibuffer_id), path_id }; if (render_path == nullptr || ! RenderPathPropertyEqual()(*render_path, key)) render_path = const_cast(&(*buffer->render_paths.emplace(key).first)); unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; @@ -3131,20 +3403,20 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } // set sequential data to their final value - m_sequential_view.endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; - m_sequential_view.current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.first; + sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; + sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; wxGetApp().plater()->enable_preview_moves_slider(!paths.empty()); #if ENABLE_GCODE_VIEWER_STATISTICS for (const TBuffer& buffer : m_buffers) { - m_statistics.render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); + statistics->render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); for (const RenderPath& path : buffer.render_paths) { - m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); - m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); + statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); + statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } } - m_statistics.refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); + statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } #endif // ENABLE_SPLITTED_VERTEX_BUFFER @@ -3169,7 +3441,7 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("uniform_color", color4); }; - auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color] + auto render_as_points = [zoom, point_size, near_plane_height, set_uniform_color] (const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS shader.set_uniform("use_fixed_screen_size", 1); @@ -3186,11 +3458,11 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == ibuffer_id) { + if (path.ibuffer_id == ibuffer_id) { set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; + ++const_cast(&m_statistics)->gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -3199,26 +3471,26 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { + auto render_as_lines = [light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { shader.set_uniform("light_intensity", light_intensity); for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == ibuffer_id) { + if (path.ibuffer_id == ibuffer_id) { set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_lines_calls_count; + ++const_cast(&m_statistics)->gl_multi_lines_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } }; - auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { + auto render_as_triangles = [set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == ibuffer_id) { + if (path.ibuffer_id == ibuffer_id) { set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_triangles_calls_count; + ++const_cast(&m_statistics)->gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -3284,6 +3556,47 @@ void GCodeViewer::render_toolpaths() const shader->stop_using(); } } + +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + auto render_sequential_range_cap = [set_uniform_color](const SequentialRangeCap& cap) { + GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str()); + if (shader != nullptr) { + shader->start_using(); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); + glsafe(::glVertexPointer(cap.buffer->vertices.position_size_floats(), GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.position_offset_size())); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + bool has_normals = cap.buffer->vertices.normal_size_floats() > 0; + if (has_normals) { + glsafe(::glNormalPointer(GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.normal_offset_size())); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + } + + set_uniform_color(cap.color, *shader); + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); + glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)cap.indices_count(), GL_UNSIGNED_SHORT, nullptr)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++const_cast(&m_statistics)->gl_triangles_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + + if (has_normals) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + shader->stop_using(); + } + }; + + for (unsigned int i = 0; i < 2; ++i) { + if (m_sequential_range_caps[i].is_renderable()) + render_sequential_range_cap(m_sequential_range_caps[i]); + } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } #else void GCodeViewer::render_toolpaths() const @@ -3306,7 +3619,7 @@ void GCodeViewer::render_toolpaths() const }; auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color] - (const TBuffer& buffer, unsigned int index_buffer_id, EOptionsColors color_id, GLShaderProgram& shader) { + (const TBuffer& buffer, unsigned int ibuffer_id, EOptionsColors color_id, GLShaderProgram& shader) { set_uniform_color(Options_Colors[static_cast(color_id)], shader); #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS shader.set_uniform("use_fixed_screen_size", 1); @@ -3323,10 +3636,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == index_buffer_id) { + if (path.ibuffer_id == ibuffer_id) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; + ++const_cast(&m_statistics)->gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -3335,26 +3648,26 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int index_buffer_id, GLShaderProgram& shader) { + auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { shader.set_uniform("light_intensity", light_intensity); for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == index_buffer_id) { + if (path.ibuffer_id == ibuffer_id) { set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_lines_calls_count; + ++const_cast(&m_statistics)->gl_multi_lines_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } }; - auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, unsigned int index_buffer_id, GLShaderProgram& shader) { + auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { for (const RenderPath& path : buffer.render_paths) { - if (path.index_buffer_id == index_buffer_id) { + if (path.ibuffer_id == ibuffer_id) { set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_triangles_calls_count; + ++const_cast(&m_statistics)->gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -3566,8 +3879,8 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); }; - auto append_range = [this, draw_list, &imgui, append_item](const Extrusions::Range& range, unsigned int decimals) { - auto append_range_item = [this, draw_list, &imgui, append_item](int i, float value, unsigned int decimals) { + auto append_range = [append_item](const Extrusions::Range& range, unsigned int decimals) { + auto append_range_item = [append_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); append_item(EItemType::Rect, Range_Colors[i], buf); @@ -3661,7 +3974,7 @@ void GCodeViewer::render_legend() const return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); }; - auto role_time_and_percent = [this, time_mode](ExtrusionRole role) { + auto role_time_and_percent = [ time_mode](ExtrusionRole role) { auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f); }; @@ -3719,7 +4032,8 @@ void GCodeViewer::render_legend() const bool visible = is_visible(role); append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], visible, times[i], percents[i], max_percent, offsets, [this, role, visible]() { - m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); + Extrusions* extrusions = const_cast(&m_extrusions); + extrusions->role_visibility_flags = visible ? extrusions->role_visibility_flags & ~(1 << role) : extrusions->role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); wxGetApp().plater()->update_preview_moves_slider(); @@ -3767,8 +4081,7 @@ void GCodeViewer::render_legend() const } } } - else // multi extruder use case - { + else { // multi extruder use case // shows only extruders actually used for (unsigned char i : m_extruder_ids) { std::vector>> cp_values = color_print_ranges(i, custom_gcode_per_print_z); @@ -3868,7 +4181,7 @@ void GCodeViewer::render_legend() const return items; }; - auto append_color_change = [this, &imgui](const Color& color1, const Color& color2, const std::array& offsets, const Times& times) { + auto append_color_change = [&imgui](const Color& color1, const Color& color2, const std::array& offsets, const Times& times) { imgui.text(_u8L("Color change")); ImGui::SameLine(); @@ -3887,7 +4200,7 @@ void GCodeViewer::render_legend() const imgui.text(short_time(get_time_dhms(times.second - times.first))); }; - auto append_print = [this, &imgui](const Color& color, const std::array& offsets, const Times& times) { + auto append_print = [&imgui](const Color& color, const std::array& offsets, const Times& times) { imgui.text(_u8L("Print")); ImGui::SameLine(); @@ -4116,7 +4429,7 @@ void GCodeViewer::render_legend() const } if (show && m_time_statistics.modes[static_cast(mode)].roles_times.size() > 0) { if (imgui.button(label)) { - m_time_estimate_mode = mode; + *const_cast(&m_time_estimate_mode) = mode; wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); } @@ -4196,6 +4509,9 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); add_time(std::string("Load:"), m_statistics.load_time); + add_time(std::string(" Load vertices:"), m_statistics.load_vertices); + add_time(std::string(" Smooth vertices:"), m_statistics.smooth_vertices); + add_time(std::string(" Load indices:"), m_statistics.load_indices); add_time(std::string("Refresh:"), m_statistics.refresh_time); add_time(std::string("Refresh paths:"), m_statistics.refresh_paths_time); } @@ -4204,6 +4520,9 @@ void GCodeViewer::render_statistics() const add_counter(std::string("Multi GL_POINTS:"), m_statistics.gl_multi_points_calls_count); add_counter(std::string("Multi GL_LINES:"), m_statistics.gl_multi_lines_calls_count); add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } if (ImGui::CollapsingHeader("CPU memory")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a4663dc04c..290c13d51d 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -218,35 +218,59 @@ class GCodeViewer // Used to batch the indices needed to render the paths struct RenderPath { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + // Index of the parent tbuffer + unsigned char tbuffer_id; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS // Render path property Color color; // Index of the buffer in TBuffer::indices - unsigned int index_buffer_id; + unsigned int ibuffer_id; // Render path content + // Index of the path in TBuffer::paths unsigned int path_id; std::vector sizes; - std::vector offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements()) - }; - struct RenderPathPropertyHash { - size_t operator() (const RenderPath &p) const { - // Conver the RGB value to an integer hash. -// return (size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) * 7919) ^ size_t(p.index_buffer_id); - return size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) ^ size_t(p.index_buffer_id); + std::vector offsets; // use size_t because we need an unsigned integer whose size matches pointer's size (used in the call glMultiDrawElements()) +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + bool contains(size_t offset) const { + for (size_t i = 0; i < offsets.size(); ++i) { + if (offsets[i] <= offset && offset <= offsets[i] + static_cast(sizes[i] * sizeof(IBufferType))) + return true; + } + return false; } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS }; +// // for unordered_set implementation of render_paths +// struct RenderPathPropertyHash { +// size_t operator() (const RenderPath &p) const { +// // Convert the RGB value to an integer hash. +//// return (size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) * 7919) ^ size_t(p.ibuffer_id); +// return size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) ^ size_t(p.ibuffer_id); +// } +// }; struct RenderPathPropertyLower { bool operator() (const RenderPath &l, const RenderPath &r) const { - for (int i = 0; i < 3; ++ i) +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + if (l.tbuffer_id < r.tbuffer_id) + return true; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + for (int i = 0; i < 3; ++i) { if (l.color[i] < r.color[i]) return true; else if (l.color[i] > r.color[i]) return false; - return l.index_buffer_id < r.index_buffer_id; + } + return l.ibuffer_id < r.ibuffer_id; } }; struct RenderPathPropertyEqual { bool operator() (const RenderPath &l, const RenderPath &r) const { - return l.color == r.color && l.index_buffer_id == r.index_buffer_id; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + return l.tbuffer_id == r.tbuffer_id && l.ibuffer_id == r.ibuffer_id && l.color == r.color; +#else + return l.color == r.color && l.ibuffer_id == r.ibuffer_id; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } }; @@ -297,29 +321,46 @@ class GCodeViewer { case ERenderPrimitiveType::Point: { return 1; } case ERenderPrimitiveType::Line: { return 2; } +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + case ERenderPrimitiveType::Triangle: { return 30; } // 3 indices x 10 triangles +#else case ERenderPrimitiveType::Triangle: { return 42; } // 3 indices x 14 triangles +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS default: { return 0; } } } #if ENABLE_SPLITTED_VERTEX_BUFFER size_t indices_per_segment_size_bytes() const { return static_cast(indices_per_segment() * sizeof(IBufferType)); } #endif // ENABLE_SPLITTED_VERTEX_BUFFER - unsigned int start_segment_vertex_offset() const { return 0; } - unsigned int end_segment_vertex_offset() const { +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + unsigned int max_indices_per_segment() const { switch (render_primitive_type) { - case ERenderPrimitiveType::Point: { return 0; } - case ERenderPrimitiveType::Line: { return 1; } - case ERenderPrimitiveType::Triangle: { return 36; } // 1st vertex of 13th triangle + case ERenderPrimitiveType::Point: { return 1; } + case ERenderPrimitiveType::Line: { return 2; } + case ERenderPrimitiveType::Triangle: { return 36; } // 3 indices x 12 triangles default: { return 0; } } } + size_t max_indices_per_segment_size_bytes() const { return max_indices_per_segment() * sizeof(IBufferType); } +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS #if ENABLE_SPLITTED_VERTEX_BUFFER bool has_data() const { return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } #else + unsigned int start_segment_vertex_offset() const { return 0; } + unsigned int end_segment_vertex_offset() const { + switch (render_primitive_type) + { + case ERenderPrimitiveType::Point: { return 0; } + case ERenderPrimitiveType::Line: { return 1; } + case ERenderPrimitiveType::Triangle: { return 36; } // 1st vertex of 13th triangle + default: { return 0; } + } + } + bool has_data() const { return vertices.id != 0 && !indices.empty() && indices.front().id != 0; } #endif // ENABLE_SPLITTED_VERTEX_BUFFER }; @@ -439,18 +480,41 @@ class GCodeViewer #endif // ENABLE_SPLITTED_VERTEX_BUFFER }; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + // used to render the toolpath caps of the current sequential range + // (i.e. when sliding on the horizontal slider) + struct SequentialRangeCap + { + TBuffer* buffer{ nullptr }; + unsigned int ibo{ 0 }; + unsigned int vbo{ 0 }; + Color color; + + ~SequentialRangeCap(); + bool is_renderable() const { return buffer != nullptr; } + void reset(); + size_t indices_count() const { return 6; } + }; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics { // time int64_t results_time{ 0 }; int64_t load_time{ 0 }; + int64_t load_vertices{ 0 }; + int64_t smooth_vertices{ 0 }; + int64_t load_indices{ 0 }; int64_t refresh_time{ 0 }; int64_t refresh_paths_time{ 0 }; // opengl calls int64_t gl_multi_points_calls_count{ 0 }; int64_t gl_multi_lines_calls_count{ 0 }; int64_t gl_multi_triangles_calls_count{ 0 }; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + int64_t gl_triangles_calls_count{ 0 }; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS // memory int64_t results_size{ 0 }; int64_t total_vertices_gpu_size{ 0 }; @@ -476,6 +540,9 @@ class GCodeViewer void reset_times() { results_time = 0; load_time = 0; + load_vertices = 0; + smooth_vertices = 0; + load_indices = 0; refresh_time = 0; refresh_paths_time = 0; } @@ -484,6 +551,9 @@ class GCodeViewer gl_multi_points_calls_count = 0; gl_multi_lines_calls_count = 0; gl_multi_triangles_calls_count = 0; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + gl_triangles_calls_count = 0; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } void reset_sizes() { @@ -544,6 +614,9 @@ public: Endpoints last_current; Vec3f current_position{ Vec3f::Zero() }; Marker marker; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + std::vector gcode_ids; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER }; enum class EViewType : unsigned char @@ -560,10 +633,10 @@ public: }; private: - mutable bool m_gl_data_initialized{ false }; + bool m_gl_data_initialized{ false }; unsigned int m_last_result_id{ 0 }; size_t m_moves_count{ 0 }; - mutable std::vector m_buffers{ static_cast(EMoveType::Extrude) }; + std::vector m_buffers{ static_cast(EMoveType::Extrude) }; // bounding box of toolpaths BoundingBoxf3 m_paths_bounding_box; // bounding box of toolpaths + marker tools @@ -574,18 +647,21 @@ private: std::vector m_roles; size_t m_extruders_count; std::vector m_extruder_ids; - mutable Extrusions m_extrusions; - mutable SequentialView m_sequential_view; + Extrusions m_extrusions; + SequentialView m_sequential_view; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; PrintEstimatedTimeStatistics m_time_statistics; - mutable PrintEstimatedTimeStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedTimeStatistics::ETimeMode::Normal }; + PrintEstimatedTimeStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedTimeStatistics::ETimeMode::Normal }; #if ENABLE_GCODE_VIEWER_STATISTICS - mutable Statistics m_statistics; + Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS - mutable std::array m_detected_point_sizes = { 0.0f, 0.0f }; + std::array m_detected_point_sizes = { 0.0f, 0.0f }; GCodeProcessor::Result::SettingsIds m_settings_ids; +#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS + std::array m_sequential_range_caps; +#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS public: GCodeViewer(); @@ -595,9 +671,7 @@ public: void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); // recalculate ranges in dependence of what is visible and sets tool/print colors void refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void refresh_render_paths(); -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void update_shells_color_by_extruder(const DynamicPrintConfig* config); void reset(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6332a7837e..0aec25404c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2,7 +2,6 @@ #include "GLCanvas3D.hpp" #include "admesh/stl.h" -#include "polypartition.h" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" @@ -68,20 +67,20 @@ #include -static const float TRACKBALLSIZE = 0.8f; +static constexpr const float TRACKBALLSIZE = 0.8f; -static const float DEFAULT_BG_DARK_COLOR[3] = { 0.478f, 0.478f, 0.478f }; -static const float DEFAULT_BG_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f }; -static const float ERROR_BG_DARK_COLOR[3] = { 0.478f, 0.192f, 0.039f }; -static const float ERROR_BG_LIGHT_COLOR[3] = { 0.753f, 0.192f, 0.039f }; -//static const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; +static constexpr const float DEFAULT_BG_DARK_COLOR[3] = { 0.478f, 0.478f, 0.478f }; +static constexpr const float DEFAULT_BG_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f }; +static constexpr const float ERROR_BG_DARK_COLOR[3] = { 0.478f, 0.192f, 0.039f }; +static constexpr const float ERROR_BG_LIGHT_COLOR[3] = { 0.753f, 0.192f, 0.039f }; +//static constexpr const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; // Number of floats -static const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB +static constexpr const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB // Reserve size in number of floats. -static const size_t VERTEX_BUFFER_RESERVE_SIZE = 131072 * 2; // 1.05MB +static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE = 131072 * 2; // 1.05MB // Reserve size in number of floats, maximum sum of all preallocated buffers. -static const size_t VERTEX_BUFFER_RESERVE_SIZE_SUM_MAX = 1024 * 1024 * 128 / 4; // 128MB +//static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE_SUM_MAX = 1024 * 1024 * 128 / 4; // 128MB namespace Slic3r { namespace GUI { @@ -612,6 +611,7 @@ GLCanvas3D::Mouse::Mouse() { } +#if !ENABLE_WARNING_TEXTURE_REMOVAL const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 120, 120, 120 };//{ 9, 91, 134 }; const unsigned char GLCanvas3D::WarningTexture::Opacity = 255; @@ -631,12 +631,12 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool std::string text; bool error = false; switch (warning) { - case ObjectOutside: text = L("An object outside the print area was detected."); break; - case ToolpathOutside: text = L("A toolpath outside the print area was detected."); error = true; break; - case SlaSupportsOutside: text = L("SLA supports outside the print area were detected."); error = true; break; - case SomethingNotShown: text = L("Some objects are not visible."); break; + case ObjectOutside: text = _u8L("An object outside the print area was detected."); break; + case ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = true; break; + case SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = true; break; + case SomethingNotShown: text = _u8L("Some objects are not visible."); break; case ObjectClashed: - text = L( "An object outside the print area was detected.\n" + text = _u8L( "An object outside the print area was detected.\n" "Resolve the current problem to continue slicing."); error = true; break; @@ -880,6 +880,7 @@ void GLCanvas3D::WarningTexture::msw_rescale(const GLCanvas3D& canvas) generate(m_msg_text, canvas, true, m_is_colored_red); } +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL void GLCanvas3D::Labels::render(const std::vector& sorted_instances) const { @@ -1086,11 +1087,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); -#if ENABLE_ARROW_KEYS_WITH_SLIDERS wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_SLIDERS, wxKeyEvent); -#else -wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent); -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); @@ -1181,7 +1178,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) #endif // ENABLE_RENDER_PICKING_PASS , m_render_sla_auxiliaries(true) , m_labels(*this) - , m_slope(*this, m_volumes) + , m_slope(m_volumes) { if (m_canvas != nullptr) { m_timer.SetOwner(m_canvas); @@ -1303,7 +1300,11 @@ void GLCanvas3D::reset_volumes() m_volumes.clear(); m_dirty = true; +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification(EWarning::ObjectOutside, false); +#else _set_warning_texture(WarningTexture::ObjectOutside, false); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL } int GLCanvas3D::check_volumes_outside_state() const @@ -1357,11 +1358,19 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject if (visible && !mo) toggle_sla_auxiliaries_visibility(true, mo, instance_idx); +#if ENABLE_WARNING_TEXTURE_REMOVAL + if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1)) + _set_warning_notification(EWarning::SomethingNotShown, true); + + if (!mo && visible) + _set_warning_notification(EWarning::SomethingNotShown, false); +#else if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1)) _set_warning_texture(WarningTexture::SomethingNotShown, true); if (!mo && visible) _set_warning_texture(WarningTexture::SomethingNotShown, false); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL } void GLCanvas3D::update_instance_printable_state_for_object(const size_t obj_idx) @@ -2237,18 +2246,31 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re const bool contained_min_one = m_volumes.check_outside_state(m_config, &state); +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification(EWarning::ObjectClashed, state == ModelInstancePVS_Partly_Outside); + _set_warning_notification(EWarning::ObjectOutside, state == ModelInstancePVS_Fully_Outside); + if (printer_technology != ptSLA || state == ModelInstancePVS_Inside) + _set_warning_notification(EWarning::SlaSupportsOutside, false); +#else _set_warning_texture(WarningTexture::ObjectClashed, state == ModelInstancePVS_Partly_Outside); _set_warning_texture(WarningTexture::ObjectOutside, state == ModelInstancePVS_Fully_Outside); if(printer_technology != ptSLA || state == ModelInstancePVS_Inside) _set_warning_texture(WarningTexture::SlaSupportsOutside, false); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, contained_min_one && !m_model->objects.empty() && state != ModelInstancePVS_Partly_Outside)); } else { +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification(EWarning::ObjectOutside, false); + _set_warning_notification(EWarning::ObjectClashed, false); + _set_warning_notification(EWarning::SlaSupportsOutside, false); +#else _set_warning_texture(WarningTexture::ObjectOutside, false); _set_warning_texture(WarningTexture::ObjectClashed, false); _set_warning_texture(WarningTexture::SlaSupportsOutside, false); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); } @@ -2291,7 +2313,11 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) if (wxGetApp().is_editor()) { m_gcode_viewer.update_shells_color_by_extruder(m_config); +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification_if_needed(EWarning::ToolpathOutside); +#else _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL } } @@ -2302,14 +2328,12 @@ void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_resul request_extra_frame(); } -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void GLCanvas3D::refresh_gcode_preview_render_paths() { m_gcode_viewer.refresh_render_paths(); set_as_dirty(); request_extra_frame(); } -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void GLCanvas3D::load_sla_preview() { @@ -2320,7 +2344,11 @@ void GLCanvas3D::load_sla_preview() this->reset_volumes(); _load_sla_shells(); _update_sla_shells_outside_state(); +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification_if_needed(EWarning::SlaSupportsOutside); +#else _show_warning_texture_if_needed(WarningTexture::SlaSupportsOutside); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL } } @@ -2341,7 +2369,11 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c _load_print_object_toolpaths(*object, str_tool_colors, color_print_values); _update_toolpath_volumes_outside_state(); +#if ENABLE_WARNING_TEXTURE_REMOVAL + _set_warning_notification_if_needed(EWarning::ToolpathOutside); +#else _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL } void GLCanvas3D::bind_event_handlers() @@ -2413,13 +2445,7 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) { if (!m_initialized) return; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT - /*NotificationManager* notification_mgr = wxGetApp().plater()->get_notification_manager(); - if (notification_mgr->requires_update()) - notification_mgr->update_notifications(); - m_dirty |= notification_mgr->requires_render();*/ -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT // FIXME m_dirty |= m_main_toolbar.update_items_state(); m_dirty |= m_undoredo_toolbar.update_items_state(); @@ -2428,13 +2454,6 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera()); m_dirty |= mouse3d_controller_applied; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT - /* - if (notification_mgr->requires_update()) { - evt.RequestMore(); - }*/ -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT - if (!m_dirty) return; @@ -2890,11 +2909,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) keyCode == WXK_UP || keyCode == WXK_DOWN) { if (dynamic_cast(m_canvas->GetParent()) != nullptr) -#if ENABLE_ARROW_KEYS_WITH_SLIDERS post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_SLIDERS, evt)); -#else - post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, evt)); -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS } } } @@ -3851,7 +3866,9 @@ void GLCanvas3D::set_cursor(ECursorType type) void GLCanvas3D::msw_rescale() { +#if !ENABLE_WARNING_TEXTURE_REMOVAL m_warning_texture.msw_rescale(*this); +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL } void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar() @@ -4582,9 +4599,9 @@ bool GLCanvas3D::_init_main_toolbar() "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ; item.sprite_id = 10; item.enabling_callback = GLToolbarItem::Default_Enabling_Callback; - item.visibility_callback = [this]() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" || - wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); }; - item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(); }; + item.visibility_callback = []() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" || + wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); }; + item.left.action_callback = []() { wxGetApp().mainframe->select_tab(); }; if (!m_main_toolbar.add_item(item)) return false; @@ -5191,7 +5208,9 @@ void GLCanvas3D::_render_overlays() const _check_and_update_toolbar_icon_scale(); _render_gizmos_overlay(); +#if !ENABLE_WARNING_TEXTURE_REMOVAL _render_warning_texture(); +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL // main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed // to correctly place them @@ -5212,7 +5231,7 @@ void GLCanvas3D::_render_overlays() const _render_collapse_toolbar(); _render_view_toolbar(); - if ((m_layers_editing.last_object_id >= 0) && (m_layers_editing.object_max_z() > 0.0f)) + if (m_layers_editing.last_object_id >= 0 && m_layers_editing.object_max_z() > 0.0f) m_layers_editing.render_overlay(*this); const ConfigOptionBool* opt = dynamic_cast(m_config->option("complete_objects")); @@ -5229,10 +5248,12 @@ void GLCanvas3D::_render_overlays() const glsafe(::glPopMatrix()); } +#if !ENABLE_WARNING_TEXTURE_REMOVAL void GLCanvas3D::_render_warning_texture() const { m_warning_texture.render(*this); } +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL void GLCanvas3D::_render_volumes_for_picking() const { @@ -5402,8 +5423,7 @@ void GLCanvas3D::_render_sla_slices() const double clip_min_z = -m_clipping_planes[0].get_data()[3]; double clip_max_z = m_clipping_planes[1].get_data()[3]; - for (unsigned int i = 0; i < (unsigned int)print_objects.size(); ++i) - { + for (unsigned int i = 0; i < (unsigned int)print_objects.size(); ++i) { const SLAPrintObject* obj = print_objects[i]; if (!obj->is_step_done(slaposSliceSupports)) @@ -5474,10 +5494,8 @@ void GLCanvas3D::_render_sla_slices() const } } - if (!bottom_obj_triangles.empty() || !top_obj_triangles.empty() || !bottom_sup_triangles.empty() || !top_sup_triangles.empty()) - { - for (const SLAPrintObject::Instance& inst : obj->instances()) - { + if (!bottom_obj_triangles.empty() || !top_obj_triangles.empty() || !bottom_sup_triangles.empty() || !top_sup_triangles.empty()) { + for (const SLAPrintObject::Instance& inst : obj->instances()) { glsafe(::glPushMatrix()); glsafe(::glTranslated(unscale(inst.shift.x()), unscale(inst.shift.y()), 0)); glsafe(::glRotatef(Geometry::rad2deg(inst.rotation), 0.0, 0.0, 1.0)); @@ -5517,8 +5535,7 @@ void GLCanvas3D::_render_selection_sidebar_hints() const void GLCanvas3D::_update_volumes_hover_state() const { - for (GLVolume* v : m_volumes.volumes) - { + for (GLVolume* v : m_volumes.volumes) { v->hover = GLVolume::HS_None; } @@ -5529,8 +5546,7 @@ void GLCanvas3D::_update_volumes_hover_state() const bool shift_pressed = wxGetKeyState(WXK_SHIFT); // select by rectangle bool alt_pressed = wxGetKeyState(WXK_ALT); // deselect by rectangle - if (alt_pressed && (shift_pressed || ctrl_pressed)) - { + if (alt_pressed && (shift_pressed || ctrl_pressed)) { // illegal combinations of keys m_hover_volume_idxs.clear(); return; @@ -5539,33 +5555,28 @@ void GLCanvas3D::_update_volumes_hover_state() const bool selection_modifiers_only = m_selection.is_empty() || m_selection.is_any_modifier(); bool hover_modifiers_only = true; - for (int i : m_hover_volume_idxs) - { - if (!m_volumes.volumes[i]->is_modifier) - { + for (int i : m_hover_volume_idxs) { + if (!m_volumes.volumes[i]->is_modifier) { hover_modifiers_only = false; break; } } std::set> hover_instances; - for (int i : m_hover_volume_idxs) - { + for (int i : m_hover_volume_idxs) { const GLVolume& v = *m_volumes.volumes[i]; hover_instances.insert(std::make_pair(v.object_idx(), v.instance_idx())); } bool hover_from_single_instance = hover_instances.size() == 1; - if (hover_modifiers_only && !hover_from_single_instance) - { + if (hover_modifiers_only && !hover_from_single_instance) { // do not allow to select volumes from different instances m_hover_volume_idxs.clear(); return; } - for (int i : m_hover_volume_idxs) - { + for (int i : m_hover_volume_idxs) { GLVolume& volume = *m_volumes.volumes[i]; if (volume.hover != GLVolume::HS_None) continue; @@ -5574,8 +5585,7 @@ void GLCanvas3D::_update_volumes_hover_state() const // (volume->is_modifier && !selection_modifiers_only && !is_ctrl_pressed) -> allows hovering on selected modifiers belonging to selection of type Instance bool select = (!volume.selected || (volume.is_modifier && !selection_modifiers_only && !ctrl_pressed)) && !alt_pressed; - if (select || deselect) - { + if (select || deselect) { bool as_volume = volume.is_modifier && hover_from_single_instance && !ctrl_pressed && ( @@ -5583,22 +5593,18 @@ void GLCanvas3D::_update_volumes_hover_state() const (deselect && !m_selection.is_single_full_instance() && (volume.object_idx() == m_selection.get_object_idx()) && (volume.instance_idx() == m_selection.get_instance_idx())) ); - if (as_volume) - { + if (as_volume) { if (deselect) volume.hover = GLVolume::HS_Deselect; else volume.hover = GLVolume::HS_Select; } - else - { + else { int object_idx = volume.object_idx(); int instance_idx = volume.instance_idx(); - for (GLVolume* v : m_volumes.volumes) - { - if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) - { + for (GLVolume* v : m_volumes.volumes) { + if (v->object_idx() == object_idx && v->instance_idx() == instance_idx) { if (deselect) v->hover = GLVolume::HS_Deselect; else @@ -5617,8 +5623,7 @@ void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt) return; // A volume is selected. Test, whether hovering over a layer thickness bar. - if (evt != nullptr) - { + if (evt != nullptr) { const Rect& rect = LayersEditing::get_bar_rect_screen(*this); float b = rect.get_bottom(); m_layers_editing.last_z = m_layers_editing.object_max_z() * (b - evt->GetY() - 1.0f) / (b - rect.get_top()); @@ -5680,19 +5685,18 @@ void GLCanvas3D::_load_print_toolpaths() if (!print->is_step_done(psSkirt) || !print->is_step_done(psBrim)) return; - if (!print->has_skirt() && (print->config().brim_width.value == 0)) + if (!print->has_skirt() && !print->has_brim()) return; const float color[] = { 0.5f, 1.0f, 0.5f, 1.0f }; // greenish // number of skirt layers size_t total_layer_count = 0; - for (const PrintObject* print_object : print->objects()) - { + for (const PrintObject* print_object : print->objects()) { total_layer_count = std::max(total_layer_count, print_object->total_layer_count()); } size_t skirt_height = print->has_infinite_skirt() ? total_layer_count : std::min(print->config().skirt_height.value, total_layer_count); - if ((skirt_height == 0) && (print->config().brim_width.value > 0)) + if ((skirt_height == 0) && print->has_brim()) skirt_height = 1; // Get first skirt_height layers. @@ -5769,8 +5773,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c auto it = std::find_if(color_print_values->begin(), color_print_values->end(), [print_z](const CustomGCode::Item& code) { return fabs(code.print_z - print_z) < EPSILON; }); - if (it != color_print_values->end()) - { + if (it != color_print_values->end()) { CustomGCode::Type type = it->type; // pause print or custom Gcode if (type == CustomGCode::PausePrint || @@ -5790,8 +5793,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const CustomGCode::Item value{print_z + EPSILON, CustomGCode::Custom, 0, ""}; it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); - while (it != color_print_values->begin()) - { + while (it != color_print_values->begin()) { --it; // change color for current extruder if (it->type == CustomGCode::ColorChange) { @@ -5910,8 +5912,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c tbb::blocked_range(0, ctxt.layers.size(), grain_size), [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { GLVolumePtrs vols; - std::vector color_print_layer_to_glvolume; - auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { + auto volume = [&ctxt, &vols](size_t layer_idx, int extruder, int feature) -> GLVolume& { return *vols[ctxt.color_by_color_print()? ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx, extruder) : ctxt.color_by_tool() ? @@ -6254,6 +6255,24 @@ void GLCanvas3D::_update_sla_shells_outside_state() } } +#if ENABLE_WARNING_TEXTURE_REMOVAL +void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) +{ + _set_current(); + bool show = false; + if (!m_volumes.empty()) + show = _is_any_volume_outside(); + else { + if (wxGetApp().is_editor()) { + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); + if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) + show = !test_volume.contains(paths_volume); + } + } + _set_warning_notification(warning, show); +} +#else void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning) { _set_current(); @@ -6270,23 +6289,21 @@ void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning } _set_warning_texture(warning, show); } +#endif // ENABLE_WARNING_TEXTURE_REMOVAL std::vector GLCanvas3D::_parse_colors(const std::vector& colors) { static const float INV_255 = 1.0f / 255.0f; std::vector output(colors.size() * 4, 1.0f); - for (size_t i = 0; i < colors.size(); ++i) - { + for (size_t i = 0; i < colors.size(); ++i) { const std::string& color = colors[i]; const char* c = color.data() + 1; - if ((color.size() == 7) && (color.front() == '#')) - { - for (size_t j = 0; j < 3; ++j) - { + if (color.size() == 7 && color.front() == '#') { + for (size_t j = 0; j < 3; ++j) { int digit1 = hex_digit_to_int(*c++); int digit2 = hex_digit_to_int(*c++); - if ((digit1 == -1) || (digit2 == -1)) + if (digit1 == -1 || digit2 == -1) break; output[i * 4 + j] = float(digit1 * 16 + digit2) * INV_255; @@ -6296,10 +6313,42 @@ std::vector GLCanvas3D::_parse_colors(const std::vector& col return output; } +#if ENABLE_WARNING_TEXTURE_REMOVAL +void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) +{ + std::string text; + bool error = false; + switch (warning) { + case EWarning::ObjectOutside: text = _u8L("An object outside the print area was detected."); break; + case EWarning::ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = true; break; + case EWarning::SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = true; break; + case EWarning::SomethingNotShown: text = _u8L("Some objects are not visible."); break; + case EWarning::ObjectClashed: + text = _u8L("An object outside the print area was detected.\n" + "Resolve the current problem to continue slicing."); + error = true; + break; +} + auto& notification_manager = *wxGetApp().plater()->get_notification_manager(); + if (state) { + if (error) + notification_manager.push_plater_error_notification(text); + else + notification_manager.push_plater_warning_notification(text); + } + else { + if (error) + notification_manager.close_plater_error_notification(text); + else + notification_manager.close_plater_warning_notification(text); + } +} +#else void GLCanvas3D::_set_warning_texture(WarningTexture::Warning warning, bool state) { m_warning_texture.activate(warning, state, *this); } +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL bool GLCanvas3D::_is_any_volume_outside() const { @@ -6315,8 +6364,7 @@ void GLCanvas3D::_update_selection_from_hover() { bool ctrl_pressed = wxGetKeyState(WXK_CONTROL); - if (m_hover_volume_idxs.empty()) - { + if (m_hover_volume_idxs.empty()) { if (!ctrl_pressed && (m_rectangle_selection.get_state() == GLSelectionRectangle::Select)) m_selection.remove_all(); @@ -6326,50 +6374,40 @@ void GLCanvas3D::_update_selection_from_hover() GLSelectionRectangle::EState state = m_rectangle_selection.get_state(); bool hover_modifiers_only = true; - for (int i : m_hover_volume_idxs) - { - if (!m_volumes.volumes[i]->is_modifier) - { + for (int i : m_hover_volume_idxs) { + if (!m_volumes.volumes[i]->is_modifier) { hover_modifiers_only = false; break; } } bool selection_changed = false; - if (state == GLSelectionRectangle::Select) - { + if (state == GLSelectionRectangle::Select) { bool contains_all = true; - for (int i : m_hover_volume_idxs) - { - if (!m_selection.contains_volume((unsigned int)i)) - { + for (int i : m_hover_volume_idxs) { + if (!m_selection.contains_volume((unsigned int)i)) { contains_all = false; break; } } // the selection is going to be modified (Add) - if (!contains_all) - { + if (!contains_all) { wxGetApp().plater()->take_snapshot(_(L("Selection-Add from rectangle"))); selection_changed = true; } } - else - { + else { bool contains_any = false; - for (int i : m_hover_volume_idxs) - { - if (m_selection.contains_volume((unsigned int)i)) - { + for (int i : m_hover_volume_idxs) { + if (m_selection.contains_volume((unsigned int)i)) { contains_any = true; break; } } // the selection is going to be modified (Remove) - if (contains_any) - { + if (contains_any) { wxGetApp().plater()->take_snapshot(_(L("Selection-Remove from rectangle"))); selection_changed = true; } @@ -6383,12 +6421,9 @@ void GLCanvas3D::_update_selection_from_hover() if ((state == GLSelectionRectangle::Select) && !ctrl_pressed) m_selection.clear(); - for (int i : m_hover_volume_idxs) - { - if (state == GLSelectionRectangle::Select) - { - if (hover_modifiers_only) - { + for (int i : m_hover_volume_idxs) { + if (state == GLSelectionRectangle::Select) { + if (hover_modifiers_only) { const GLVolume& v = *m_volumes.volumes[i]; m_selection.add_volume(v.object_idx(), v.volume_idx(), v.instance_idx(), false); } @@ -6411,13 +6446,11 @@ void GLCanvas3D::_update_selection_from_hover() bool GLCanvas3D::_deactivate_undo_redo_toolbar_items() { - if (m_undoredo_toolbar.is_item_pressed("undo")) - { + if (m_undoredo_toolbar.is_item_pressed("undo")) { m_undoredo_toolbar.force_right_action(m_undoredo_toolbar.get_item_id("undo"), *this); return true; } - else if (m_undoredo_toolbar.is_item_pressed("redo")) - { + else if (m_undoredo_toolbar.is_item_pressed("redo")) { m_undoredo_toolbar.force_right_action(m_undoredo_toolbar.get_item_id("redo"), *this); return true; } @@ -6442,8 +6475,7 @@ bool GLCanvas3D::_deactivate_arrange_menu() bool GLCanvas3D::_deactivate_search_toolbar_item() { - if (is_search_pressed()) - { + if (is_search_pressed()) { m_main_toolbar.force_left_action(m_main_toolbar.get_item_id("search"), *this); return true; } @@ -6453,8 +6485,7 @@ bool GLCanvas3D::_deactivate_search_toolbar_item() bool GLCanvas3D::_activate_search_toolbar_item() { - if (!m_main_toolbar.is_item_pressed("search")) - { + if (!m_main_toolbar.is_item_pressed("search")) { m_main_toolbar.force_left_action(m_main_toolbar.get_item_id("search"), *this); return true; } @@ -6465,8 +6496,7 @@ bool GLCanvas3D::_activate_search_toolbar_item() bool GLCanvas3D::_deactivate_collapse_toolbar_items() { GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - if (collapse_toolbar.is_item_pressed("print")) - { + if (collapse_toolbar.is_item_pressed("print")) { collapse_toolbar.force_left_action(collapse_toolbar.get_item_id("print"), *this); return true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8e31addaab..10294931fe 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -124,11 +124,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); -#if ENABLE_ARROW_KEYS_WITH_SLIDERS wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_SLIDERS, wxKeyEvent); -#else -wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent); -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); @@ -302,6 +298,15 @@ class GLCanvas3D bool matches(double z) const { return this->z == z; } }; +#if ENABLE_WARNING_TEXTURE_REMOVAL + enum class EWarning { + ObjectOutside, + ToolpathOutside, + SlaSupportsOutside, + SomethingNotShown, + ObjectClashed + }; +#else class WarningTexture : public GUI::GLTexture { public: @@ -340,6 +345,7 @@ class GLCanvas3D // Generates the texture with given text. bool generate(const std::string& msg, const GLCanvas3D& canvas, bool compress, bool red_colored = false); }; +#endif // ENABLE_WARNING_TEXTURE_REMOVAL #if ENABLE_RENDER_STATISTICS class RenderStats @@ -394,12 +400,10 @@ class GLCanvas3D class Slope { bool m_enabled{ false }; - bool m_dialog_shown{ false }; - GLCanvas3D& m_canvas; GLVolumeCollection& m_volumes; static float s_window_width; public: - Slope(GLCanvas3D& canvas, GLVolumeCollection& volumes) : m_canvas(canvas), m_volumes(volumes) {} + Slope(GLVolumeCollection& volumes) : m_volumes(volumes) {} void enable(bool enable) { m_enabled = enable; } bool is_enabled() const { return m_enabled; } @@ -439,7 +443,9 @@ private: std::unique_ptr m_retina_helper; #endif bool m_in_render; +#if !ENABLE_WARNING_TEXTURE_REMOVAL WarningTexture m_warning_texture; +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL wxTimer m_timer; LayersEditing m_layers_editing; Mouse m_mouse; @@ -580,10 +586,8 @@ public: void bed_shape_changed(); - void set_clipping_plane(unsigned int id, const ClippingPlane& plane) - { - if (id < 2) - { + void set_clipping_plane(unsigned int id, const ClippingPlane& plane) { + if (id < 2) { m_clipping_planes[id] = plane; m_sla_caps[id].reset(); } @@ -662,9 +666,7 @@ public: void load_gcode_preview(const GCodeProcessor::Result& gcode_result); void refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void refresh_gcode_preview_render_paths(); -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } void load_sla_preview(); @@ -814,7 +816,9 @@ private: #endif // ENABLE_RENDER_SELECTION_CENTER void _check_and_update_toolbar_icon_scale() const; void _render_overlays() const; +#if !ENABLE_WARNING_TEXTURE_REMOVAL void _render_warning_texture() const; +#endif // !ENABLE_WARNING_TEXTURE_REMOVAL void _render_volumes_for_picking() const; void _render_current_gizmo() const; void _render_gizmos_overlay() const; @@ -867,10 +871,17 @@ private: void _load_sla_shells(); void _update_toolpath_volumes_outside_state(); void _update_sla_shells_outside_state(); +#if ENABLE_WARNING_TEXTURE_REMOVAL + void _set_warning_notification_if_needed(EWarning warning); + + // generates a warning notification containing the given message + void _set_warning_notification(EWarning warning, bool state); +#else void _show_warning_texture_if_needed(WarningTexture::Warning warning); // generates a warning texture containing the given message void _set_warning_texture(WarningTexture::Warning warning, bool state); +#endif // ENABLE_WARNING_TEXTURE_REMOVAL bool _is_any_volume_outside() const; diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index b0322a8213..dc81fde216 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -35,8 +35,8 @@ void disable_screensaver() { #if __APPLE__ CFStringRef reasonForActivity = CFSTR("Slic3r"); - IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, - kIOPMAssertionLevelOn, reasonForActivity, &assertionID); + [[maybe_unused]]IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, + kIOPMAssertionLevelOn, reasonForActivity, &assertionID); // ignore result: success == kIOReturnSuccess #elif _WIN32 SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS); @@ -46,7 +46,7 @@ void disable_screensaver() void enable_screensaver() { #if __APPLE__ - IOReturn success = IOPMAssertionRelease(assertionID); + IOPMAssertionRelease(assertionID); #elif _WIN32 SetThreadExecutionState(ES_CONTINUOUS); #endif @@ -71,7 +71,7 @@ void break_to_debugger() const std::string& shortkey_ctrl_prefix() { - static const std::string str = + static const std::string str = #ifdef __APPLE__ "⌘" #else @@ -83,7 +83,7 @@ const std::string& shortkey_ctrl_prefix() const std::string& shortkey_alt_prefix() { - static const std::string str = + static const std::string str = #ifdef __APPLE__ "⌥" #else @@ -132,13 +132,13 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt ConfigOptionFloats* vec_new = new ConfigOptionFloats{ boost::any_cast(value) }; config.option(opt_key)->set_at(vec_new, opt_index, opt_index); break; - } + } case coString: config.set_key_value(opt_key, new ConfigOptionString(boost::any_cast(value))); break; case coStrings:{ if (opt_key == "compatible_prints" || opt_key == "compatible_printers") { - config.option(opt_key)->values = + config.option(opt_key)->values = boost::any_cast>(value); } else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0) { @@ -179,17 +179,15 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt if (opt_key == "top_fill_pattern" || opt_key == "bottom_fill_pattern" || opt_key == "fill_pattern") - config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("ironing_type") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); - else if (opt_key.compare("fuzzy_skin_perimeter_mode") == 0) - config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); -// else if (opt_key.compare("fuzzy_skin_shape") == 0) -// config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + else if (opt_key.compare("fuzzy_skin") == 0) + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("gcode_flavor") == 0) - config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("machine_limits_usage") == 0) - config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("support_material_pattern") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if (opt_key.compare("seam_position") == 0) @@ -202,6 +200,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if(opt_key == "printhost_authorization_type") config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); + else if(opt_key == "brim_type") + config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); } break; case coPoints:{ diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 085bdb865a..90e1780903 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -799,6 +799,9 @@ bool GUI_App::on_init_inner() app_config->set("version", SLIC3R_VERSION); app_config->save(); + // If load_language() fails, the application closes. + load_language(wxString(), true); + wxInitAllImageHandlers(); SplashScreen* scrn = nullptr; @@ -866,9 +869,6 @@ bool GUI_App::on_init_inner() init_label_colours(); init_fonts(); - // If load_language() fails, the application closes. - load_language(wxString(), true); - // Suppress the '- default -' presets. preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1"); try { @@ -1716,7 +1716,11 @@ void GUI_App::add_config_menu(wxMenuBar *menu) PreferencesDialog dlg(mainframe); dlg.ShowModal(); app_layout_changed = dlg.settings_layout_changed(); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed()) +#else if (dlg.seq_top_layer_only_changed()) +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER this->plater_->refresh_print(); #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN #ifdef _WIN32 @@ -1813,7 +1817,8 @@ bool GUI_App::check_unsaved_changes(const wxString &header) // synchronize config.ini with the current selections. preset_bundle->export_selections(*app_config); - wxMessageBox(_L("The preset(s) modifications are successfully saved")); + wxMessageBox(_L_PLURAL("The preset modifications are successfully saved", + "The presets modifications are successfully saved", dlg.get_names_and_types().size())); } } @@ -1928,15 +1933,11 @@ void GUI_App::MacOpenFiles(const wxArrayString &fileNames) start_new_slicer(non_gcode_files, true); } else { if (! files.empty()) { -#if ENABLE_DRAG_AND_DROP_FIX wxArrayString input_files; for (size_t i = 0; i < non_gcode_files.size(); ++i) { input_files.push_back(non_gcode_files[i]); } this->plater()->load_files(input_files); -#else - this->plater()->load_files(files, true, true); -#endif } for (const wxString &filename : gcode_files) start_new_gcodeviewer(&filename); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 7d8643c7f8..8768f39ff7 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -132,7 +132,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus // Add control for the "Layer height" editor = new LayerRangeEditor(this, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), etLayerHeight, set_focus_data, - [range, this](coordf_t layer_height, bool, bool) + [range](coordf_t layer_height, bool, bool) { return wxGetApp().obj_list()->edit_layer_range(range, layer_height); }); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a1249c696f..5e4dd87890 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -13,6 +13,7 @@ #include "libslic3r/Model.hpp" #include "GLCanvas3D.hpp" #include "Selection.hpp" +#include "format.hpp" #include #include "slic3r/Utils/FixModelByWin10.hpp" @@ -72,7 +73,7 @@ static DynamicPrintConfig& printer_config() static int extruders_count() { - return wxGetApp().extruders_cnt(); + return wxGetApp().extruders_edited_cnt(); } static void take_snapshot(const wxString& snapshot_name) @@ -97,7 +98,7 @@ ObjectList::ObjectList(wxWindow* parent) : CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap("funnel"); CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap("funnel"); CATEGORY_ICON[L("Wipe options")] = create_scaled_bitmap("funnel"); -// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); + CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); // CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap("time"); CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap("wrench"); // ptSLA @@ -116,7 +117,9 @@ ObjectList::ObjectList(wxWindow* parent) : // detect the current mouse position here, to pass it to list_manipulation() method // if we detect it later, the user may have moved the mouse pointer while calculations are performed, and this would mess-up the HitTest() call performed into list_manipulation() // see: https://github.com/prusa3d/PrusaSlicer/issues/3802 +#ifndef __WXOSX__ const wxPoint mouse_pos = this->get_mouse_position_in_control(); +#endif #ifndef __APPLE__ // On Windows and Linux, forces a kill focus emulation on the object manipulator fields because this event handler is called @@ -413,27 +416,27 @@ wxString ObjectList::get_mesh_errors_list(const int obj_idx, const int vol_idx / return ""; // hide tooltip // Create tooltip string, if there are errors - wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):")), errors) + "\n"; + wxString tooltip = format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors) + ":\n"; const stl_stats& stats = vol_idx == -1 ? (*m_objects)[obj_idx]->get_object_stl_stats() : (*m_objects)[obj_idx]->volumes[vol_idx]->mesh().stl.stats; - std::map error_msg = { - { L("degenerate facets"), stats.degenerate_facets }, - { L("edges fixed"), stats.edges_fixed }, - { L("facets removed"), stats.facets_removed }, - { L("facets added"), stats.facets_added }, - { L("facets reversed"), stats.facets_reversed }, - { L("backwards edges"), stats.backwards_edges } - }; - - for (const auto& error : error_msg) - if (error.second > 0) - tooltip += from_u8((boost::format("\t%1% %2%\n") % error.second % _utf8(error.first)).str()); + if (stats.degenerate_facets > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d degenerate facet", "%1$d degenerate facets", stats.degenerate_facets), stats.degenerate_facets) + "\n"; + if (stats.edges_fixed > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d edge fixed", "%1$d edges fixed", stats.edges_fixed), stats.edges_fixed) + "\n"; + if (stats.facets_removed > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet removed", "%1$d facets removed", stats.facets_removed), stats.facets_removed) + "\n"; + if (stats.facets_added > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet added", "%1$d facets added", stats.facets_added), stats.facets_added) + "\n"; + if (stats.facets_reversed > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet reversed", "%1$d facets reversed", stats.facets_reversed), stats.facets_reversed) + "\n"; + if (stats.backwards_edges > 0) + tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d backwards edge", "%1$d backwards edges", stats.backwards_edges), stats.backwards_edges) + "\n"; if (is_windows10()) - tooltip += _(L("Right button click the icon to fix STL through Netfabb")); + tooltip += _L("Right button click the icon to fix STL through Netfabb"); return tooltip; } @@ -686,7 +689,7 @@ void ObjectList::msw_rescale_icons() CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap("funnel"); CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap("funnel"); CATEGORY_ICON[L("Wipe options")] = create_scaled_bitmap("funnel"); -// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); + CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); // CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap("time"); CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap("wrench"); // ptSLA @@ -751,7 +754,7 @@ void ObjectList::copy_layers_to_clipboard() return; } - for (const auto layer_item : sel_layers) + for (const auto& layer_item : sel_layers) if (m_objects_model->GetItemType(layer_item) & itLayer) { auto range = m_objects_model->GetLayerRangeByItem(layer_item); auto it = ranges.find(range); @@ -777,7 +780,7 @@ void ObjectList::paste_layers_into_list() t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; // and create Layer item(s) according to the layer_config_ranges - for (const auto range : cache_ranges) + for (const auto& range : cache_ranges) ranges.emplace(range); layers_item = add_layer_root_item(object_item); @@ -1020,7 +1023,7 @@ void ObjectList::show_context_menu(const bool evt_context_menu) printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; if (type & (itObject | itVolume)) - append_menu_item_convert_unit(menu); + append_menu_items_convert_unit(menu); if (!(type & itInstance)) append_menu_item_settings(menu); } @@ -1211,7 +1214,7 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event) **/ m_prevent_list_events = true;//it's needed for GTK - /* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid vaSome textlue, + /* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid value, * so set some nonempty string */ wxTextDataObject* obj = new wxTextDataObject; @@ -1271,7 +1274,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) // It looks like a fixed in current version of the wxWidgets // #ifdef __WXGTK__ // /* Under GTK, DnD moves an item between another two items. -// * And event.GetItem() return item, which is under "insertion line"Some text +// * And event.GetItem() return item, which is under "insertion line" // * So, if we move item down we should to decrease the to_volume_id value // **/ // if (to_volume_id > from_volume_id) to_volume_id--; @@ -1841,7 +1844,7 @@ void ObjectList::append_menu_item_export_stl(wxMenu* menu) const void ObjectList::append_menu_item_reload_from_disk(wxMenu* menu) const { append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), - [this](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, + [](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { return wxGetApp().plater()->can_reload_from_disk(); }, wxGetApp().plater()); } @@ -1903,56 +1906,59 @@ void ObjectList::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* me [](wxCommandEvent&) { wxGetApp().plater()->scale_selection_to_fit_print_volume(); }, "", menu); } -void ObjectList::append_menu_item_convert_unit(wxMenu* menu, int insert_pos/* = 1*/) +void ObjectList::append_menu_items_convert_unit(wxMenu* menu, int insert_pos/* = 1*/) { std::vector obj_idxs, vol_idxs; get_selection_indexes(obj_idxs, vol_idxs); if (obj_idxs.empty() && vol_idxs.empty()) return; - auto can_append = [this, obj_idxs, vol_idxs](bool from_imperial_unit) { + auto volume_respects_conversion = [](ModelVolume* volume, ConversionType conver_type) + { + return (conver_type == ConversionType::CONV_FROM_INCH && volume->source.is_converted_from_inches) || + (conver_type == ConversionType::CONV_TO_INCH && !volume->source.is_converted_from_inches) || + (conver_type == ConversionType::CONV_FROM_METER && volume->source.is_converted_from_meters) || + (conver_type == ConversionType::CONV_TO_METER && !volume->source.is_converted_from_meters); + }; + + auto can_append = [this, obj_idxs, vol_idxs, volume_respects_conversion](ConversionType conver_type) + { ModelObjectPtrs objects; for (int obj_idx : obj_idxs) { ModelObject* object = (*m_objects)[obj_idx]; if (vol_idxs.empty()) { for (ModelVolume* volume : object->volumes) - if (volume->source.is_converted_from_inches == from_imperial_unit) + if (volume_respects_conversion(volume, conver_type)) return false; } else { for (int vol_idx : vol_idxs) - if (object->volumes[vol_idx]->source.is_converted_from_inches == from_imperial_unit) + if (volume_respects_conversion(object->volumes[vol_idx], conver_type)) return false; } } return true; }; - wxString convert_menu_name = _L("Convert from imperial units"); - int convert_menu_id = menu->FindItem(convert_menu_name); - wxString revert_menu_name = _L("Revert conversion from imperial units"); - int revert_menu_id = menu->FindItem(revert_menu_name); + std::vector> items = { + {ConversionType::CONV_FROM_INCH , _L("Convert from imperial units") }, + {ConversionType::CONV_TO_INCH , _L("Revert conversion from imperial units") }, + {ConversionType::CONV_FROM_METER, _L("Convert from meters") }, + {ConversionType::CONV_TO_METER , _L("Revert conversion from meters") } }; - if (can_append(true)) { - // Delete revert menu item - if (revert_menu_id != wxNOT_FOUND) - menu->Destroy(revert_menu_id); - // Add convert menu item if it doesn't exist - if (convert_menu_id == wxNOT_FOUND) - append_menu_item(menu, wxID_ANY, convert_menu_name, convert_menu_name, - [](wxCommandEvent&) { wxGetApp().plater()->convert_unit(true); }, "", menu, - []() {return true;}, nullptr, insert_pos); - } - - if (can_append(false)) { - // Delete convert menu item - if (convert_menu_id != wxNOT_FOUND) - menu->Destroy(convert_menu_id); - // Add convert menu item if it doesn't exist - if (revert_menu_id == wxNOT_FOUND) - append_menu_item(menu, wxID_ANY, revert_menu_name, revert_menu_name, - [](wxCommandEvent&) { wxGetApp().plater()->convert_unit(false); }, "", menu, - []() {return true;}, nullptr, insert_pos); + for (auto item : items) { + int menu_id = menu->FindItem(item.second); + if (can_append(item.first)) { + // Add menu item if it doesn't exist + if (menu_id == wxNOT_FOUND) + append_menu_item(menu, wxID_ANY, item.second, item.second, + [item](wxCommandEvent&) { wxGetApp().plater()->convert_unit(item.first); }, "", menu, + []() {return true; }, nullptr, insert_pos); + } + else if (menu_id != wxNOT_FOUND) { + // Delete menu item + menu->Destroy(menu_id); + } } } @@ -2062,9 +2068,9 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) for (auto cat : settings_menu) { append_menu_item(menu, wxID_ANY, _(cat.first), "", - [menu, this](wxCommandEvent& event) { get_settings_choice(menu->GetLabel(event.GetId())); }, + [this, menu](wxCommandEvent& event) { get_settings_choice(menu->GetLabel(event.GetId())); }, CATEGORY_ICON.find(cat.first) == CATEGORY_ICON.end() ? wxNullBitmap : CATEGORY_ICON.at(cat.first), parent_menu, - [this]() { return true; }, wxGetApp().plater()); + []() { return true; }, wxGetApp().plater()); } return menu; @@ -2083,9 +2089,9 @@ void ObjectList::create_freq_settings_popupmenu(wxMenu *menu, const bool is_obje continue; append_menu_item(menu, wxID_ANY, _(it.first), "", - [menu, this](wxCommandEvent& event) { get_freq_settings_choice(menu->GetLabel(event.GetId())); }, + [this, menu](wxCommandEvent& event) { get_freq_settings_choice(menu->GetLabel(event.GetId())); }, CATEGORY_ICON.find(it.first) == CATEGORY_ICON.end() ? wxNullBitmap : CATEGORY_ICON.at(it.first), menu, - [this]() { return true; }, wxGetApp().plater()); + []() { return true; }, wxGetApp().plater()); } #if 0 // Add "Quick" settings bundles @@ -2481,6 +2487,13 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con if (!last_volume->config.empty()) { object->config.apply(last_volume->config); last_volume->config.clear(); + + // update extruder color in ObjectList + wxDataViewItem obj_item = m_objects_model->GetItemById(obj_idx); + if (obj_item) { + wxString extruder = object->config.has("extruder") ? wxString::Format("%d", object->config.extruder()) : _L("default"); + m_objects_model->SetExtruder(extruder, obj_item); + } } } } @@ -3946,6 +3959,8 @@ void ObjectList::select_items(const wxDataViewItemArray& sels) { m_prevent_list_events = true; + m_last_selected_item = sels.empty() ? wxDataViewItem(nullptr) : sels.back(); + UnselectAll(); SetSelections(sels); part_selection_changed(); @@ -4599,11 +4614,11 @@ void ObjectList::show_multi_selection_menu() append_menu_item_change_extruder(menu); append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), - [this](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { + [](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { return wxGetApp().plater()->can_reload_from_disk(); }, wxGetApp().plater()); - append_menu_item_convert_unit(menu); + append_menu_items_convert_unit(menu); if (can_merge_to_multipart_object()) append_menu_item_merge_to_multipart_object(menu); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 15d5ecb08e..0846def53c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -284,7 +284,7 @@ public: void append_menu_item_change_extruder(wxMenu* menu); void append_menu_item_delete(wxMenu* menu); void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu); - void append_menu_item_convert_unit(wxMenu* menu, int insert_pos = 1); // Add "Conver/Revert..." menu item after "Reload From Disk" + void append_menu_items_convert_unit(wxMenu* menu, int insert_pos = 1); // Add "Conver/Revert..." menu items (from/to inches/meters) after "Reload From Disk" void append_menu_item_merge_to_multipart_object(wxMenu *menu); void append_menu_item_merge_to_single_object(wxMenu *menu); void create_object_popupmenu(wxMenu *menu); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index b3cef47c55..cba7cef36c 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -76,6 +76,7 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent) void msw_rescale_word_local_combo(choice_ctrl* combo) { +#ifdef __WXOSX__ const wxString selection = combo->GetString(combo->GetSelection()); /* To correct scaling (set new controll size) of a wxBitmapCombobox @@ -97,6 +98,9 @@ void msw_rescale_word_local_combo(choice_ctrl* combo) combo->Append(_L("Local coordinates")); combo->SetValue(selection); +#else + combo->SetMinSize(wxSize(15 * wxGetApp().em_unit(), -1)); +#endif } static void set_font_and_background_style(wxWindow* win, const wxFont& font) @@ -105,10 +109,13 @@ static void set_font_and_background_style(wxWindow* win, const wxFont& font) win->SetBackgroundStyle(wxBG_STYLE_PAINT); } +static const wxString axes_color_text[] = { "#990000", "#009900", "#000099" }; +static const wxString axes_color_back[] = { "#f5dcdc", "#dcf5dc", "#dcdcf5" }; ObjectManipulation::ObjectManipulation(wxWindow* parent) : OG_Settings(parent, true) { m_imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + m_use_colors = wxGetApp().app_config->get("color_mapinulation_panel") == "1"; m_manifold_warning_bmp = ScalableBitmap(parent, "exclamation"); @@ -232,13 +239,14 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Add Axes labels with icons static const char axes[] = { 'X', 'Y', 'Z' }; -// std::vector axes_color = {"#990000", "#009900","#000099"}; +// std::vector axes_color = {"#EE0000", "#00EE00", "#0000EE"}; for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++) { const char label = axes[axis_idx]; wxStaticText* axis_name = new wxStaticText(m_parent, wxID_ANY, wxString(label)); set_font_and_background_style(axis_name, wxGetApp().bold_font()); -// axis_name->SetForegroundColour(wxColour(axes_color[axis_idx])); + //if (m_use_colors) + // axis_name->SetForegroundColour(wxColour(axes_color_text[axis_idx])); sizer = new wxBoxSizer(wxHORIZONTAL); // Under OSX we use font, smaller than default font, so @@ -477,8 +485,20 @@ void ObjectManipulation::update_ui_from_settings() update(3/*meSize*/, m_new_size); } } - m_check_inch->SetValue(m_imperial_units); + + if (m_use_colors != (wxGetApp().app_config->get("color_mapinulation_panel") == "1")) + { + m_use_colors = wxGetApp().app_config->get("color_mapinulation_panel") == "1"; + // update colors for edit-boxes + int axis_id = 0; + for (ManipulationEditor* editor : m_editors) { +// editor->SetForegroundColour(m_use_colors ? wxColour(axes_color_text[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + editor->SetBackgroundColour(m_use_colors ? wxColour(axes_color_back[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + if (++axis_id == 3) + axis_id = 0; + } + } } void ObjectManipulation::update_settings_value(const Selection& selection) @@ -996,6 +1016,10 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent, #ifdef __WXOSX__ this->OSXDisableAllSmartSubstitutions(); #endif // __WXOSX__ + if (parent->use_colors()) { +// this->SetForegroundColour(wxColour(axes_color_text[axis])); + this->SetBackgroundColour(wxColour(axes_color_back[axis])); + } // A name used to call handle_sidebar_focus_event() m_full_opt_name = m_opt_key+"_"+axes[axis]; diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 6b275799fe..bcc0d41234 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -95,6 +95,7 @@ private: wxStaticText* m_rotate_Label = nullptr; bool m_imperial_units { false }; + bool m_use_colors { false }; wxStaticText* m_position_unit { nullptr }; wxStaticText* m_size_unit { nullptr }; @@ -162,7 +163,8 @@ public: void Show(const bool show) override; bool IsShown() override; void UpdateAndShow(const bool show) override; - void update_ui_from_settings(); + void update_ui_from_settings(); + bool use_colors() { return m_use_colors; } void set_dirty() { m_dirty = true; } // Called from the App to update the UI if dirty. diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 3a1ec46f2e..76677660da 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include // this include must follow the wxWidgets ones or it won't compile on Windows -> see http://trac.wxwidgets.org/ticket/2421 @@ -169,9 +170,6 @@ Preview::Preview( : m_config(config) , m_process(process) , m_gcode_result(gcode_result) -#if !ENABLE_PREVIEW_TYPE_CHANGE - , m_preferred_color_mode("feature") -#endif // !ENABLE_PREVIEW_TYPE_CHANGE , m_schedule_background_process(schedule_background_process_func) { if (init(parent, model)) @@ -207,7 +205,7 @@ bool Preview::init(wxWindow* parent, Model* model) m_bottom_toolbar_panel = new wxPanel(this); m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View")); - m_choice_view_type = new wxChoice(m_bottom_toolbar_panel, wxID_ANY); + m_choice_view_type = new wxComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); m_choice_view_type->Append(_L("Feature type")); m_choice_view_type->Append(_L("Height")); m_choice_view_type->Append(_L("Width")); @@ -315,22 +313,6 @@ void Preview::set_as_dirty() m_canvas->set_as_dirty(); } -#if !ENABLE_PREVIEW_TYPE_CHANGE -void Preview::set_number_extruders(unsigned int number_extruders) -{ - if (m_number_extruders != number_extruders) { - m_number_extruders = number_extruders; - int tool_idx = m_choice_view_type->FindString(_(L("Tool"))); - int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type - m_choice_view_type->SetSelection(type); - if (0 <= type && (type < static_cast(GCodeViewer::EViewType::Count))) - m_canvas->set_gcode_view_preview_type(static_cast(type)); - - m_preferred_color_mode = (type == tool_idx) ? "tool_or_feature" : "feature"; - } -} -#endif // !ENABLE_PREVIEW_TYPE_CHANGE - void Preview::bed_shape_changed() { if (m_canvas != nullptr) @@ -434,7 +416,7 @@ void Preview::edit_layers_slider(wxKeyEvent& evt) void Preview::bind_event_handlers() { this->Bind(wxEVT_SIZE, &Preview::on_size, this); - m_choice_view_type->Bind(wxEVT_CHOICE, &Preview::on_choice_view_type, this); + m_choice_view_type->Bind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); @@ -443,18 +425,16 @@ void Preview::bind_event_handlers() void Preview::unbind_event_handlers() { this->Unbind(wxEVT_SIZE, &Preview::on_size, this); - m_choice_view_type->Unbind(wxEVT_CHOICE, &Preview::on_choice_view_type, this); + m_choice_view_type->Unbind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); } -#if ENABLE_ARROW_KEYS_WITH_SLIDERS void Preview::move_moves_slider(wxKeyEvent& evt) { if (m_moves_slider != nullptr) m_moves_slider->OnKeyDown(evt); } -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS void Preview::hide_layers_slider() { @@ -470,20 +450,11 @@ void Preview::on_size(wxSizeEvent& evt) void Preview::on_choice_view_type(wxCommandEvent& evt) { -#if !ENABLE_PREVIEW_TYPE_CHANGE - m_preferred_color_mode = (m_choice_view_type->GetStringSelection() == L("Tool")) ? "tool" : "feature"; -#endif // !ENABLE_PREVIEW_TYPE_CHANGE int selection = m_choice_view_type->GetCurrentSelection(); -#if ENABLE_PREVIEW_TYPE_CHANGE if (0 <= selection && selection < static_cast(GCodeViewer::EViewType::Count)) { m_canvas->set_toolpath_view_type(static_cast(selection)); m_keep_current_preview_type = true; } -#else - if (0 <= selection && selection < static_cast(GCodeViewer::EViewType::Count)) - m_canvas->set_toolpath_view_type(static_cast(selection)); -#endif // ENABLE_PREVIEW_TYPE_CHANGE - refresh_print(); } @@ -502,51 +473,10 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt) return; m_canvas->set_gcode_options_visibility_from_flags(new_flags); - -#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE m_canvas->refresh_gcode_preview_render_paths(); -#else - auto xored = [](unsigned int flags1, unsigned int flags2, unsigned int flag) { - auto is_flag_set = [](unsigned int flags, unsigned int flag) { - return (flags & (1 << flag)) != 0; - }; - return !is_flag_set(flags1, flag) != !is_flag_set(flags2, flag); - }; - - bool skip_refresh = xored(curr_flags, new_flags, static_cast(OptionType::Shells)) || - xored(curr_flags, new_flags, static_cast(OptionType::ToolMarker)); - - if (!skip_refresh) - refresh_print(); - else - m_canvas->set_as_dirty(); -#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE + update_moves_slider(); } -#if !ENABLE_PREVIEW_TYPE_CHANGE -void Preview::update_view_type(bool keep_volumes) -{ - const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; - - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes.empty() /*&& - (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */? - _L("Color Print") : - config.option("wiping_volumes_matrix")->values.size() > 1 ? - _L("Tool") : - _L("Feature type"); - - int type = m_choice_view_type->FindString(choice); - if (m_choice_view_type->GetSelection() != type) { - m_choice_view_type->SetSelection(type); - if (0 <= type && type < static_cast(GCodeViewer::EViewType::Count)) - m_canvas->set_gcode_view_preview_type(static_cast(type)); - m_preferred_color_mode = "feature"; - } - - reload_print(keep_volumes); -} -#endif // !ENABLE_PREVIEW_TYPE_CHANGE - void Preview::update_bottom_toolbar() { combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); @@ -602,12 +532,8 @@ wxBoxSizer* Preview::create_layers_slider_sizer() model.custom_gcode_per_print_z = m_layers_slider->GetTicksValues(); m_schedule_background_process(); -#if ENABLE_PREVIEW_TYPE_CHANGE m_keep_current_preview_type = false; reload_print(false); -#else - update_view_type(false); -#endif // ENABLE_PREVIEW_TYPE_CHANGE }); return sizer; @@ -680,6 +606,9 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee CustomGCode::Info& ticks_info_from_model = plater->model().custom_gcode_per_print_z; check_layers_slider_values(ticks_info_from_model.gcodes, layers_z); + //first of all update extruder colors to avoid crash, when we are switching printer preset from MM to SM + m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config()); + m_layers_slider->SetSliderValues(layers_z); assert(m_layers_slider->GetMinValue() == 0); m_layers_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); @@ -704,7 +633,6 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee bool sla_print_technology = plater->printer_technology() == ptSLA; bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); m_layers_slider->SetDrawMode(sla_print_technology, sequential_print); - m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config()); if (sla_print_technology) m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times); else @@ -781,26 +709,17 @@ void Preview::update_layers_slider_from_canvas(wxKeyEvent& event) const auto key = event.GetKeyCode(); -#if ENABLE_ARROW_KEYS_WITH_SLIDERS if (key == 'S' || key == 'W') { const int new_pos = key == 'W' ? m_layers_slider->GetHigherValue() + 1 : m_layers_slider->GetHigherValue() - 1; -#else - if (key == 'U' || key == 'D') { - const int new_pos = key == 'U' ? m_layers_slider->GetHigherValue() + 1 : m_layers_slider->GetHigherValue() - 1; -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS m_layers_slider->SetHigherValue(new_pos); if (event.ShiftDown() || m_layers_slider->is_one_layer()) m_layers_slider->SetLowerValue(m_layers_slider->GetHigherValue()); } -#if ENABLE_ARROW_KEYS_WITH_SLIDERS else if (key == 'A' || key == 'D') { const int new_pos = key == 'D' ? m_moves_slider->GetHigherValue() + 1 : m_moves_slider->GetHigherValue() - 1; m_moves_slider->SetHigherValue(new_pos); if (event.ShiftDown() || m_moves_slider->is_one_layer()) m_moves_slider->SetLowerValue(m_moves_slider->GetHigherValue()); } else if (key == 'X') -#else - else if (key == 'S') -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS m_layers_slider->ChangeOneLayerLock(); else if (key == WXK_SHIFT) m_layers_slider->UseDefaultColors(false); @@ -816,12 +735,25 @@ void Preview::update_moves_slider() return; std::vector values(view.endpoints.last - view.endpoints.first + 1); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + std::vector alternate_values(view.endpoints.last - view.endpoints.first + 1); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER unsigned int count = 0; for (unsigned int i = view.endpoints.first; i <= view.endpoints.last; ++i) { +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + values[count] = static_cast(i + 1); + if (view.gcode_ids[i] > 0) + alternate_values[count] = static_cast(view.gcode_ids[i]); + ++count; +#else values[count++] = static_cast(i + 1); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER } m_moves_slider->SetSliderValues(values); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_moves_slider->SetSliderAlternateValues(alternate_values); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER m_moves_slider->SetMaxValue(view.endpoints.last - view.endpoints.first); m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, view.current.last - view.endpoints.first); } @@ -873,21 +805,6 @@ void Preview::load_print_as_fff(bool keep_z_range) return; } -#if !ENABLE_PREVIEW_TYPE_CHANGE - if (m_preferred_color_mode == "tool_or_feature") { - // It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature. - // Color by feature if it is a single extruder print. - unsigned int number_extruders = (unsigned int)print->extruders().size(); - int tool_idx = m_choice_view_type->FindString(_L("Tool")); - int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type - m_choice_view_type->SetSelection(type); - if (0 <= type && type < static_cast(GCodeViewer::EViewType::Count)) - m_canvas->set_gcode_view_preview_type(static_cast(type)); - // If the->SetSelection changed the following line, revert it to "decide yourself". - m_preferred_color_mode = "tool_or_feature"; - } -#endif // !ENABLE_PREVIEW_TYPE_CHANGE - GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); // Collect colors per extruder. @@ -936,7 +853,6 @@ void Preview::load_print_as_fff(bool keep_z_range) update_layers_slider(zs, keep_z_range); } -#if ENABLE_PREVIEW_TYPE_CHANGE unsigned int number_extruders = (unsigned int)print->extruders().size(); if (!m_keep_current_preview_type) { @@ -952,7 +868,6 @@ void Preview::load_print_as_fff(bool keep_z_range) } } } -#endif // ENABLE_PREVIEW_TYPE_CHANGE } void Preview::load_print_as_sla() diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 372d44fa31..3bf0e21ae3 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -13,7 +13,7 @@ class wxNotebook; class wxGLCanvas; class wxBoxSizer; class wxStaticText; -class wxChoice; +class wxComboBox; class wxComboCtrl; class wxBitmapComboBox; class wxCheckBox; @@ -82,7 +82,7 @@ class Preview : public wxPanel wxBoxSizer* m_layers_slider_sizer { nullptr }; wxPanel* m_bottom_toolbar_panel { nullptr }; wxStaticText* m_label_view_type { nullptr }; - wxChoice* m_choice_view_type { nullptr }; + wxComboBox* m_choice_view_type { nullptr }; wxStaticText* m_label_show { nullptr }; wxComboCtrl* m_combochecklist_features { nullptr }; size_t m_combochecklist_features_pos { 0 }; @@ -102,11 +102,7 @@ class Preview : public wxPanel std::function m_schedule_background_process; unsigned int m_number_extruders { 1 }; -#if ENABLE_PREVIEW_TYPE_CHANGE bool m_keep_current_preview_type{ false }; -#else - std::string m_preferred_color_mode; -#endif // ENABLE_PREVIEW_TYPE_CHANGE bool m_loaded { false }; @@ -138,9 +134,6 @@ public: void set_as_dirty(); -#if !ENABLE_PREVIEW_TYPE_CHANGE - void set_number_extruders(unsigned int number_extruders); -#endif // !ENABLE_PREVIEW_TYPE_CHANGE void bed_shape_changed(); void select_view(const std::string& direction); void set_drop_target(wxDropTarget* target); @@ -155,18 +148,12 @@ public: void move_layers_slider(wxKeyEvent& evt); void edit_layers_slider(wxKeyEvent& evt); -#if !ENABLE_PREVIEW_TYPE_CHANGE - void update_view_type(bool keep_volumes); -#endif // !ENABLE_PREVIEW_TYPE_CHANGE - bool is_loaded() const { return m_loaded; } void update_bottom_toolbar(); void update_moves_slider(); void enable_moves_slider(bool enable); -#if ENABLE_ARROW_KEYS_WITH_SLIDERS void move_moves_slider(wxKeyEvent& evt); -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS void hide_layers_slider(); private: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index c0f33978f6..1bd917c862 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -31,17 +31,17 @@ public: std::string get_tooltip() const override; protected: - virtual bool on_init(); - virtual void on_load(cereal::BinaryInputArchive& ar) { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } - virtual void on_save(cereal::BinaryOutputArchive& ar) const { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } - virtual std::string on_get_name() const; - virtual void on_set_state(); - virtual bool on_is_activable() const; - virtual void on_start_dragging(); - virtual void on_update(const UpdateData& data); - virtual void on_render() const; - virtual void on_render_for_picking() const; - virtual void on_render_input_window(float x, float y, float bottom_limit); + virtual bool on_init() override; + virtual void on_load(cereal::BinaryInputArchive& ar) override{ ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } + virtual void on_save(cereal::BinaryOutputArchive& ar) const override { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } + virtual std::string on_get_name() const override; + virtual void on_set_state() override; + virtual bool on_is_activable() const override; + virtual void on_start_dragging() override; + virtual void on_update(const UpdateData& data) override; + virtual void on_render() const override; + virtual void on_render_for_picking() const override; + virtual void on_render_input_window(float x, float y, float bottom_limit) override; private: void update_max_z(const Selection& selection) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 8f2703faad..f3f87cc33e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -20,10 +20,8 @@ namespace GUI { void GLGizmoFdmSupports::on_shutdown() { - if (m_setting_angle) { - m_setting_angle = false; - m_parent.use_slope(false); - } + m_angle_threshold_deg = 0.f; + m_parent.use_slope(false); } @@ -52,6 +50,9 @@ bool GLGizmoFdmSupports::on_init() m_desc["remove_all"] = _L("Remove all selection"); m_desc["circle"] = _L("Circle"); m_desc["sphere"] = _L("Sphere"); + m_desc["highlight_by_angle"] = _L("Highlight by angle"); + m_desc["enforce_button"] = _L("Enforce"); + m_desc["cancel"] = _L("Cancel"); return true; } @@ -65,8 +66,7 @@ void GLGizmoFdmSupports::render_painter_gizmo() const glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (! m_setting_angle) - render_triangles(selection); + render_triangles(selection); m_c->object_clipper()->render_cut(); render_cursor(); @@ -81,179 +81,183 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l if (! m_c->selection_info()->model_object()) return; - const float approx_height = m_imgui->scaled(14.0f); + const float approx_height = m_imgui->scaled(17.0f); y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - if (! m_setting_angle) { - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: - const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, - m_imgui->calc_text_size(m_desc.at("reset_direction")).x) - + m_imgui->scaled(1.5f); - const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); - const float cursor_type_radio_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f); - const float cursor_type_radio_width1 = m_imgui->calc_text_size(m_desc["circle"]).x - + m_imgui->scaled(2.5f); - const float cursor_type_radio_width2 = m_imgui->calc_text_size(m_desc["sphere"]).x - + m_imgui->scaled(2.5f); - const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float minimal_slider_width = m_imgui->scaled(4.f); + // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, + m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float autoset_slider_left = m_imgui->calc_text_size(m_desc.at("highlight_by_angle")).x + m_imgui->scaled(1.f); + const float cursor_type_radio_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f); + const float cursor_type_radio_width1 = m_imgui->calc_text_size(m_desc["circle"]).x + + m_imgui->scaled(2.5f); + const float cursor_type_radio_width2 = m_imgui->calc_text_size(m_desc["sphere"]).x + + m_imgui->scaled(2.5f); + const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); + const float button_enforce_width = m_imgui->calc_text_size(m_desc.at("enforce_button")).x; + const float button_cancel_width = m_imgui->calc_text_size(m_desc.at("cancel")).x; + const float buttons_width = std::max(button_enforce_width, button_cancel_width) + m_imgui->scaled(0.5f); + const float minimal_slider_width = m_imgui->scaled(4.f); - float caption_max = 0.f; - float total_text_max = 0.; - for (const std::string& t : {"enforce", "block", "remove"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); - total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); - } - caption_max += m_imgui->scaled(1.f); - total_text_max += m_imgui->scaled(1.f); + float caption_max = 0.f; + float total_text_max = 0.; + for (const std::string& t : {"enforce", "block", "remove"}) { + caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); + total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); + } + caption_max += m_imgui->scaled(1.f); + total_text_max += m_imgui->scaled(1.f); - float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, button_width); - window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_width1 + cursor_type_radio_width2); + float window_width = minimal_slider_width + std::max(autoset_slider_left, std::max(cursor_slider_left, clipping_slider_left)); + window_width = std::max(window_width, total_text_max); + window_width = std::max(window_width, button_width); + window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_width1 + cursor_type_radio_width2); + window_width = std::max(window_width, 2.f * buttons_width + m_imgui->scaled(1.f)); - auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, caption); - ImGui::SameLine(caption_max); - m_imgui->text(text); - }; + auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, caption); + ImGui::SameLine(caption_max); + m_imgui->text(text); + }; - for (const std::string& t : {"enforce", "block", "remove"}) - draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); + for (const std::string& t : {"enforce", "block", "remove"}) + draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); - m_imgui->text(""); + m_imgui->text(""); + ImGui::Separator(); - if (m_imgui->button(_L("Autoset by angle") + "...")) { - m_setting_angle = true; - } - - ImGui::SameLine(); - - if (m_imgui->button(m_desc.at("remove_all"))) { - Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - if (mv->is_model_part()) { - ++idx; - m_triangle_selectors[idx]->reset(); - } - } - - update_model_object(); + m_imgui->text(m_desc["highlight_by_angle"] + ":"); + ImGui::AlignTextToFramePadding(); + std::string format_str = std::string("%.f") + I18N::translate_utf8("°", + "Degree sign to use in the respective slider in FDM supports gizmo," + "placed after the number with no whitespace in between."); + ImGui::SameLine(autoset_slider_left); + ImGui::PushItemWidth(window_width - autoset_slider_left); + if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, format_str.data())) { + m_parent.set_slope_normal_angle(90.f - m_angle_threshold_deg); + if (! m_parent.is_using_slope()) { + m_parent.use_slope(true); m_parent.set_as_dirty(); } + } - const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + m_imgui->disabled_begin(m_angle_threshold_deg == 0.f); + ImGui::NewLine(); + ImGui::SameLine(window_width - 2.f*buttons_width - m_imgui->scaled(0.5f)); + if (m_imgui->button(m_desc["enforce_button"], buttons_width, 0.f)) { + select_facets_by_angle(m_angle_threshold_deg, false); + m_angle_threshold_deg = 0.f; + } + ImGui::SameLine(window_width - buttons_width); + if (m_imgui->button(m_desc["cancel"], buttons_width, 0.f)) { + m_angle_threshold_deg = 0.f; + m_parent.use_slope(false); + } + m_imgui->disabled_end(); - ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc.at("cursor_size")); - ImGui::SameLine(cursor_slider_left); - ImGui::PushItemWidth(window_width - cursor_slider_left); - ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } + ImGui::Separator(); - - ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc.at("cursor_type")); - ImGui::SameLine(cursor_type_radio_left + m_imgui->scaled(0.f)); - ImGui::PushItemWidth(cursor_type_radio_width1); - - bool sphere_sel = m_cursor_type == TriangleSelector::CursorType::SPHERE; - if (m_imgui->radio_button(m_desc["sphere"], sphere_sel)) - sphere_sel = true; - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Paints all facets inside, regardless of their orientation.").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - ImGui::SameLine(cursor_type_radio_left + cursor_type_radio_width2 + m_imgui->scaled(0.f)); - ImGui::PushItemWidth(cursor_type_radio_width2); - - if (m_imgui->radio_button(m_desc["circle"], ! sphere_sel)) - sphere_sel = false; - - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Ignores facets facing away from the camera.").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - m_cursor_type = sphere_sel - ? TriangleSelector::CursorType::SPHERE - : TriangleSelector::CursorType::CIRCLE; - - - - - ImGui::Separator(); - if (m_c->object_clipper()->get_position() == 0.f) { - ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc.at("clipping_of_view")); - } - else { - if (m_imgui->button(m_desc.at("reset_direction"))) { - wxGetApp().CallAfter([this](){ - m_c->object_clipper()->set_position(-1., false); - }); + if (m_imgui->button(m_desc.at("remove_all"))) { + Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (mv->is_model_part()) { + ++idx; + m_triangle_selectors[idx]->reset(); } } - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - float clp_dist = m_c->object_clipper()->get_position(); - if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) - m_c->object_clipper()->set_position(clp_dist, true); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } + update_model_object(); + m_parent.set_as_dirty(); + } - m_imgui->end(); + + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + + ImGui::AlignTextToFramePadding(); + m_imgui->text(m_desc.at("cursor_size")); + ImGui::SameLine(cursor_slider_left); + ImGui::PushItemWidth(window_width - cursor_slider_left); + ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + + ImGui::AlignTextToFramePadding(); + m_imgui->text(m_desc.at("cursor_type")); + ImGui::SameLine(cursor_type_radio_left + m_imgui->scaled(0.f)); + ImGui::PushItemWidth(cursor_type_radio_width1); + + bool sphere_sel = m_cursor_type == TriangleSelector::CursorType::SPHERE; + if (m_imgui->radio_button(m_desc["sphere"], sphere_sel)) + sphere_sel = true; + + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Paints all facets inside, regardless of their orientation.").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::SameLine(cursor_type_radio_left + cursor_type_radio_width2 + m_imgui->scaled(0.f)); + ImGui::PushItemWidth(cursor_type_radio_width2); + + if (m_imgui->radio_button(m_desc["circle"], ! sphere_sel)) + sphere_sel = false; + + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ignores facets facing away from the camera.").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + m_cursor_type = sphere_sel + ? TriangleSelector::CursorType::SPHERE + : TriangleSelector::CursorType::CIRCLE; + + + + + ImGui::Separator(); + if (m_c->object_clipper()->get_position() == 0.f) { + ImGui::AlignTextToFramePadding(); + m_imgui->text(m_desc.at("clipping_of_view")); } else { - m_imgui->begin(_L("Autoset custom supports"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - ImGui::AlignTextToFramePadding(); - m_imgui->text(_L("Threshold:")); - std::string format_str = std::string("%.f") + I18N::translate_utf8("°", - "Degree sign to use in the respective slider in FDM supports gizmo," - "placed after the number with no whitespace in between."); - ImGui::SameLine(); - if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, format_str.data())) - m_parent.set_slope_normal_angle(90.f - m_angle_threshold_deg); - if (m_imgui->button(_L("Enforce"))) - select_facets_by_angle(m_angle_threshold_deg, false); - ImGui::SameLine(); - if (m_imgui->button(_L("Block"))) - select_facets_by_angle(m_angle_threshold_deg, true); - ImGui::SameLine(); - if (m_imgui->button(_L("Cancel"))) - m_setting_angle = false; - m_imgui->end(); - bool needs_update = !(m_setting_angle && m_parent.is_using_slope()); - if (needs_update) { - m_parent.use_slope(m_setting_angle); - m_parent.set_as_dirty(); + if (m_imgui->button(m_desc.at("reset_direction"))) { + wxGetApp().CallAfter([this](){ + m_c->object_clipper()->set_position(-1., false); + }); } } + + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + float clp_dist = m_c->object_clipper()->get_position(); + if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) + m_c->object_clipper()->set_position(clp_dist, true); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + m_imgui->end(); } @@ -296,7 +300,6 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) : _L("Add supports by angle")); update_model_object(); m_parent.set_as_dirty(); - m_setting_angle = false; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index fc97707873..41e4cc514b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -30,8 +30,7 @@ private: PainterGizmoType get_painter_type() const override; void select_facets_by_angle(float threshold, bool block); - float m_angle_threshold_deg = 45.f; - bool m_setting_angle = false; + float m_angle_threshold_deg = 0.f; // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 5a4275b7fc..20aa9f56cc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -33,14 +33,14 @@ public: std::string get_tooltip() const override; protected: - virtual bool on_init(); - virtual std::string on_get_name() const; - virtual bool on_is_activable() const; - virtual void on_start_dragging(); - virtual void on_stop_dragging(); - virtual void on_update(const UpdateData& data); - virtual void on_render() const; - virtual void on_render_for_picking() const; + virtual bool on_init() override; + virtual std::string on_get_name() const override; + virtual bool on_is_activable() const override; + virtual void on_start_dragging() override; + virtual void on_stop_dragging() override; + virtual void on_update(const UpdateData& data) override; + virtual void on_render() const override; + virtual void on_render_for_picking() const override; private: double calc_projection(const UpdateData& data) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 819d014e81..91aef75d9a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -540,7 +540,9 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), double(m_vertices[tr.verts_idxs[i]].v[1]), double(m_vertices[tr.verts_idxs[i]].v[2]), - 0., 0., 1.); + double(tr.normal[0]), + double(tr.normal[1]), + double(tr.normal[2])); va.push_triangle(cnt, cnt+1, cnt+2); @@ -550,14 +552,26 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) m_iva_enforcers.finalize_geometry(true); m_iva_blockers.finalize_geometry(true); - if (m_iva_enforcers.has_VBOs()) { - ::glColor4f(0.f, 0.f, 1.f, 0.4f); + bool render_enf = m_iva_enforcers.has_VBOs(); + bool render_blc = m_iva_blockers.has_VBOs(); + + auto* shader = wxGetApp().get_shader("gouraud"); + if (! shader) + return; + + shader->start_using(); + ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); + shader->set_uniform("slope.actived", false); + + if (render_enf) { + std::array color = { 0.47f, 0.47f, 1.f, 1.f }; + shader->set_uniform("uniform_color", color); m_iva_enforcers.render(); } - - if (m_iva_blockers.has_VBOs()) { - ::glColor4f(1.f, 0.f, 0.f, 0.4f); + if (render_blc) { + std::array color = { 1.f, 0.44f, 0.44f, 1.f }; + shader->set_uniform("uniform_color", color); m_iva_blockers.render(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 6f8cbec603..da415ce09a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -59,8 +59,8 @@ class GLGizmoPainterBase : public GLGizmoBase private: ObjectID m_old_mo_id; size_t m_old_volumes_size = 0; - virtual void on_render() const {} - virtual void on_render_for_picking() const {} + virtual void on_render() const override {} + virtual void on_render_for_picking() const override {} public: GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index 0d8f3f7fa7..39021640ad 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -47,13 +47,13 @@ public: std::string get_tooltip() const override; protected: - virtual bool on_init(); - virtual std::string on_get_name() const; - virtual bool on_is_activable() const; - virtual void on_start_dragging(); - virtual void on_update(const UpdateData& data); - virtual void on_render() const; - virtual void on_render_for_picking() const; + virtual bool on_init() override; + virtual std::string on_get_name() const override; + virtual bool on_is_activable() const override; + virtual void on_start_dragging() override; + virtual void on_update(const UpdateData& data) override; + virtual void on_render() const override; + virtual void on_render_for_picking() const override; private: void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index e626aa7f86..b5dbab2844 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -893,7 +893,7 @@ void GLGizmoSlaSupports::on_set_state() // Only take the snapshot when the USER opens the gizmo. Common gizmos // data are not yet available, the CallAfter will postpone taking the // snapshot until they are. No, it does not feel right. - wxGetApp().CallAfter([this]() { + wxGetApp().CallAfter([]() { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on"))); }); } @@ -903,7 +903,7 @@ void GLGizmoSlaSupports::on_set_state() m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - bool will_ask = m_editing_mode && unsaved_changes(); + bool will_ask = m_editing_mode && unsaved_changes() && on_is_activable(); if (will_ask) { wxGetApp().CallAfter([this]() { // Following is called through CallAfter, because otherwise there was a problem diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index aedf782e89..61c2732976 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -161,7 +161,7 @@ protected: private: ModelObject* m_model_object = nullptr; - int m_active_inst = -1; + // int m_active_inst = -1; float m_z_shift = 0.f; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index e3bb964ad3..abbc8599bd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -7,6 +7,7 @@ #include "slic3r/GUI/GUI_ObjectManipulation.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "slic3r/GUI/NotificationManager.hpp" #include "slic3r/GUI/Gizmos/GLGizmoMove.hpp" #include "slic3r/GUI/Gizmos/GLGizmoScale.hpp" @@ -1139,5 +1140,19 @@ bool GLGizmosManager::grabber_contains_mouse() const return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; } + +bool GLGizmosManager::is_in_editing_mode(bool error_notification) const +{ + if (m_current != SlaSupports || ! dynamic_cast(get_current())->is_in_editing_mode()) + return false; + + if (error_notification) + wxGetApp().plater()->get_notification_manager()->push_slicing_error_notification( + _u8L("You are currently editing SLA support points. Please, apply or discard " + "your changes first.")); + + return true; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 7f47167e9e..917a5830c2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -210,6 +210,8 @@ public: ClippingPlane get_clipping_plane() const; bool wants_reslice_supports_on_undo() const; + bool is_in_editing_mode(bool error_notification = false) const; + void render_current_gizmo() const; void render_current_gizmo_for_picking_pass() const; void render_painter_gizmo() const; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index ff8ba8f48a..1ed4b492fd 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -940,7 +940,7 @@ void ImGuiWrapper::init_font(bool compress) config.MergeMode = true; if (! m_font_cjk) { // Apple keyboard shortcuts are only contained in the CJK fonts. - ImFont *font_cjk = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSansCJK-Regular.ttc").c_str(), m_font_size, &config, ranges_keyboard_shortcuts); + [[maybe_unused]]ImFont *font_cjk = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSansCJK-Regular.ttc").c_str(), m_font_size, &config, ranges_keyboard_shortcuts); assert(font_cjk != nullptr); } #endif diff --git a/src/slic3r/GUI/InstanceCheck.cpp b/src/slic3r/GUI/InstanceCheck.cpp index 73bbeda353..9535e0126a 100644 --- a/src/slic3r/GUI/InstanceCheck.cpp +++ b/src/slic3r/GUI/InstanceCheck.cpp @@ -28,8 +28,32 @@ #endif //__linux__ namespace Slic3r { + +#ifdef __APPLE__ + bool unlock_lockfile(const std::string& name, const std::string& path) + { + std::string dest_dir = path + name; + //BOOST_LOG_TRIVIAL(debug) << "full lock path: " << dest_dir; + struct flock fl; + int fdlock; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 1; + if ((fdlock = open(dest_dir.c_str(), O_WRONLY | O_CREAT, 0666)) == -1) + return false; + + if (fcntl(fdlock, F_SETLK, &fl) == -1) + return false; + + return true; + } +#endif //__APPLE__ + namespace instance_check_internal { + static bool s_created_lockfile = false; + struct CommandLineAnalysis { std::optional should_send; @@ -145,15 +169,41 @@ namespace instance_check_internal BOOST_LOG_TRIVIAL(debug) << "get_lock(): unable to create datadir !!!"; } - if ((fdlock = open(dest_dir.c_str(), O_WRONLY | O_CREAT, 0666)) == -1) + if ((fdlock = open(dest_dir.c_str(), O_WRONLY | O_CREAT, 0666)) == -1) { + BOOST_LOG_TRIVIAL(debug) << "Not creating lockfile."; return true; + } - if (fcntl(fdlock, F_SETLK, &fl) == -1) + if (fcntl(fdlock, F_SETLK, &fl) == -1) { + BOOST_LOG_TRIVIAL(debug) << "Not creating lockfile."; return true; + } + BOOST_LOG_TRIVIAL(debug) << "Creating lockfile."; + s_created_lockfile = true; return false; } + // Deletes lockfile if it was created by this instance + // The Lockfile is created only on Linux a OSX. On Win, its handled by named mutex. + // The lockfile is deleted by instance it created it. + // On OSX message is passed to other instances to create a new lockfile after deletition. + static void delete_lockfile() + { + //BOOST_LOG_TRIVIAL(debug) << "shuting down with lockfile: " << l_created_lockfile; + if (s_created_lockfile) + { + std::string path = data_dir() + "/cache/" + GUI::wxGetApp().get_instance_hash_string() + ".lock"; + if( remove( path.c_str() ) != 0 ) + BOOST_LOG_TRIVIAL(error) << "Failed to delete lockfile " << path; + //else + // BOOST_LOG_TRIVIAL(error) << "success delete lockfile " << path; +#ifdef __APPLE__ + send_message_mac_closing(GUI::wxGetApp().get_instance_hash_string(),GUI::wxGetApp().get_instance_hash_string()); +#endif + } + } + #endif //WIN32 #if defined(__APPLE__) @@ -295,7 +345,7 @@ bool instance_check(int argc, char** argv, bool app_config_single_instance) if (! cla.should_send.has_value()) cla.should_send = app_config_single_instance; #ifdef _WIN32 - GUI::wxGetApp().init_single_instance_checker(lock_name + ".lock", data_dir() + "/cache/"); + GUI::wxGetApp().init_single_instance_checker(lock_name + ".lock", data_dir() + "\\cache\\"); if (cla.should_send.value() && GUI::wxGetApp().single_instance_checker()->IsAnotherRunning()) { #else // mac & linx // get_lock() creates the lockfile therefore *cla.should_send is checked after @@ -306,29 +356,11 @@ bool instance_check(int argc, char** argv, bool app_config_single_instance) return true; } BOOST_LOG_TRIVIAL(info) << "instance check: Another instance not found or single-instance not set."; + return false; } -#ifdef __APPLE__ -bool unlock_lockfile(const std::string& name, const std::string& path) -{ - std::string dest_dir = path + name; - //BOOST_LOG_TRIVIAL(debug) << "full lock path: " << dest_dir; - struct flock fl; - int fdlock; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 1; - if ((fdlock = open(dest_dir.c_str(), O_WRONLY | O_CREAT, 0666)) == -1) - return false; - if (fcntl(fdlock, F_SETLK, &fl) == -1) - return false; - - return true; -} -#endif //__APPLE__ namespace GUI { wxDEFINE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent); @@ -355,6 +387,9 @@ void OtherInstanceMessageHandler::init(wxEvtHandler* callback_evt_handler) void OtherInstanceMessageHandler::shutdown(MainFrame* main_frame) { BOOST_LOG_TRIVIAL(debug) << "message handler shutdown()."; +#ifndef _WIN32 + instance_check_internal::delete_lockfile(); +#endif //!_WIN32 assert(m_initialized); if (m_initialized) { #ifdef _WIN32 @@ -472,6 +507,13 @@ void OtherInstanceMessageHandler::handle_message(const std::string& message) } } +#ifdef __APPLE__ +void OtherInstanceMessageHandler::handle_message_other_closed() +{ + instance_check_internal::get_lock(wxGetApp().get_instance_hash_string() + ".lock", data_dir() + "/cache/"); +} +#endif //__APPLE__ + #ifdef BACKGROUND_MESSAGE_LISTENER namespace MessageHandlerDBusInternal diff --git a/src/slic3r/GUI/InstanceCheck.hpp b/src/slic3r/GUI/InstanceCheck.hpp index 9fb74b0a94..907b831929 100644 --- a/src/slic3r/GUI/InstanceCheck.hpp +++ b/src/slic3r/GUI/InstanceCheck.hpp @@ -28,6 +28,8 @@ bool instance_check(int argc, char** argv, bool app_config_single_instance); // apple implementation of inner functions of instance_check // in InstanceCheckMac.mm void send_message_mac(const std::string& msg, const std::string& version); +void send_message_mac_closing(const std::string& msg, const std::string& version); + bool unlock_lockfile(const std::string& name, const std::string& path); #endif //__APPLE__ @@ -66,6 +68,10 @@ public: // mac - anybody who posts notification with name:@"OtherPrusaSlicerTerminating" // linux - instrospectable on dbus void handle_message(const std::string& message); +#ifdef __APPLE__ + // Messege form other instance, that it deleted its lockfile - first instance to get it will create its own. + void handle_message_other_closed(); +#endif //__APPLE__ #ifdef _WIN32 static void init_windows_properties(MainFrame* main_frame, size_t instance_hash); #endif //WIN32 diff --git a/src/slic3r/GUI/InstanceCheckMac.h b/src/slic3r/GUI/InstanceCheckMac.h index 30943c4d53..0af2737efb 100644 --- a/src/slic3r/GUI/InstanceCheckMac.h +++ b/src/slic3r/GUI/InstanceCheckMac.h @@ -5,5 +5,6 @@ -(instancetype) init; -(void) add_observer:(NSString *)version; -(void) message_update:(NSNotification *)note; +-(void) closing_update:(NSNotification *)note; -(void) bring_forward; @end diff --git a/src/slic3r/GUI/InstanceCheckMac.mm b/src/slic3r/GUI/InstanceCheckMac.mm index 9969b1a7b2..b43e898b05 100644 --- a/src/slic3r/GUI/InstanceCheckMac.mm +++ b/src/slic3r/GUI/InstanceCheckMac.mm @@ -15,6 +15,8 @@ //NSString *nsver = @"OtherPrusaSlicerInstanceMessage" + version_hash; NSString *nsver = [NSString stringWithFormat: @"%@%@", @"OtherPrusaSlicerInstanceMessage", version_hash]; [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(message_update:) name:nsver object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; + NSString *nsver2 = [NSString stringWithFormat: @"%@%@", @"OtherPrusaSlicerInstanceClosing", version_hash]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(closing_update:) name:nsver2 object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; } -(void)message_update:(NSNotification *)msg @@ -24,6 +26,13 @@ Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message(std::string([msg.userInfo[@"data"] UTF8String])); } +-(void)closing_update:(NSNotification *)msg +{ + //[self bring_forward]; + //pass message + Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message_other_closed(); +} + -(void) bring_forward { //demiaturize all windows @@ -51,13 +60,22 @@ void send_message_mac(const std::string &msg, const std::string &version) [[NSDistributedNotificationCenter defaultCenter] postNotificationName:notifname object:nil userInfo:[NSDictionary dictionaryWithObject:nsmsg forKey:@"data"] deliverImmediately:YES]; } +void send_message_mac_closing(const std::string &msg, const std::string &version) +{ + NSString *nsmsg = [NSString stringWithCString:msg.c_str() encoding:[NSString defaultCStringEncoding]]; + //NSString *nsver = @"OtherPrusaSlicerInstanceMessage" + [NSString stringWithCString:version.c_str() encoding:[NSString defaultCStringEncoding]]; + NSString *nsver = [NSString stringWithCString:version.c_str() encoding:[NSString defaultCStringEncoding]]; + NSString *notifname = [NSString stringWithFormat: @"%@%@", @"OtherPrusaSlicerInstanceClosing", nsver]; + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:notifname object:nil userInfo:[NSDictionary dictionaryWithObject:nsmsg forKey:@"data"] deliverImmediately:YES]; +} + namespace GUI { void OtherInstanceMessageHandler::register_for_messages(const std::string &version_hash) { m_impl_osx = [[OtherInstanceMessageHandlerMac alloc] init]; if(m_impl_osx) { NSString *nsver = [NSString stringWithCString:version_hash.c_str() encoding:[NSString defaultCStringEncoding]]; - [m_impl_osx add_observer:nsver]; + [(id)m_impl_osx add_observer:nsver]; } } @@ -65,7 +83,7 @@ void OtherInstanceMessageHandler::unregister_for_messages() { //NSLog(@"unreegistering other instance messages"); if (m_impl_osx) { - [m_impl_osx release]; + [(id)m_impl_osx release]; m_impl_osx = nullptr; } else { NSLog(@"warning: unregister instance InstanceCheck notifications not required"); @@ -75,7 +93,7 @@ void OtherInstanceMessageHandler::unregister_for_messages() void OtherInstanceMessageHandler::bring_instance_forward() { if (m_impl_osx) { - [m_impl_osx bring_forward]; + [(id)m_impl_osx bring_forward]; } } }//namespace GUI diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 32375f8291..3f1207b479 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -152,7 +152,7 @@ void ArrangeJob::on_exception(const std::exception_ptr &eptr) } catch (libnest2d::GeometryException &) { show_error(m_plater, _(L("Could not arrange model objects! " "Some geometries may be invalid."))); - } catch (std::exception &e) { + } catch (std::exception &) { PlaterJob::on_exception(eptr); } } diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 11bf7f6877..04e6769e4c 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -192,7 +192,6 @@ void KBShortcutsDialog::fill_shortcuts() } Shortcuts preview_shortcuts = { -#if ENABLE_ARROW_KEYS_WITH_SLIDERS { L("Arrow Up"), L("Vertical slider - Move active thumb Up") }, { L("Arrow Down"), L("Vertical slider - Move active thumb Down") }, { L("Arrow Left"), L("Horizontal slider - Move active thumb Left") }, @@ -203,33 +202,17 @@ void KBShortcutsDialog::fill_shortcuts() { "D", L("Horizontal slider - Move active thumb Right") }, { "X", L("On/Off one layer mode of the vertical slider") }, { "L", L("Show/Hide Legend and Estimated printing time") }, -#else - { L("Arrow Up"), L("Upper layer") }, - { L("Arrow Down"), L("Lower layer") }, - { "U", L("Upper Layer") }, - { "D", L("Lower Layer") }, - { "L", L("Show/Hide Legend & Estimated printing time") }, -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS }; m_full_shortcuts.push_back({ { _L("Preview"), "" }, preview_shortcuts }); Shortcuts layers_slider_shortcuts = { -#if ENABLE_ARROW_KEYS_WITH_SLIDERS { L("Arrow Up"), L("Move active thumb Up") }, { L("Arrow Down"), L("Move active thumb Down") }, { L("Arrow Left"), L("Set upper thumb as active") }, { L("Arrow Right"), L("Set lower thumb as active") }, { "+", L("Add color change marker for current layer") }, { "-", L("Delete color change marker for current layer") }, -#else - { L("Arrow Up"), L("Move current slider thumb Up") }, - { L("Arrow Down"), L("Move current slider thumb Down") }, - { L("Arrow Left"), L("Set upper thumb to current slider thumb") }, - { L("Arrow Right"), L("Set lower thumb to current slider thumb") }, - { "+", L("Add color change marker for current layer") }, - { "-", L("Delete color change marker for current layer") }, -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS { "Shift+", L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, { ctrl, L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, }; @@ -237,15 +220,10 @@ void KBShortcutsDialog::fill_shortcuts() m_full_shortcuts.push_back({ { _L("Vertical Slider"), _L("The following shortcuts are applicable in G-code preview when the vertical slider is active") }, layers_slider_shortcuts }); Shortcuts sequential_slider_shortcuts = { -#if ENABLE_ARROW_KEYS_WITH_SLIDERS { L("Arrow Left"), L("Move active thumb Left") }, { L("Arrow Right"), L("Move active thumb Right") }, { L("Arrow Up"), L("Set left thumb as active") }, { L("Arrow Down"), L("Set right thumb as active") }, -#else - { L("Arrow Left"), L("Move active slider thumb Left") }, - { L("Arrow Right"), L("Move active slider thumb Right") }, -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS { "Shift+", L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, { ctrl, L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, }; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 8e6b1c5ef2..c6d85067e1 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -37,6 +37,7 @@ #include #include "GUI_App.hpp" +#include "UnsavedChangesDialog.hpp" #ifdef _WIN32 #include @@ -63,10 +64,10 @@ public: // Only allow opening a new PrusaSlicer instance on OSX if "single_instance" is disabled, // as starting new instances would interfere with the locking mechanism of "single_instance" support. append_menu_item(menu, wxID_ANY, _L("Open new instance"), _L("Open a new PrusaSlicer instance"), - [this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr); + [](wxCommandEvent&) { start_new_slicer(); }, "", nullptr); } append_menu_item(menu, wxID_ANY, _L("G-code preview") + dots, _L("Open G-code viewer"), - [this](wxCommandEvent&) { start_new_gcodeviewer_open_file(); }, "", nullptr); + [](wxCommandEvent&) { start_new_gcodeviewer_open_file(); }, "", nullptr); return menu; } }; @@ -77,9 +78,9 @@ public: wxMenu *CreatePopupMenu() override { wxMenu *menu = new wxMenu; append_menu_item(menu, wxID_ANY, _L("Open PrusaSlicer"), _L("Open a new PrusaSlicer instance"), - [this](wxCommandEvent&) { start_new_slicer(nullptr, true); }, "", nullptr); + [](wxCommandEvent&) { start_new_slicer(nullptr, true); }, "", nullptr); append_menu_item(menu, wxID_ANY, _L("G-code preview") + dots, _L("Open new G-code viewer"), - [this](wxCommandEvent&) { start_new_gcodeviewer_open_file(); }, "", nullptr); + [](wxCommandEvent&) { start_new_gcodeviewer_open_file(); }, "", nullptr); return menu; } }; @@ -115,6 +116,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S m_printhost_queue_dlg(new PrintHostQueueDialog(this)) , m_recent_projects(9) , m_settings_dialog(this) + , diff_dialog(this) { // Fonts were created by the DPIFrame constructor for the monitor, on which the window opened. wxGetApp().update_fonts(this); @@ -230,7 +232,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S // So, redraw explicitly canvas, when application is moved //FIXME maybe this is useful for __WXGTK3__ as well? #if __APPLE__ - Bind(wxEVT_MOVE, [this](wxMoveEvent& event) { + Bind(wxEVT_MOVE, [](wxMoveEvent& event) { wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); event.Skip(); @@ -542,6 +544,26 @@ void MainFrame::init_tabpanel() select_tab(size_t(0)); // select Plater }); +#if ENABLE_VALIDATE_CUSTOM_GCODE + m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGING, [this](wxBookCtrlEvent& evt) { + wxWindow* panel = m_tabpanel->GetCurrentPage(); + if (panel != nullptr) { + TabPrinter* printer_tab = dynamic_cast(panel); + if (printer_tab != nullptr) { + if (!printer_tab->validate_custom_gcodes()) + evt.Veto(); + return; + } + TabFilament* filament_tab = dynamic_cast(panel); + if (filament_tab != nullptr) { + if (!filament_tab->validate_custom_gcodes()) + evt.Veto(); + return; + } + } + }); +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + m_plater = new Plater(this, this); m_plater->Hide(); @@ -1189,7 +1211,11 @@ void MainFrame::init_menubar_as_editor() windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, _L("Open new instance") + "\tCtrl+Shift+I", _L("Open a new PrusaSlicer instance"), - [this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && wxGetApp().app_config->get("single_instance") != "1"; }, this); + [](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && wxGetApp().app_config->get("single_instance") != "1"; }, this); + + windowMenu->AppendSeparator(); + append_menu_item(windowMenu, wxID_ANY, _L("Compare presets")/* + "\tCtrl+F"*/, _L("Compare presets"), + [this](wxCommandEvent&) { diff_dialog.show();}, "compare", nullptr, []() {return true; }, this); } // View menu @@ -1258,8 +1284,8 @@ void MainFrame::init_menubar_as_gcodeviewer() [this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->export_toolpaths_to_obj(); }, "export_plater", nullptr, [this]() {return can_export_toolpaths(); }, this); append_menu_item(fileMenu, wxID_ANY, _L("Open &PrusaSlicer") + dots, _L("Open PrusaSlicer"), - [this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, - [this]() {return true; }, this); + [](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, + []() {return true; }, this); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), [this](wxCommandEvent&) { Close(false); }); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 9504376b45..0971fdc77a 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -16,6 +16,7 @@ #include "GUI_Utils.hpp" #include "Event.hpp" +#include "UnsavedChangesDialog.hpp" class wxNotebook; class wxProgressDialog; @@ -132,7 +133,7 @@ class MainFrame : public DPIFrame ESettingsLayout m_layout{ ESettingsLayout::Unknown }; protected: - virtual void on_dpi_changed(const wxRect &suggested_rect); + virtual void on_dpi_changed(const wxRect &suggested_rect) override; virtual void on_sys_color_changed() override; public: @@ -190,6 +191,7 @@ public: Plater* m_plater { nullptr }; wxNotebook* m_tabpanel { nullptr }; SettingsDialog m_settings_dialog; + DiffPresetDialog diff_dialog; wxWindow* m_plater_page{ nullptr }; wxProgressDialog* m_progress_dialog { nullptr }; PrintHostQueueDialog* m_printhost_queue_dlg; diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index 692ae7f1ba..9ff5688be2 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -397,7 +397,7 @@ void Mouse3DController::save_config(AppConfig &appconfig) const // We do not synchronize m_params_by_device with the background thread explicitely // as there should be a full memory barrier executed once the background thread is stopped. - for (const std::pair &key_value_pair : m_params_by_device) { + for (const auto &key_value_pair : m_params_by_device) { const std::string &device_name = key_value_pair.first; const Params ¶ms = key_value_pair.second; // Store current device parameters into the config diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index d90f4de10d..de4c7e00f2 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -107,5 +107,55 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_ Fit(); } +// WarningDialog + +WarningDialog::WarningDialog(wxWindow *parent, + const wxString& message, + const wxString& caption/* = wxEmptyString*/, + long style/* = wxOK*/) + : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_NAME) : caption, + wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE) + , msg(message) +{ + // Text shown as HTML, so that mouse selection and Ctrl-V to copy will work. + wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + { + html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), 10 * wxGetApp().em_unit())); + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont monospace = wxGetApp().code_font(); + wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); + auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + const int font_size = font.GetPointSize(); + int size[] = {font_size, font_size, font_size, font_size, font_size, font_size, font_size}; + html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size); + html->SetBorders(2); + std::string msg_escaped = xml_escape(msg.ToUTF8().data()); + boost::replace_all(msg_escaped, "\r\n", "
"); + boost::replace_all(msg_escaped, "\n", "
"); + html->SetPage("" + wxString::FromUTF8(msg_escaped.data()) + ""); + content_sizer->Add(html, 1, wxEXPAND|wxBOTTOM, BORDER); + } + + auto add_btn = [this](wxWindowID btn_id) { + auto* btn = new wxButton(this, btn_id); + btn_sizer->Add(btn, 0, wxRIGHT, HORIZ_SPACING); + btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); }); + }; + + if (style & wxOK) + add_btn(wxID_OK); + if (style & wxYES) + add_btn(wxID_YES); + if (style & wxNO) + add_btn(wxID_NO); + + logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 150)); + + SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit())); + Fit(); +} + } } diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 70032089be..20d7f8dd55 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -66,6 +66,27 @@ private: }; +// Generic error dialog, used for displaying exceptions +class WarningDialog : public MsgDialog +{ +public: + // If monospaced_font is true, the error message is displayed using html
tags, + // so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser. + WarningDialog( wxWindow *parent, + const wxString& message, + const wxString& caption = wxEmptyString, + long style = wxOK); + WarningDialog(WarningDialog&&) = delete; + WarningDialog(const WarningDialog&) = delete; + WarningDialog &operator=(WarningDialog&&) = delete; + WarningDialog &operator=(const WarningDialog&) = delete; + virtual ~WarningDialog() = default; + +private: + wxString msg; +}; + + } } diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index b0d0a556c6..a6fd9cfd3c 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -10,7 +10,8 @@ #include #include -#include +#include +#include #include @@ -18,14 +19,12 @@ static constexpr float GAP_WIDTH = 10.0f; static constexpr float SPACE_RIGHT_PANEL = 10.0f; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT static constexpr float FADING_OUT_DURATION = 2.0f; // Time in Miliseconds after next render when fading out is requested static constexpr int FADING_OUT_TIMEOUT = 100; // If timeout is changed to higher than 1 second, substract_time call should be revorked //static constexpr int MAX_TIMEOUT_MILISECONDS = 1000; //static constexpr int MAX_TIMEOUT_SECONDS = 1; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT namespace Slic3r { namespace GUI { @@ -143,12 +142,11 @@ NotificationManager::PopNotification::PopNotification(const NotificationData &n, { //init(); } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT + void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float initial_y, bool move_from_overlay, float overlay_width) { - if (!m_initialized) { + if (!m_initialized) init(); - } if (m_hidden) { m_top_y = initial_y - GAP_WIDTH; @@ -239,142 +237,7 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init if (fading_pop) ImGui::PopStyleColor(2); } -#else -NotificationManager::PopNotification::RenderResult NotificationManager::PopNotification::render(GLCanvas3D& canvas, const float& initial_y, bool move_from_overlay, float overlay_width) -{ - if (!m_initialized) { - init(); - } - if (m_finished) - return RenderResult::Finished; - if (m_close_pending) { - // request of extra frame will be done in caller function by ret val ClosePending - m_finished = true; - return RenderResult::ClosePending; - } - if (m_hidden) { - m_top_y = initial_y - GAP_WIDTH; - return RenderResult::Static; - } - RenderResult ret_val = m_counting_down ? RenderResult::Countdown : RenderResult::Static; - Size cnv_size = canvas.get_canvas_size(); - ImGuiWrapper& imgui = *wxGetApp().imgui(); - bool shown = true; - ImVec2 mouse_pos = ImGui::GetMousePos(); - float right_gap = SPACE_RIGHT_PANEL + (move_from_overlay ? overlay_width + m_line_height * 5 : 0); - if (m_line_height != ImGui::CalcTextSize("A").y) - init(); - - set_next_window_size(imgui); - - //top y of window - m_top_y = initial_y + m_window_height; - //top right position - - ImVec2 win_pos(1.0f * (float)cnv_size.get_width() - right_gap, 1.0f * (float)cnv_size.get_height() - m_top_y); - imgui.set_next_window_pos(win_pos.x, win_pos.y, ImGuiCond_Always, 1.0f, 0.0f); - imgui.set_next_window_size(m_window_width, m_window_height, ImGuiCond_Always); - - //find if hovered - if (mouse_pos.x < win_pos.x && mouse_pos.x > win_pos.x - m_window_width && mouse_pos.y > win_pos.y&& mouse_pos.y < win_pos.y + m_window_height) - { - ImGui::SetNextWindowFocus(); - ret_val = RenderResult::Hovered; - //reset fading - m_fading_out = false; - m_current_fade_opacity = 1.f; - m_remaining_time = m_data.duration; - m_countdown_frame = 0; - } - - if (m_counting_down && m_remaining_time < 0) - m_close_pending = true; - - if (m_close_pending) { - // request of extra frame will be done in caller function by ret val ClosePending - m_finished = true; - return RenderResult::ClosePending; - } - - // color change based on fading out - bool fading_pop = false; - if (m_fading_out) { - if (!m_paused) - m_current_fade_opacity -= 1.f / ((m_fading_time + 1.f) * 60.f); - Notifications_Internal::push_style_color(ImGuiCol_WindowBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg), m_fading_out, m_current_fade_opacity); - Notifications_Internal::push_style_color(ImGuiCol_Text, ImGui::GetStyleColorVec4(ImGuiCol_Text), m_fading_out, m_current_fade_opacity); - fading_pop = true; - } - // background color - if (m_is_gray) { - ImVec4 backcolor(0.7f, 0.7f, 0.7f, 0.5f); - Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_fading_out, m_current_fade_opacity); - } else if (m_data.level == NotificationLevel::ErrorNotification) { - ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg); - backcolor.x += 0.3f; - Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_fading_out, m_current_fade_opacity); - } else if (m_data.level == NotificationLevel::WarningNotification) { - ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg); - backcolor.x += 0.3f; - backcolor.y += 0.15f; - Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_fading_out, m_current_fade_opacity); - } - - //name of window - probably indentifies window and is shown so last_end add whitespaces according to id - if (! m_id) - m_id = m_id_provider.allocate_id(); - std::string name; - { - // Create a unique ImGUI window name. The name may be recycled using a name of an already released notification. - char buf[32]; - sprintf(buf, "!!Ntfctn%d", m_id); - name = buf; - } - if (imgui.begin(name, &shown, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar )) { - if (shown) { - - ImVec2 win_size = ImGui::GetWindowSize(); - - - //FIXME: dont forget to us this for texts - //GUI::format(_utf8(L())); - - /* - //countdown numbers - ImGui::SetCursorPosX(15); - ImGui::SetCursorPosY(15); - imgui.text(std::to_string(m_remaining_time).c_str()); - */ - if(m_counting_down) - render_countdown(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y); - render_left_sign(imgui); - render_text(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y); - render_close_button(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y); - m_minimize_b_visible = false; - if (m_multiline && m_lines_count > 3) - render_minimize_button(imgui, win_pos.x, win_pos.y); - } else { - // the user clicked on the [X] button ( ImGuiWindowFlags_NoTitleBar means theres no [X] button) - m_close_pending = true; - canvas.set_as_dirty(); - } - } - imgui.end(); - - if (fading_pop) { - ImGui::PopStyleColor(); - ImGui::PopStyleColor(); - } - if (m_is_gray) - ImGui::PopStyleColor(); - else if (m_data.level == NotificationLevel::ErrorNotification) - ImGui::PopStyleColor(); - else if (m_data.level == NotificationLevel::WarningNotification) - ImGui::PopStyleColor(); - return ret_val; -} -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT void NotificationManager::PopNotification::count_spaces() { //determine line width @@ -632,55 +495,7 @@ void NotificationManager::PopNotification::render_close_button(ImGuiWrapper& img ImGui::PopStyleColor(); ImGui::PopStyleColor(); } -#if !ENABLE_NEW_NOTIFICATIONS_FADE_OUT -void NotificationManager::PopNotification::render_countdown(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) -{ - /* - ImVec2 win_size(win_size_x, win_size_y); - ImVec2 win_pos(win_pos_x, win_pos_y); - - //countdown dots - std::string dot_text; - dot_text = m_remaining_time <= (float)m_data.duration / 4 * 3 ? ImGui::TimerDotEmptyMarker : ImGui::TimerDotMarker; - ImGui::SetCursorPosX(win_size.x - m_line_height); - //ImGui::SetCursorPosY(win_size.y / 2 - 24); - ImGui::SetCursorPosY(0); - imgui.text(dot_text.c_str()); - dot_text = m_remaining_time < m_data.duration / 2 ? ImGui::TimerDotEmptyMarker : ImGui::TimerDotMarker; - ImGui::SetCursorPosX(win_size.x - m_line_height); - //ImGui::SetCursorPosY(win_size.y / 2 - 9); - ImGui::SetCursorPosY(win_size.y / 2 - m_line_height / 2); - imgui.text(dot_text.c_str()); - - dot_text = m_remaining_time <= m_data.duration / 4 ? ImGui::TimerDotEmptyMarker : ImGui::TimerDotMarker; - ImGui::SetCursorPosX(win_size.x - m_line_height); - //ImGui::SetCursorPosY(win_size.y / 2 + 6); - ImGui::SetCursorPosY(win_size.y - m_line_height); - imgui.text(dot_text.c_str()); - */ - if (!m_fading_out && m_remaining_time <= m_data.duration / 4) { - m_fading_out = true; - m_fading_time = m_remaining_time; - } - - if (m_last_remaining_time != m_remaining_time) { - m_last_remaining_time = m_remaining_time; - m_countdown_frame = 0; - } - /* - //countdown line - ImVec4 orange_color = ImGui::GetStyleColorVec4(ImGuiCol_Button); - float invisible_length = ((float)(m_data.duration - m_remaining_time) / (float)m_data.duration * win_size_x); - invisible_length -= win_size_x / ((float)m_data.duration * 60.f) * (60 - m_countdown_frame); - ImVec2 lineEnd = ImVec2(win_pos_x - invisible_length, win_pos_y + win_size_y - 5); - ImVec2 lineStart = ImVec2(win_pos_x - win_size_x, win_pos_y + win_size_y - 5); - ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, IM_COL32((int)(orange_color.x * 255), (int)(orange_color.y * 255), (int)(orange_color.z * 255), (int)(orange_color.picture_width * 255.f * (m_fading_out ? m_current_fade_opacity : 1.f))), 2.f); - if (!m_paused) - m_countdown_frame++; - */ -} -#endif // !ENABLE_NEW_NOTIFICATIONS_FADE_OUT void NotificationManager::PopNotification::render_left_sign(ImGuiWrapper& imgui) { if (m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification) { @@ -740,16 +555,15 @@ void NotificationManager::PopNotification::update(const NotificationData& n) } bool NotificationManager::PopNotification::compare_text(const std::string& text) { - std::string t1(m_text1); - std::string t2(text); - t1.erase(std::remove_if(t1.begin(), t1.end(), ::isspace), t1.end()); - t2.erase(std::remove_if(t2.begin(), t2.end(), ::isspace), t2.end()); - if (t1.compare(t2) == 0) + std::wstring wt1 = boost::nowide::widen(m_text1); + std::wstring wt2 = boost::nowide::widen(text); + wt1.erase(std::remove_if(wt1.begin(), wt1.end(), ::iswspace), wt1.end()); + wt2.erase(std::remove_if(wt2.begin(), wt2.end(), ::iswspace), wt2.end()); + if (wt1.compare(wt2) == 0) return true; return false; } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT void NotificationManager::PopNotification::update_state() { if (!m_initialized) @@ -816,7 +630,6 @@ void NotificationManager::PopNotification::update_state() } } } -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT NotificationManager::SlicingCompleteLargeNotification::SlicingCompleteLargeNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, bool large) : NotificationManager::PopNotification(n, id_provider, evt_handler) @@ -1209,11 +1022,6 @@ bool NotificationManager::push_notification_data(const NotificationData& notific } bool NotificationManager::push_notification_data(std::unique_ptr notification, int timestamp) { -/* -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT - m_requires_update = true; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT -*/ // if timestamped notif, push only new one if (timestamp != 0) { if (m_used_timestamps.find(timestamp) == m_used_timestamps.end()) { @@ -1235,10 +1043,9 @@ bool NotificationManager::push_notification_data(std::unique_ptrget_current_canvas3D(); @@ -1254,71 +1061,6 @@ void NotificationManager::render_notifications(float overlay_width) } update_notifications(); } -#else -void NotificationManager::render_notifications(float overlay_width) -{ - float last_x = 0.0f; - float current_height = 0.0f; - bool request_next_frame = false; - bool render_main = false; - bool hovered = false; - sort_notifications(); - - GLCanvas3D& canvas = *wxGetApp().plater()->get_current_canvas3D(); - - // iterate thru notifications and render them / erase them - for (auto it = m_pop_notifications.begin(); it != m_pop_notifications.end();) { - if ((*it)->is_finished()) { - it = m_pop_notifications.erase(it); - } else { - (*it)->set_paused(m_hovered); - PopNotification::RenderResult res = (*it)->render(canvas, last_x, m_move_from_overlay && !m_in_preview, overlay_width); - if (res != PopNotification::RenderResult::Finished) { - last_x = (*it)->get_top() + GAP_WIDTH; - current_height = std::max(current_height, (*it)->get_current_top()); - render_main = true; - } - if (res == PopNotification::RenderResult::Countdown || res == PopNotification::RenderResult::ClosePending || res == PopNotification::RenderResult::Finished) - request_next_frame = true; - if (res == PopNotification::RenderResult::Hovered) - hovered = true; - ++it; - } - } - m_hovered = hovered; - - //actualizate timers and request frame if needed - wxWindow* p = dynamic_cast (wxGetApp().plater()); - while (p->GetParent()) - p = p->GetParent(); - wxTopLevelWindow* top_level_wnd = dynamic_cast(p); - if (!top_level_wnd->IsActive()) - return; - - { - // Control the fade-out. - // time in seconds - long now = wxGetLocalTime(); - // Pausing fade-out when the mouse is over some notification. - if (!m_hovered && m_last_time < now) - { - if (now - m_last_time == 1) - { - for (auto ¬ification : m_pop_notifications) - { - notification->substract_remaining_time(); - } - } - m_last_time = now; - } - } - - if (request_next_frame) - //FIXME this is very expensive for fade-out control. - // If any of the notifications is fading out, 100% of the CPU/GPU is consumed. - canvas.request_extra_frame(); -} -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT void NotificationManager::sort_notifications() { @@ -1370,7 +1112,6 @@ void NotificationManager::set_in_preview(bool preview) } } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT void NotificationManager::update_notifications() { // no update if not top window @@ -1467,7 +1208,6 @@ void NotificationManager::update_notifications() } */ } -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT bool NotificationManager::has_slicing_error_notification() { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index e3e50a3e37..044c204f41 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -148,13 +148,7 @@ public: void set_in_preview(bool preview); // Move to left to avoid colision with variable layer height gizmo. void set_move_from_overlay(bool move) { m_move_from_overlay = move; } -/* -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT - - bool requires_update() const { return m_requires_update; } - bool requires_render() const { return m_requires_render; } -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT -*/ + private: // duration 0 means not disapearing struct NotificationData { @@ -190,7 +184,6 @@ private: { public: -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT enum class EState { Unknown, @@ -200,32 +193,16 @@ private: ClosePending, // Requesting Render Finished, // Requesting Render }; -#else - enum class RenderResult - { - Finished, - ClosePending, - Static, - Countdown, - Hovered - }; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT PopNotification(const NotificationData &n, NotificationIDProvider &id_provider, wxEvtHandler* evt_handler); virtual ~PopNotification() { if (m_id) m_id_provider.release_id(m_id); } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT void render(GLCanvas3D& canvas, float initial_y, bool move_from_overlay, float overlay_width); -#else - RenderResult render(GLCanvas3D& canvas, const float& initial_y, bool move_from_overlay, float overlay_width); -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT // close will dissapear notification on next render void close() { m_close_pending = true; } // data from newer notification of same type void update(const NotificationData& n); bool is_finished() const { return m_finished || m_close_pending; } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT bool is_hovered() const { return m_hovered; } -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT // returns top after movement float get_top() const { return m_top_y; } //returns top in actual frame @@ -239,7 +216,6 @@ private: void set_paused(bool p) { m_paused = p; } bool compare_text(const std::string& text); void hide(bool h) { m_hidden = h; } -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT // sets m_next_render with time of next mandatory rendering void update_state(); int64_t next_render() const { return m_next_render; } @@ -248,7 +224,6 @@ private: bool requires_update() const { return m_state != EState::Hidden; } */ EState get_state() const { return m_state; } -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT protected: // Call after every size change void init(); @@ -262,11 +237,6 @@ private: virtual void render_close_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x , const float win_pos_y); -#if !ENABLE_NEW_NOTIFICATIONS_FADE_OUT - void render_countdown(ImGuiWrapper& imgui, - const float win_size_x, const float win_size_y, - const float win_pos_x , const float win_pos_y); -#endif // !ENABLE_NEW_NOTIFICATIONS_FADE_OUT virtual void render_hypertext(ImGuiWrapper& imgui, const float text_x, const float text_y, const std::string text, @@ -284,9 +254,7 @@ private: // For reusing ImGUI windows. NotificationIDProvider &m_id_provider; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT EState m_state { EState::Unknown }; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT int m_id { 0 }; bool m_initialized { false }; @@ -303,7 +271,6 @@ private: bool m_paused { false }; int m_countdown_frame { 0 }; bool m_fading_out { false }; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT int64_t m_fading_start { 0LL }; // time of last done render when fading int64_t m_last_render_fading { 0LL }; @@ -311,20 +278,14 @@ private: int64_t m_notification_start; // time to next must-do render int64_t m_next_render { std::numeric_limits::max() }; -#else - // total time left when fading beggins - float m_fading_time{ 0.0f }; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT float m_current_fade_opacity { 1.0f }; // If hidden the notif is alive but not visible to user bool m_hidden { false }; // m_finished = true - does not render, marked to delete bool m_finished { false }; // Will go to m_finished next render - bool m_close_pending { false }; -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT + bool m_close_pending { false }; bool m_hovered { false }; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT // variables to count positions correctly // all space without text float m_window_width_offset; @@ -438,11 +399,9 @@ private: void sort_notifications(); // If there is some error notification active, then the "Export G-code" notification after the slicing is finished is suppressed. bool has_slicing_error_notification(); -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT // perform update_state on each notification and ask for more frames if needed void update_notifications(); -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT - + // Target for wxWidgets events sent by clicking on the hyperlink available at some notifications. wxEvtHandler* m_evt_handler; // Cache of IDs to identify and reuse ImGUI windows. @@ -458,12 +417,7 @@ private: bool m_in_preview { false }; // True if the layer editing is enabled in Plater, so that the notifications are shifted left of it. bool m_move_from_overlay { false }; -/* -#if ENABLE_NEW_NOTIFICATIONS_FADE_OUT - bool m_requires_update{ false }; - bool m_requires_render{ false }; -#endif // ENABLE_NEW_NOTIFICATIONS_FADE_OUT -*/ + //prepared (basic) notifications const std::vector basic_notifications = { // {NotificationType::SlicingNotPossible, NotificationLevel::RegularNotification, 10, _u8L("Slicing is not possible.")}, diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index ef65f59748..7de37fb48c 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -1208,7 +1208,7 @@ void ObjectDataViewModel::AddAllChildren(const wxDataViewItem& parent) ItemAdded(parent, wxDataViewItem((void*)child)); } - for (const auto item : array) + for (const auto& item : array) AddAllChildren(item); m_ctrl->Expand(parent); @@ -1362,7 +1362,7 @@ void ObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataVie } wxDataViewItemArray new_array = array; - for (const auto item : new_array) + for (const auto& item : new_array) { wxDataViewItemArray children; GetAllChildren(item, children); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 8f5e202414..7509d40608 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -27,21 +27,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co // is the normal type. if (opt.gui_type == "select") { } else if (opt.gui_type == "select_open") { - m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, Choice::Create(this->ctrl_parent(), opt, id)); } else if (opt.gui_type == "color") { - m_fields.emplace(id, std::move(ColourPicker::Create(this->ctrl_parent(), opt, id))); - } else if (opt.gui_type == "f_enum_open" || + m_fields.emplace(id, ColourPicker::Create(this->ctrl_parent(), opt, id)); + } else if (opt.gui_type == "f_enum_open" || opt.gui_type == "i_enum_open" || opt.gui_type == "i_enum_closed") { - m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, Choice::Create(this->ctrl_parent(), opt, id)); } else if (opt.gui_type == "slider") { - m_fields.emplace(id, std::move(SliderCtrl::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, SliderCtrl::Create(this->ctrl_parent(), opt, id)); } else if (opt.gui_type == "i_spin") { // Spinctrl } else if (opt.gui_type == "legend") { // StaticText - m_fields.emplace(id, std::move(StaticText::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, StaticText::Create(this->ctrl_parent(), opt, id)); } else if (opt.gui_type == "one_string") { - m_fields.emplace(id, std::move(TextCtrl::Create(this->ctrl_parent(), opt, id))); - } else { + m_fields.emplace(id, TextCtrl::Create(this->ctrl_parent(), opt, id)); + } else { switch (opt.type) { case coFloatOrPercent: case coFloat: @@ -50,21 +50,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co case coPercents: case coString: case coStrings: - m_fields.emplace(id, std::move(TextCtrl::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, TextCtrl::Create(this->ctrl_parent(), opt, id)); break; case coBool: case coBools: - m_fields.emplace(id, std::move(CheckBox::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, CheckBox::Create(this->ctrl_parent(), opt, id)); break; case coInt: case coInts: - m_fields.emplace(id, std::move(SpinCtrl::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, SpinCtrl::Create(this->ctrl_parent(), opt, id)); break; case coEnum: - m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, Choice::Create(this->ctrl_parent(), opt, id)); break; case coPoints: - m_fields.emplace(id, std::move(PointCtrl::Create(this->ctrl_parent(), opt, id))); + m_fields.emplace(id, PointCtrl::Create(this->ctrl_parent(), opt, id)); break; case coNone: break; default: @@ -74,19 +74,19 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co // Grab a reference to fields for convenience const t_field& field = m_fields[id]; field->m_on_change = [this](const std::string& opt_id, const boost::any& value) { - //! This function will be called from Field. + //! This function will be called from Field. //! Call OptionGroup._on_change(...) - if (!m_disabled) + if (!m_disabled) this->on_change_OG(opt_id, value); }; field->m_on_kill_focus = [this](const std::string& opt_id) { - //! This function will be called from Field. - if (!m_disabled) + //! This function will be called from Field. + if (!m_disabled) this->on_kill_focus(opt_id); }; field->m_on_set_focus = [this](const std::string& opt_id) { - //! This function will be called from Field. - if (!m_disabled) + //! This function will be called from Field. + if (!m_disabled) this->on_set_focus(opt_id); }; field->m_parent = parent(); @@ -99,7 +99,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co if (!this->m_disabled) this->back_to_sys_value(opt_id); }; - + // assign function objects for callbacks, etc. return field; } @@ -178,7 +178,7 @@ void OptionsGroup::append_line(const Line& line) return; auto option_set = line.get_options(); - for (auto opt : option_set) + for (auto opt : option_set) m_options.emplace(opt.opt_id, opt); // add mode value for current line to m_options_mode @@ -232,7 +232,7 @@ void OptionsGroup::activate_line(Line& line) // if we have a single option with no label, no sidetext just add it directly to sizer if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width && option_set.front().opt.label.empty() && - option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && + option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { const auto& option = option_set.front(); @@ -334,7 +334,7 @@ void OptionsGroup::activate_line(Line& line) wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ? _CTX(option.label, "Layers") : _(option.label); - label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize); + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize); wxSize(sublabel_width != -1 ? sublabel_width * wxGetApp().em_unit() : -1, -1), wxALIGN_RIGHT); label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetFont(wxGetApp().normal_font()); @@ -379,7 +379,7 @@ void OptionsGroup::activate_line(Line& line) } // add extra sizers if any - for (auto extra_widget : line.get_extra_widgets()) + for (auto extra_widget : line.get_extra_widgets()) { if (line.get_extra_widgets().size() == 1 && !staticbox) { @@ -504,7 +504,7 @@ void OptionsGroup::clear_fields_except_of(const std::vector left_fi while (it != m_fields.end()) { if (std::find(left_fields.begin(), left_fields.end(), it->first) == left_fields.end()) it = m_fields.erase(it); - else + else it++; } } @@ -530,7 +530,7 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index std::pair pair(opt_key, opt_index); m_opt_map.emplace(opt_id, pair); - if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab + if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab wxGetApp().sidebar().get_searcher().add_key(opt_id, title, this->config_category()); return Option(*m_config->def()->get(opt_key), opt_id); @@ -545,7 +545,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b { OptionsGroup::on_change_OG(opt_id, value); return; - } + } auto itOption = it->second; const std::string &opt_key = itOption.first; @@ -554,7 +554,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b this->change_opt_value(opt_key, value, opt_index == -1 ? 0 : opt_index); } - OptionsGroup::on_change_OG(opt_id, value); + OptionsGroup::on_change_OG(opt_id, value); } void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key) @@ -582,7 +582,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, } else if (m_opt_map.find(opt_key) == m_opt_map.end() || // This option don't have corresponded field - opt_key == "bed_shape" || opt_key == "filament_ramming_parameters" || + opt_key == "bed_shape" || opt_key == "filament_ramming_parameters" || opt_key == "compatible_printers" || opt_key == "compatible_prints" ) { value = get_config_value(config, opt_key); this->change_opt_value(opt_key, value); @@ -765,7 +765,7 @@ boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index /*= -1*/) { size_t idx = opt_index == -1 ? 0 : opt_index; - + boost::any ret; wxString text_value = wxString(""); const ConfigOptionDef* opt = config.def()->get(opt_key); @@ -869,12 +869,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config else if (opt_key == "ironing_type") { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key == "fuzzy_skin_perimeter_mode") { - ret = static_cast(config.option>(opt_key)->value); + else if (opt_key == "fuzzy_skin") { + ret = static_cast(config.option>(opt_key)->value); } -// else if (opt_key == "fuzzy_skin_shape") { -// ret = static_cast(config.option>(opt_key)->value); -// } else if (opt_key == "gcode_flavor") { ret = static_cast(config.option>(opt_key)->value); } @@ -899,6 +896,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config else if (opt_key == "printhost_authorization_type") { ret = static_cast(config.option>(opt_key)->value); } + else if (opt_key == "brim_type") { + ret = static_cast(config.option>(opt_key)->value); + } } break; case coPoints: @@ -955,7 +955,7 @@ void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, co m_modelconfig->touch(); } -ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) : +ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) { if (!text.IsEmpty()) { diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 5bc2d45959..f19a3e0336 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -273,7 +273,6 @@ private: const DynamicPrintConfig* m_config {nullptr}; // If the config is modelconfig, then ModelConfig::touch() has to be called after value change. ModelConfig* m_modelconfig { nullptr }; - bool m_full_labels{ 0 }; t_opt_map m_opt_map; std::string m_config_category; diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 620a3ddcad..8b16575ba8 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -275,7 +275,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr m_optgroup->append_single_option_line("host_type"); - auto create_sizer_with_btn = [this](wxWindow* parent, ScalableButton** btn, const std::string& icon_name, const wxString& label) { + auto create_sizer_with_btn = [](wxWindow* parent, ScalableButton** btn, const std::string& icon_name, const wxString& label) { *btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT); (*btn)->SetFont(wxGetApp().normal_font()); @@ -290,7 +290,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr m_printhost_browse_btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) { BonjourDialog dialog(this, Preset::printer_technology(m_printer.config)); if (dialog.show_and_lookup()) { - m_optgroup->set_value("print_host", std::move(dialog.get_selected()), true); + m_optgroup->set_value("print_host", dialog.get_selected(), true); m_optgroup->get_field("print_host")->field_changed(); } }); @@ -366,7 +366,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr static const auto filemasks = _L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"); wxFileDialog openFileDialog(this, _L("Open CA certificate file"), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (openFileDialog.ShowModal() != wxID_CANCEL) { - m_optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true); + m_optgroup->set_value("printhost_cafile", openFileDialog.GetPath(), true); m_optgroup->get_field("printhost_cafile")->field_changed(); } }); @@ -379,7 +379,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr Line cafile_hint{ "", "" }; cafile_hint.full_width = 1; - cafile_hint.widget = [this, ca_file_hint](wxWindow* parent) { + cafile_hint.widget = [ca_file_hint](wxWindow* parent) { auto txt = new wxStaticText(parent, wxID_ANY, ca_file_hint); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(txt); @@ -420,7 +420,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr { wxTextCtrl* temp = dynamic_cast(printhost_field->getWindow()); if (temp) - temp->Bind(wxEVT_TEXT, ([this, printhost_field, temp](wxEvent& e) + temp->Bind(wxEVT_TEXT, ([printhost_field, temp](wxEvent& e) { #ifndef __WXGTK__ e.Skip(); @@ -572,12 +572,17 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event) if (!repeat_presets.empty()) { wxString repeatable_presets = "\n"; - for (const std::string& preset_name : repeat_presets) + int repeat_cnt = 0; + for (const std::string& preset_name : repeat_presets) { repeatable_presets += " " + from_u8(preset_name) + "\n"; + repeat_cnt++; + } repeatable_presets += "\n"; - wxString msg_text = from_u8((boost::format(_u8L("Following printer preset(s) is duplicated:%1%" - "The above preset for printer \"%2%\" will be used just once.")) % repeatable_presets % printer_name).str()); + wxString msg_text = format_wxstr(_L_PLURAL("Following printer preset is duplicated:%1%" + "The above preset for printer \"%2%\" will be used just once.", + "Following printer presets are duplicated:%1%" + "The above presets for printer \"%2%\" will be used just once.", repeat_cnt), repeatable_presets, printer_name); wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxOK | wxCANCEL); if (dialog.ShowModal() == wxID_CANCEL) return; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8b42745790..6400bbbcc6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -274,7 +274,7 @@ public: wxButton* get_wiping_dialog_button() { return m_wiping_dialog_button; } wxSizer* get_sizer() override; ConfigOptionsGroup* get_og(const bool is_fff); - void Show(const bool is_fff); + void Show(const bool is_fff) override; void msw_rescale(); }; @@ -790,6 +790,9 @@ Sidebar::Sidebar(Plater *parent) p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(false); }); p->btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + if (p->plater->canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) + return; + const bool export_gcode_after_slicing = wxGetKeyState(WXK_SHIFT); if (export_gcode_after_slicing) p->plater->export_gcode(true); @@ -1065,18 +1068,29 @@ void Sidebar::show_info_sizer() const auto& stats = model_object->get_object_stl_stats();//model_object->volumes.front()->mesh.stl.stats; p->object_info->info_volume->SetLabel(wxString::Format("%.2f", stats.volume*pow(koef,3))); - p->object_info->info_facets->SetLabel(wxString::Format(_L("%d (%d shells)"), static_cast(model_object->facets_count()), stats.number_of_parts)); + p->object_info->info_facets->SetLabel(format_wxstr(_L_PLURAL("%1% (%2$d shell)", "%1% (%2$d shells)", stats.number_of_parts), + static_cast(model_object->facets_count()), stats.number_of_parts)); int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_added + stats.facets_reversed + stats.backwards_edges; if (errors > 0) { - wxString tooltip = wxString::Format(_L("Auto-repaired (%d errors)"), errors); + wxString tooltip = format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors); p->object_info->info_manifold->SetLabel(tooltip); - tooltip += ":\n" + wxString::Format(_L("%d degenerate facets, %d edges fixed, %d facets removed, " - "%d facets added, %d facets reversed, %d backwards edges"), - stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, - stats.facets_added, stats.facets_reversed, stats.backwards_edges); + tooltip += ":\n"; + if (stats.degenerate_facets > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d degenerate facet", "%1$d degenerate facets", stats.degenerate_facets), stats.degenerate_facets) + ", "; + if (stats.edges_fixed > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d edge fixed", "%1$d edges fixed", stats.edges_fixed), stats.edges_fixed) + ", "; + if (stats.facets_removed > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d facet removed", "%1$d facets removed", stats.facets_removed), stats.facets_removed) + ", "; + if (stats.facets_added > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d facet added", "%1$d facets added", stats.facets_added), stats.facets_added) + ", "; + if (stats.facets_reversed > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d facet reversed", "%1$d facets reversed", stats.facets_reversed), stats.facets_reversed) + ", "; + if (stats.backwards_edges > 0) + tooltip += format_wxstr(_L_PLURAL("%1$d backwards edge", "%1$d backwards edges", stats.backwards_edges), stats.backwards_edges) + ", "; + tooltip.RemoveLast(2);//remove last coma p->object_info->showing_manifold_warning_icon = true; p->object_info->info_manifold->SetToolTip(tooltip); @@ -1107,7 +1121,7 @@ void Sidebar::update_sliced_info_sizer() wxString new_label = _L("Used Material (ml)") + ":"; const bool is_supports = ps.support_used_material > 0.0; if (is_supports) - new_label += format_wxstr("\n - %s\n - %s", _L("object(s)"), _L("supports and pad")); + new_label += format_wxstr("\n - %s\n - %s", _L_PLURAL("object", "objects", p->plater->model().objects.size()), _L("supports and pad")); wxString info_text = is_supports ? wxString::Format("%.2f \n%.2f \n%.2f", (ps.objects_used_material + ps.support_used_material) / 1000, @@ -1364,200 +1378,16 @@ public: private: Plater* m_plater; - -#if !ENABLE_DRAG_AND_DROP_FIX - static const std::regex pattern_drop; - static const std::regex pattern_gcode_drop; -#endif // !ENABLE_DRAG_AND_DROP_FIX }; -#if !ENABLE_DRAG_AND_DROP_FIX -const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", std::regex::icase); -const std::regex PlaterDropTarget::pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase); - -enum class LoadType : unsigned char -{ - Unknown, - OpenProject, - LoadGeometry, - LoadConfig -}; - -class ProjectDropDialog : public DPIDialog -{ - wxRadioBox* m_action{ nullptr }; -public: - ProjectDropDialog(const std::string& filename); - - int get_action() const { return m_action->GetSelection() + 1; } - -protected: - void on_dpi_changed(const wxRect& suggested_rect) override; -}; - -ProjectDropDialog::ProjectDropDialog(const std::string& filename) - : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, - from_u8((boost::format(_utf8(L("%s - Drop project file"))) % SLIC3R_APP_NAME).str()), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_DIALOG_STYLE) -{ - SetFont(wxGetApp().normal_font()); - - wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); - - const wxString choices[] = { _L("Open as project"), - _L("Import geometry only"), - _L("Import config only") }; - - main_sizer->Add(new wxStaticText(this, wxID_ANY, - _L("Select an action to apply to the file") + ": " + from_u8(filename)), 0, wxEXPAND | wxALL, 10); - m_action = new wxRadioBox(this, wxID_ANY, _L("Action"), wxDefaultPosition, wxDefaultSize, - WXSIZEOF(choices), choices, 0, wxRA_SPECIFY_ROWS); - int action = std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")), - static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig)) - 1; - m_action->SetSelection(action); - main_sizer->Add(m_action, 1, wxEXPAND | wxRIGHT | wxLEFT, 10); - - wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); - wxCheckBox* check = new wxCheckBox(this, wxID_ANY, _L("Don't show again")); - check->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& evt) { - wxGetApp().app_config->set("show_drop_project_dialog", evt.IsChecked() ? "0" : "1"); - }); - - bottom_sizer->Add(check, 0, wxEXPAND | wxRIGHT, 5); - bottom_sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT, 5); - main_sizer->Add(bottom_sizer, 0, wxEXPAND | wxALL, 10); - - SetSizer(main_sizer); - main_sizer->SetSizeHints(this); -} - -void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect) -{ - const int em = em_unit(); - SetMinSize(wxSize(65 * em, 30 * em)); - Fit(); - Refresh(); -} -#endif // !ENABLE_DRAG_AND_DROP_FIX - bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) { -#if !ENABLE_DRAG_AND_DROP_FIX - std::vector paths; -#endif // !ENABLE_DRAG_AND_DROP_FIX - #ifdef WIN32 // hides the system icon this->MSWUpdateDragImageOnLeave(); #endif // WIN32 -#if ENABLE_DRAG_AND_DROP_FIX return (m_plater != nullptr) ? m_plater->load_files(filenames) : false; -#else - // gcode viewer section - if (wxGetApp().is_gcode_viewer()) { - for (const auto& filename : filenames) { - fs::path path(into_path(filename)); - if (std::regex_match(path.string(), pattern_gcode_drop)) - paths.push_back(std::move(path)); - } - - if (paths.size() > 1) { - wxMessageDialog(static_cast(m_plater), _L("You can open only one .gcode file at a time."), - wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); - return false; - } - else if (paths.size() == 1) { - m_plater->load_gcode(from_path(paths.front())); - return true; - } - return false; - } - - // editor section - for (const auto &filename : filenames) { - fs::path path(into_path(filename)); - if (std::regex_match(path.string(), pattern_drop)) - paths.push_back(std::move(path)); - else if (std::regex_match(path.string(), pattern_gcode_drop)) - start_new_gcodeviewer(&filename); - else - return false; - } - if (paths.empty()) - // Likely all paths processed were gcodes, for which a G-code viewer instance has hopefully been started. - return false; - - // searches for project files - for (std::vector::const_reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) { - std::string filename = (*it).filename().string(); - if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) { - LoadType load_type = LoadType::Unknown; - if (!m_plater->model().objects.empty()) { - if (wxGetApp().app_config->get("show_drop_project_dialog") == "1") { - ProjectDropDialog dlg(filename); - if (dlg.ShowModal() == wxID_OK) { - int choice = dlg.get_action(); - load_type = static_cast(choice); - wxGetApp().app_config->set("drop_project_action", std::to_string(choice)); - } - } - else - load_type = static_cast(std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")), - static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig))); - } - else - load_type = LoadType::OpenProject; - - if (load_type == LoadType::Unknown) - return false; - - switch (load_type) { - case LoadType::OpenProject: { - m_plater->load_project(from_path(*it)); - break; - } - case LoadType::LoadGeometry: { - Plater::TakeSnapshot snapshot(m_plater, _L("Import Object")); - std::vector in_paths; - in_paths.emplace_back(*it); - m_plater->load_files(in_paths, true, false); - break; - } - case LoadType::LoadConfig: { - std::vector in_paths; - in_paths.emplace_back(*it); - m_plater->load_files(in_paths, false, true); - break; - } - } - - return true; - } - } - - // other files - wxString snapshot_label; - assert(!paths.empty()); - if (paths.size() == 1) { - snapshot_label = _L("Load File"); - snapshot_label += ": "; - snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); - } - else { - snapshot_label = _L("Load Files"); - snapshot_label += ": "; - snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str()); - for (size_t i = 1; i < paths.size(); ++i) { - snapshot_label += ", "; - snapshot_label += wxString::FromUTF8(paths[i].filename().string().c_str()); - } - } - Plater::TakeSnapshot snapshot(m_plater, snapshot_label); - m_plater->load_files(paths); - - return true; -#endif // ENABLE_DRAG_AND_DROP_FIX } // State to manage showing after export notifications and device ejecting @@ -1924,7 +1754,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) , main_frame(main_frame) , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ "bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", - "brim_width", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material", + "brim_width", "brim_offset", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology", // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. @@ -2054,21 +1884,17 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); // Preview events: - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); if (wxGetApp().is_editor()) { preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); } preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_JUMP_TO, [this](wxKeyEvent& evt) { preview->jump_layers_slider(evt); }); -#if ENABLE_ARROW_KEYS_WITH_SLIDERS preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_SLIDERS, [this](wxKeyEvent& evt) { preview->move_layers_slider(evt); preview->move_moves_slider(evt); }); -#else - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, [this](wxKeyEvent& evt) { preview->move_layers_slider(evt); }); -#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_layers_slider(evt); }); if (wxGetApp().is_gcode_viewer()) preview->Bind(EVT_GLCANVAS_RELOAD_FROM_DISK, [this](SimpleEvent&) { this->q->reload_gcode_from_disk(); }); @@ -2116,8 +1942,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) if (wxGetApp().is_editor()) { this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); }); this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); }); - this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [this](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); - this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this, q](RemovableDriveEjectEvent &evt) { + this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); + this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) { if (evt.data.second) { this->show_action_buttons(this->ready_to_slice); notification_manager->close_notification_of_type(NotificationType::ExportFinished); @@ -2132,7 +1958,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) ); } }); - this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this, q](RemovableDrivesChangedEvent &) { + this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this](RemovableDrivesChangedEvent &) { this->show_action_buttons(this->ready_to_slice); // Close notification ExportingFinished but only if last export was to removable notification_manager->device_ejected(); @@ -2149,7 +1975,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // Initialize the Undo / Redo stack with a first snapshot. this->take_snapshot(_L("New Project")); -#if ENABLE_DRAG_AND_DROP_FIX this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent& evt) { BOOST_LOG_TRIVIAL(trace) << "Received load from other instance event."; wxArrayString input_files; @@ -2159,12 +1984,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) wxGetApp().mainframe->Raise(); this->q->load_files(input_files); }); -#else - this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent &evt) { - BOOST_LOG_TRIVIAL(trace) << "Received load from other instance event."; - this->load_files(evt.data, true, true); - }); -#endif // ENABLE_DRAG_AND_DROP_FIX this->q->Bind(EVT_INSTANCE_GO_TO_FRONT, [this](InstanceGoToFrontEvent &) { bring_instance_forward(); }); @@ -2404,17 +2223,30 @@ std::vector Plater::priv::load_files(const std::vector& input_ auto convert_from_imperial_units = [](Model& model, bool only_small_volumes) { model.convert_from_imperial_units(only_small_volumes); // wxGetApp().app_config->set("use_inches", "1"); - wxGetApp().sidebar().update_ui_from_settings(); +// wxGetApp().sidebar().update_ui_from_settings(); }; if (!is_project_file) { if (imperial_units) // Convert even if the object is big. convert_from_imperial_units(model, false); + else if (model.looks_like_saved_in_meters()) { + wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( + "The object in file %s looks like saved in meters.\n" + "Should I consider it as a saved in meters and convert it?", + "Some objects in file %s look like saved in meters.\n" + "Should I consider them as a saved in meters and convert them?", model.objects.size()), from_path(filename)) + "\n", + _L("The object appears to be saved in meters"), wxICON_WARNING | wxYES | wxNO); + if (msg_dlg.ShowModal() == wxID_YES) + //FIXME up-scale only the small parts? + model.convert_from_meters(true); + } else if (model.looks_like_imperial_units()) { - wxMessageDialog msg_dlg(q, format_wxstr(_L( - "Some object(s) in file %s looks like saved in inches.\n" - "Should I consider them as a saved in inches and convert them?"), from_path(filename)) + "\n", + wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( + "The object in file %s looks like saved in inches.\n" + "Should I consider it as a saved in inches and convert it?", + "Some objects in file %s look like saved in inches.\n" + "Should I consider them as a saved in inches and convert them?", model.objects.size()), from_path(filename)) + "\n", _L("The object appears to be saved in inches"), wxICON_WARNING | wxYES | wxNO); if (msg_dlg.ShowModal() == wxID_YES) //FIXME up-scale only the small parts? @@ -2868,10 +2700,6 @@ void Plater::priv::split_object() { Plater::TakeSnapshot snapshot(q, _L("Split to Objects")); - unsigned int counter = 1; - for (ModelObject* m : new_objects) - m->name = current_model_object->name + "_" + std::to_string(counter++); - remove(obj_idx); // load all model objects at once, otherwise the plate would be rearranged after each one @@ -3309,6 +3137,10 @@ void Plater::priv::reload_from_disk() new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); if (old_volume->source.is_converted_from_inches) new_volume->convert_from_imperial_units(); + if (old_volume->source.is_converted_from_meters) + new_volume->convert_from_meters(); + new_volume->supported_facets.assign(old_volume->supported_facets); + new_volume->seam_facets.assign(old_volume->seam_facets); std::swap(old_model_object->volumes[sel_v.volume_idx], old_model_object->volumes.back()); old_model_object->delete_volume(old_model_object->volumes.size() - 1); old_model_object->ensure_on_bed(); @@ -3696,7 +3528,7 @@ bool Plater::priv::warnings_dialog() text += it.first.message; } //text += "\n\nDo you still wish to export?"; - wxMessageDialog msg_wingow(this->q, text, wxString(SLIC3R_APP_NAME " ") + _L("generated warnings"), wxOK); + wxMessageDialog msg_wingow(this->q, from_u8(text), wxString(SLIC3R_APP_NAME " ") + _L("generated warnings"), wxOK); const auto res = msg_wingow.ShowModal(); return res == wxID_OK; @@ -3849,7 +3681,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) menu_item_convert_unit_position = 2; } - sidebar->obj_list()->append_menu_item_convert_unit(menu, menu_item_convert_unit_position); + sidebar->obj_list()->append_menu_items_convert_unit(menu, menu_item_convert_unit_position); sidebar->obj_list()->append_menu_item_settings(menu); if (printer_technology != ptSLA) @@ -4385,9 +4217,9 @@ bool Plater::priv::can_fix_through_netfabb() const bool Plater::priv::can_increase_instances() const { - if (m_ui_jobs.is_any_running()) { - return false; - } + if (m_ui_jobs.is_any_running() + || q->canvas3D()->get_gizmos_manager().is_in_editing_mode()) + return false; int obj_idx = get_selected_object_idx(); return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()); @@ -4395,9 +4227,9 @@ bool Plater::priv::can_increase_instances() const bool Plater::priv::can_decrease_instances() const { - if (m_ui_jobs.is_any_running()) { - return false; - } + if (m_ui_jobs.is_any_running() + || q->canvas3D()->get_gizmos_manager().is_in_editing_mode()) + return false; int obj_idx = get_selected_object_idx(); return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1); @@ -4903,7 +4735,6 @@ std::vector Plater::load_files(const std::vector& input_fil return p->load_files(paths, load_model, load_config, imperial_units); } -#if ENABLE_DRAG_AND_DROP_FIX enum class LoadType : unsigned char { Unknown, @@ -4948,7 +4779,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string& filename) wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); wxCheckBox* check = new wxCheckBox(this, wxID_ANY, _L("Don't show again")); - check->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& evt) { + check->Bind(wxEVT_CHECKBOX, [](wxCommandEvent& evt) { wxGetApp().app_config->set("show_drop_project_dialog", evt.IsChecked() ? "0" : "1"); }); @@ -5083,7 +4914,6 @@ bool Plater::load_files(const wxArrayString& filenames) return true; } -#endif // ENABLE_DRAG_AND_DROP_FIX void Plater::update() { p->update(); } @@ -5224,20 +5054,22 @@ void Plater::scale_selection_to_fit_print_volume() p->scale_selection_to_fit_print_volume(); } -void Plater::convert_unit(bool from_imperial_unit) +void Plater::convert_unit(ConversionType conv_type) { std::vector obj_idxs, volume_idxs; wxGetApp().obj_list()->get_selection_indexes(obj_idxs, volume_idxs); if (obj_idxs.empty() && volume_idxs.empty()) return; - TakeSnapshot snapshot(this, from_imperial_unit ? _L("Convert from imperial units") : _L("Revert conversion from imperial units")); + TakeSnapshot snapshot(this, conv_type == ConversionType::CONV_FROM_INCH ? _L("Convert from imperial units") : + conv_type == ConversionType::CONV_TO_INCH ? _L("Revert conversion from imperial units") : + conv_type == ConversionType::CONV_FROM_METER ? _L("Convert from meters") : _L("Revert conversion from meters")); wxBusyCursor wait; ModelObjectPtrs objects; for (int obj_idx : obj_idxs) { ModelObject *object = p->model.objects[obj_idx]; - object->convert_units(objects, from_imperial_unit, volume_idxs); + object->convert_units(objects, conv_type, volume_idxs); remove(obj_idx); } p->load_model_objects(objects); @@ -5287,6 +5119,10 @@ void Plater::export_gcode(bool prefer_removable) if (p->model.objects.empty()) return; + if (canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) + return; + + if (p->process_completed_with_error) return; @@ -5562,6 +5398,11 @@ void Plater::reslice() if (p->process_completed_with_error) return; + // In case SLA gizmo is in editing mode, refuse to continue + // and notify user that he should leave it first. + if (canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) + return; + // Stop arrange and (or) optimize rotation tasks. this->stop_jobs(); @@ -5603,12 +5444,7 @@ void Plater::reslice() if (clean_gcode_toolpaths) reset_gcode_toolpaths(); -#if ENABLE_PREVIEW_TYPE_CHANGE p->preview->reload_print(!clean_gcode_toolpaths); -#else - // update type of preview - p->preview->update_view_type(!clean_gcode_toolpaths); -#endif // ENABLE_PREVIEW_TYPE_CHANGE } void Plater::reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages) @@ -5817,8 +5653,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) bool update_scheduled = false; bool bed_shape_changed = false; for (auto opt_key : p->config->diff(config)) { - if (opt_key == "filament_colour") - { + if (opt_key == "filament_colour") { update_scheduled = true; // update should be scheduled (for update 3DScene) #2738 if (update_filament_colors_in_full_config()) { @@ -5852,14 +5687,12 @@ void Plater::on_config_change(const DynamicPrintConfig &config) } else if(opt_key == "extruder_colour") { update_scheduled = true; -#if !ENABLE_PREVIEW_TYPE_CHANGE - p->preview->set_number_extruders(p->config->option(opt_key)->values.size()); -#endif // !ENABLE_PREVIEW_TYPE_CHANGE p->sidebar->obj_list()->update_extruder_colors(); - } else if(opt_key == "max_print_height") { - update_scheduled = true; } + else if(opt_key == "max_print_height") + update_scheduled = true; else if (opt_key == "printer_model") { + p->reset_gcode_toolpaths(); // update to force bed selection(for texturing) bed_shape_changed = true; update_scheduled = true; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5407a6e858..82afdcc3dd 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -28,6 +28,7 @@ class ModelInstance; class Print; class SLAPrint; enum SLAPrintObjectStep : unsigned int; +enum class ConversionType : int; using ModelInstancePtrs = std::vector; @@ -150,10 +151,8 @@ public: std::vector load_files(const std::vector& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false); // To be called when providing a list of files to the GUI slic3r on command line. std::vector load_files(const std::vector& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false); -#if ENABLE_DRAG_AND_DROP_FIX // to be called on drag and drop bool load_files(const wxArrayString& filenames); -#endif // ENABLE_DRAG_AND_DROP_FIX const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; } @@ -191,7 +190,7 @@ public: void fill_bed_with_instances(); bool is_selection_empty() const; void scale_selection_to_fit_print_volume(); - void convert_unit(bool from_imperial_unit); + void convert_unit(ConversionType conv_type); void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 0a8a6c886e..cba941a396 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -39,7 +39,7 @@ static void activate_options_tab(std::shared_ptr optgroup) optgroup->activate(); optgroup->update_visibility(comSimple); wxBoxSizer* sizer = static_cast(static_cast(optgroup->parent())->GetSizer()); - sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 20); + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); } void PreferencesDialog::build() @@ -275,12 +275,22 @@ void PreferencesDialog::build() def.label = L("Sequential slider applied only to top layer"); def.type = coBool; - def.tooltip = L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer. " + def.tooltip = L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer." "If disabled, changes made using the sequential slider, in preview, apply to the whole gcode."); def.set_default_value(new ConfigOptionBool{ app_config->get("seq_top_layer_only") == "1" }); option = Option(def, "seq_top_layer_only"); m_optgroup_gui->append_single_option_line(option); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + def.label = L("Sequential slider shows gcode line numbers"); + def.type = coBool; + def.tooltip = L("If enabled, the sequential slider, in preview, shows the gcode lines numbers." + "If disabled, the sequential slider, in preview, shows the move index."); + def.set_default_value(new ConfigOptionBool{ app_config->get("seq_top_gcode_indices") == "1" }); + option = Option(def, "seq_top_gcode_indices"); + m_optgroup_gui->append_single_option_line(option); +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (is_editor) { def.label = L("Show sidebar collapse/expand button"); def.type = coBool; @@ -297,6 +307,14 @@ void PreferencesDialog::build() option = Option(def, "suppress_hyperlinks"); m_optgroup_gui->append_single_option_line(option); + def.label = L("Use colors for axes values in Manipulation panel"); + def.type = coBool; + def.tooltip = L("If enabled, the axes names and axes values will be colorized according to the axes colors. " + "If disabled, old UI will be used."); + def.set_default_value(new ConfigOptionBool{ app_config->get("color_mapinulation_panel") == "1" }); + option = Option(def, "color_mapinulation_panel"); + m_optgroup_gui->append_single_option_line(option); + def.label = L("Use custom size for toolbar icons"); def.type = coBool; def.tooltip = L("If enabled, you can change size of toolbar icons manually."); @@ -358,6 +376,12 @@ void PreferencesDialog::accept() if (auto it = m_values.find("seq_top_layer_only"); it != m_values.end()) m_seq_top_layer_only_changed = app_config->get("seq_top_layer_only") != it->second; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_seq_top_gcode_indices_changed = false; + if (auto it = m_values.find("seq_top_gcode_indices"); it != m_values.end()) + m_seq_top_gcode_indices_changed = app_config->get("seq_top_gcode_indices") != it->second; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + m_settings_layout_changed = false; for (const std::string& key : { "old_settings_layout_mode", "new_settings_layout_mode", @@ -380,9 +404,10 @@ void PreferencesDialog::accept() app_config->set(it->first, it->second); app_config->save(); - - wxGetApp().set_label_clr_sys(m_sys_colour->GetColour()); - wxGetApp().set_label_clr_modified(m_mod_colour->GetColour()); + if (wxGetApp().is_editor()) { + wxGetApp().set_label_clr_sys(m_sys_colour->GetColour()); + wxGetApp().set_label_clr_modified(m_mod_colour->GetColour()); + } EndModal(wxID_OK); @@ -500,7 +525,7 @@ void PreferencesDialog::create_settings_mode_widget() auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_layout_mode_box, 1, wxALIGN_CENTER_VERTICAL); - m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND); + m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit()); } void PreferencesDialog::create_settings_text_color_widget() @@ -511,7 +536,7 @@ void PreferencesDialog::create_settings_text_color_widget() if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT); wxSizer* sizer = new wxStaticBoxSizer(stb, wxVERTICAL); - wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(2, 10, 20); + wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(2, 5, 5); sizer->Add(grid_sizer, 0, wxEXPAND); auto sys_label = new wxStaticText(parent, wxID_ANY, _L("Value is the same as the system value")); @@ -522,8 +547,8 @@ void PreferencesDialog::create_settings_text_color_widget() sys_label->Refresh(); }); - grid_sizer->Add(m_sys_colour, -1, wxALIGN_CENTRE_VERTICAL); - grid_sizer->Add(sys_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); + grid_sizer->Add(m_sys_colour, 0, wxALIGN_CENTRE_VERTICAL); + grid_sizer->Add(sys_label, 0, wxALIGN_CENTRE_VERTICAL | wxEXPAND); auto mod_label = new wxStaticText(parent, wxID_ANY, _L("Value was changed and is not equal to the system value or the last saved preset")); mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified()); @@ -533,8 +558,8 @@ void PreferencesDialog::create_settings_text_color_widget() mod_label->Refresh(); }); - grid_sizer->Add(m_mod_colour, -1, wxALIGN_CENTRE_VERTICAL); - grid_sizer->Add(mod_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); + grid_sizer->Add(m_mod_colour, 0, wxALIGN_CENTRE_VERTICAL); + grid_sizer->Add(mod_label, 0, wxALIGN_CENTRE_VERTICAL | wxEXPAND); m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit()); } diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 0da0447365..68e75662ae 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -31,12 +31,19 @@ class PreferencesDialog : public DPIDialog bool isOSX {false}; bool m_settings_layout_changed {false}; bool m_seq_top_layer_only_changed{ false }; +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + bool m_seq_top_gcode_indices_changed{ false }; +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + public: - PreferencesDialog(wxWindow* parent); - ~PreferencesDialog() {} + explicit PreferencesDialog(wxWindow* parent); + ~PreferencesDialog() = default; bool settings_layout_changed() const { return m_settings_layout_changed; } bool seq_top_layer_only_changed() const { return m_seq_top_layer_only_changed; } +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + bool seq_seq_top_gcode_indices_changed() const { return m_seq_top_gcode_indices_changed; } +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER void build(); void accept(); diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 60bb9a5aeb..0754df5712 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -62,12 +62,12 @@ namespace GUI { * control size calculation methods (virtual) are overridden. **/ -PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size) : +PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size, PresetBundle* preset_bundle/* = nullptr*/) : wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY), m_type(preset_type), m_last_selected(wxNOT_FOUND), m_em_unit(em_unit(this)), - m_preset_bundle(wxGetApp().preset_bundle) + m_preset_bundle(preset_bundle ? preset_bundle : wxGetApp().preset_bundle) { SetFont(wxGetApp().normal_font()); #ifdef _WIN32 @@ -186,6 +186,12 @@ void PresetComboBox::update_selection() validate_selection(); SetSelection(m_last_selected); +#ifdef __WXMSW__ + // From the Windows 2004 the tooltip for preset combobox doesn't work after next call of SetTooltip() + // (There was an issue, when tooltip doesn't appears after changing of the preset selection) + // But this workaround seems to work: We should to kill tooltip and than set new tooltip value + SetToolTip(NULL); +#endif SetToolTip(GetString(m_last_selected)); // A workaround for a set of issues related to text fitting into gtk widgets: @@ -208,6 +214,21 @@ void PresetComboBox::update_selection() #endif } +static std::string suffix(const Preset& preset) +{ + return (preset.is_dirty ? Preset::suffix_modified() : ""); +} + +static std::string suffix(Preset* preset) +{ + return (preset->is_dirty ? Preset::suffix_modified() : ""); +} + +wxString PresetComboBox::get_preset_name(const Preset & preset) +{ + return from_u8(preset.name/* + suffix(preset)*/); +} + void PresetComboBox::update(std::string select_preset_name) { Freeze(); @@ -226,7 +247,7 @@ void PresetComboBox::update(std::string select_preset_name) for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) { const Preset& preset = presets[i]; - if (!preset.is_visible || !preset.is_compatible) + if (!m_show_all && (!preset.is_visible || !preset.is_compatible)) continue; // marker used for disable incompatible printer models for the selected physical printer @@ -246,17 +267,17 @@ void PresetComboBox::update(std::string select_preset_name) assert(bmp); if (!is_enabled) - incomp_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp); + incomp_presets.emplace(get_preset_name(preset), bmp); else if (preset.is_default || preset.is_system) { - Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); + Append(get_preset_name(preset), *bmp); validate_selection(preset.name == select_preset_name); } else { - nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), std::pair(bmp, is_enabled)); + nonsys_presets.emplace(get_preset_name(preset), std::pair(bmp, is_enabled)); if (preset.name == select_preset_name || (select_preset_name.empty() && is_enabled)) - selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()); + selected = get_preset_name(preset); } if (i + 1 == m_collection->num_default_presets()) set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); @@ -329,11 +350,22 @@ bool PresetComboBox::del_physical_printer(const wxString& note_string/* = wxEmpt return true; } +void PresetComboBox::show_all(bool show_all) +{ + m_show_all = show_all; + update(); +} + void PresetComboBox::update() { this->update(into_u8(this->GetString(this->GetSelection()))); } +void PresetComboBox::update_from_bundle() +{ + this->update(m_collection->get_selected_preset().name); +} + void PresetComboBox::msw_rescale() { m_em_unit = em_unit(this); @@ -364,9 +396,9 @@ void PresetComboBox::fill_width_height() thin_icon_width = lroundf(8 * scale_f); // analogue to 8px; wide_icon_width = norm_icon_width + thin_icon_width; - space_icon_width = lroundf(2 * scale_f); - thin_space_icon_width = 2 * space_icon_width; - wide_space_icon_width = 3 * space_icon_width; + space_icon_width = lroundf(2 * scale_f); + thin_space_icon_width = lroundf(4 * scale_f); + wide_space_icon_width = lroundf(6 * scale_f); } wxString PresetComboBox::separator(const std::string& label) @@ -385,7 +417,8 @@ wxBitmap* PresetComboBox::get_bmp( std::string bitmap_key, bool wide_icons, con bitmap_key += is_system ? ",syst" : ",nsyst"; bitmap_key += ",h" + std::to_string(icon_height); - if (wxGetApp().dark_mode()) + bool dark_mode = wxGetApp().dark_mode(); + if (dark_mode) bitmap_key += ",dark"; wxBitmap* bmp = bitmap_cache().find(bitmap_key); @@ -401,10 +434,10 @@ wxBitmap* PresetComboBox::get_bmp( std::string bitmap_key, bool wide_icons, con unsigned char rgb[3]; // Paint the color bars. bitmap_cache().parse_color(filament_rgb, rgb); - bmps.emplace_back(bitmap_cache().mksolid(is_single_bar ? wide_icon_width : norm_icon_width, icon_height, rgb)); + bmps.emplace_back(bitmap_cache().mksolid(is_single_bar ? wide_icon_width : norm_icon_width, icon_height, rgb, false, 1, dark_mode)); if (!is_single_bar) { bitmap_cache().parse_color(extruder_rgb, rgb); - bmps.emplace_back(bitmap_cache().mksolid(thin_icon_width, icon_height, rgb)); + bmps.emplace_back(bitmap_cache().mksolid(thin_icon_width, icon_height, rgb, false, 1, dark_mode)); } // Paint a lock at the system presets. bmps.emplace_back(bitmap_cache().mkclear(space_icon_width, icon_height)); @@ -705,7 +738,7 @@ void PlaterPresetComboBox::show_add_menu() wxMenu* menu = new wxMenu(); append_menu_item(menu, wxID_ANY, _L("Add/Remove presets"), "", - [this](wxCommandEvent&) { + [](wxCommandEvent&) { wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); }); }, "edit_uni", menu, []() { return true; }, wxGetApp().plater()); @@ -735,7 +768,7 @@ void PlaterPresetComboBox::show_edit_menu() } else append_menu_item(menu, wxID_ANY, _L("Add/Remove presets"), "", - [this](wxCommandEvent&) { + [](wxCommandEvent&) { wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); }); }, "edit_uni", menu, []() { return true; }, wxGetApp().plater()); @@ -745,6 +778,12 @@ void PlaterPresetComboBox::show_edit_menu() wxGetApp().plater()->PopupMenu(menu); } +wxString PlaterPresetComboBox::get_preset_name(const Preset& preset) +{ + std::string name = preset.alias.empty() ? preset.name : preset.alias; + return from_u8(name + suffix(preset)); +} + // Only the compatible presets are shown. // If an incompatible preset is selected, it is shown as well. void PlaterPresetComboBox::update() @@ -821,17 +860,17 @@ void PlaterPresetComboBox::update() const std::string name = preset.alias.empty() ? preset.name : preset.alias; if (preset.is_default || preset.is_system) { - Append(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); + Append(get_preset_name(preset), *bmp); validate_selection(is_selected); if (is_selected) - tooltip = wxString::FromUTF8(preset.name.c_str()); + tooltip = from_u8(preset.name); } else { - nonsys_presets.emplace(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp); + nonsys_presets.emplace(get_preset_name(preset), bmp); if (is_selected) { - selected_user_preset = wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()); - tooltip = wxString::FromUTF8(preset.name.c_str()); + selected_user_preset = get_preset_name(preset); + tooltip = from_u8(preset.name); } } if (i + 1 == m_collection->num_default_presets()) @@ -854,7 +893,7 @@ void PlaterPresetComboBox::update() const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers; for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { - for (const std::string preset_name : it->get_preset_names()) { + for (const std::string& preset_name : it->get_preset_names()) { Preset* preset = m_collection->find_preset(preset_name); if (!preset) continue; @@ -862,7 +901,7 @@ void PlaterPresetComboBox::update() wxBitmap* bmp = get_bmp(main_icon_name, wide_icons, main_icon_name); assert(bmp); - set_label_marker(Append(wxString::FromUTF8((it->get_full_name(preset_name) + (preset->is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); + set_label_marker(Append(from_u8(it->get_full_name(preset_name) + suffix(preset)), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); validate_selection(ph_printers.is_selected(it, preset_name)); } } @@ -884,8 +923,16 @@ void PlaterPresetComboBox::update() update_selection(); Thaw(); - if (!tooltip.IsEmpty()) + if (!tooltip.IsEmpty()) { +#ifdef __WXMSW__ + // From the Windows 2004 the tooltip for preset combobox doesn't work after next call of SetTooltip() + // (There was an issue, when tooltip doesn't appears after changing of the preset selection) + // But this workaround seems to work: We should to kill tooltip and than set new tooltip value + // See, https://groups.google.com/g/wx-users/c/mOEe3fgHrzk + SetToolTip(NULL); +#endif SetToolTip(tooltip); + } #ifdef __WXMSW__ // Use this part of code just on Windows to avoid of some layout issues on Linux @@ -946,6 +993,11 @@ TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) }); } +wxString TabPresetComboBox::get_preset_name(const Preset& preset) +{ + return from_u8(preset.name + suffix(preset)); +} + // Update the choice UI from the list of presets. // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown. // If an incompatible preset is selected, it is shown as well. @@ -991,7 +1043,7 @@ void TabPresetComboBox::update() assert(bmp); if (preset.is_default || preset.is_system) { - int item_id = Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); + int item_id = Append(get_preset_name(preset), *bmp); if (!is_enabled) set_label_marker(item_id, LABEL_ITEM_DISABLED); validate_selection(i == idx_selected); @@ -999,9 +1051,9 @@ void TabPresetComboBox::update() else { std::pair pair(bmp, is_enabled); - nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), std::pair(bmp, is_enabled)); + nonsys_presets.emplace(get_preset_name(preset), std::pair(bmp, is_enabled)); if (i == idx_selected) - selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()); + selected = get_preset_name(preset); } if (i + 1 == m_collection->num_default_presets()) set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); @@ -1026,7 +1078,7 @@ void TabPresetComboBox::update() const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers; for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { - for (const std::string preset_name : it->get_preset_names()) { + for (const std::string& preset_name : it->get_preset_names()) { Preset* preset = m_collection->find_preset(preset_name); if (!preset) continue; @@ -1035,7 +1087,7 @@ void TabPresetComboBox::update() wxBitmap* bmp = get_bmp(main_icon_name, main_icon_name, "", true, true, false); assert(bmp); - set_label_marker(Append(wxString::FromUTF8((it->get_full_name(preset_name) + (preset->is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); + set_label_marker(Append(from_u8(it->get_full_name(preset_name) + suffix(preset)), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); validate_selection(ph_printers.is_selected(it, preset_name)); } } @@ -1082,15 +1134,15 @@ void TabPresetComboBox::update_dirty() preset_name = PhysicalPrinter::get_preset_name(preset_name); } - const Preset* preset = m_collection->find_preset(preset_name, false); + Preset* preset = m_collection->find_preset(preset_name, false); if (preset) { - std::string new_label = preset->is_dirty ? preset->name + Preset::suffix_modified() : preset->name; + std::string new_label = preset->name + suffix(preset); if (marker == LABEL_ITEM_PHYSICAL_PRINTER) new_label = ph_printer_name + PhysicalPrinter::separator() + new_label; if (old_label != new_label) - SetString(ui_id, wxString::FromUTF8(new_label.c_str())); + SetString(ui_id, from_u8(new_label)); } } #ifdef __APPLE__ diff --git a/src/slic3r/GUI/PresetComboBoxes.hpp b/src/slic3r/GUI/PresetComboBoxes.hpp index d3cc6277db..6f41c95f4e 100644 --- a/src/slic3r/GUI/PresetComboBoxes.hpp +++ b/src/slic3r/GUI/PresetComboBoxes.hpp @@ -30,8 +30,9 @@ class BitmapCache; // BitmapComboBox used to presets list on Sidebar and Tabs class PresetComboBox : public wxBitmapComboBox { + bool m_show_all { false }; public: - PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size = wxDefaultSize); + PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size = wxDefaultSize, PresetBundle* preset_bundle = nullptr); ~PresetComboBox(); enum LabelItemType { @@ -58,11 +59,16 @@ public: bool selection_is_changed_according_to_physical_printers(); void update(std::string select_preset); + // select preset which is selected in PreseBundle + void update_from_bundle(); void edit_physical_printer(); void add_physical_printer(); bool del_physical_printer(const wxString& note_string = wxEmptyString); + virtual wxString get_preset_name(const Preset& preset); + Preset::Type get_type() { return m_type; } + void show_all(bool show_all); virtual void update(); virtual void msw_rescale(); @@ -158,6 +164,7 @@ public: void show_add_menu(); void show_edit_menu(); + wxString get_preset_name(const Preset& preset) override; void update() override; void msw_rescale() override; @@ -182,6 +189,7 @@ public: show_incompatible = show_incompatible_presets; } + wxString get_preset_name(const Preset& preset) override; void update() override; void update_dirty(); void msw_rescale() override; diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index 8efe832dd4..8621586f8e 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -93,7 +93,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle double bridge_flow_ratio = print_config.opt_float("bridge_flow_ratio"); double perimeter_speed = print_config.opt_float("perimeter_speed"); double external_perimeter_speed = print_config.get_abs_value("external_perimeter_speed", perimeter_speed); - // double gap_fill_speed = print_config.opt_float("gap_fill_speed"); + // double gap_fill_speed = print_config.opt_bool("gap_fill_enabled") ? print_config.opt_float("gap_fill_speed") : 0.; double infill_speed = print_config.opt_float("infill_speed"); double small_perimeter_speed = print_config.get_abs_value("small_perimeter_speed", perimeter_speed); double solid_infill_speed = print_config.get_abs_value("solid_infill_speed", infill_speed); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index b11cc8dd50..a1247f3a04 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -203,6 +203,7 @@ namespace search_for_drives_internal } } +#if ! __APPLE__ static void search_path(const std::string &path, const std::string &parent_path, std::vector &out) { glob_t globbuf; @@ -217,6 +218,7 @@ namespace search_for_drives_internal } globfree(&globbuf); } +#endif // ! __APPLE__ } std::vector RemovableDriveManager::search_for_removable_drives() const diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index 0b8646af17..3bd1fba7eb 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -52,9 +52,8 @@ static void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void *con { int err = 0; DADiskRef disk; - DASessionRef session; - CFDictionaryRef descDict; - session = DASessionCreate(nullptr); + CFDictionaryRef descDict = nullptr; + DASessionRef session = DASessionCreate(nullptr); if (session == nullptr) err = EINVAL; if (err == 0) { @@ -69,7 +68,7 @@ static void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void *con } if (err == 0) { CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey); - BOOL ejectable = [mediaEjectableKey boolValue]; + BOOL ejectable = [(id)mediaEjectableKey boolValue]; CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey); CFTypeRef deviceModelKey = CFDictionaryGetValue(descDict, kDADiskDescriptionDeviceModelKey); @@ -96,16 +95,15 @@ static void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void *con //this eject drive is not used now -(void)eject_drive:(NSString *)path { - DADiskRef disk; - DASessionRef session; NSURL *url = [[NSURL alloc] initFileURLWithPath:path]; + DASessionRef session = DASessionCreate(nullptr); int err = 0; - session = DASessionCreate(nullptr); if (session == nullptr) err = EINVAL; + DADiskRef disk = nullptr; + if (err == 0) + disk = DADiskCreateFromVolumePath(nullptr, session, (CFURLRef)url); if (err == 0) - disk = DADiskCreateFromVolumePath(nullptr,session,(CFURLRef)url); - if( err == 0) //DADiskUnmount(disk, kDADiskUnmountOptionDefault, nullptr, nullptr); DADiskUnmount(disk, kDADiskUnmountOptionWhole | kDADiskUnmountOptionForce, unmount_callback, nullptr); if (disk != nullptr) @@ -124,13 +122,13 @@ void RemovableDriveManager::register_window_osx() assert(m_impl_osx == nullptr); m_impl_osx = [[RemovableDriveManagerMM alloc] init]; if (m_impl_osx) - [m_impl_osx add_unmount_observer]; + [(id)m_impl_osx add_unmount_observer]; } void RemovableDriveManager::unregister_window_osx() { if (m_impl_osx) { - [m_impl_osx release]; + [(id)m_impl_osx release]; m_impl_osx = nullptr; } } @@ -144,7 +142,7 @@ void RemovableDriveManager::list_devices(std::vector &out) const { assert(m_impl_osx != nullptr); if (m_impl_osx) { - NSArray* devices = [m_impl_osx list_dev]; + NSArray* devices = [(id)m_impl_osx list_dev]; for (NSString* volumePath in devices) search_for_drives_internal::inspect_file(std::string([volumePath UTF8String]), "/Volumes", out); } @@ -156,7 +154,7 @@ void RemovableDriveManager::eject_device(const std::string &path) assert(m_impl_osx != nullptr); if (m_impl_osx) { NSString * pth = [NSString stringWithCString:path.c_str() encoding:[NSString defaultCStringEncoding]]; - [m_impl_osx eject_drive:pth]; + [(id)m_impl_osx eject_drive:pth]; } } diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 2b7b3f3d9d..03aa11eb69 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -326,6 +326,53 @@ const Option& OptionsSearcher::get_option(const std::string& opt_key) const return options[it - options.begin()]; } +static Option create_option(const std::string& opt_key, const wxString& label, Preset::Type type, const GroupAndCategory& gc) +{ + wxString suffix; + wxString suffix_local; + if (gc.category == "Machine limits") { + suffix = opt_key.back() == '1' ? L("Stealth") : L("Normal"); + suffix_local = " " + _(suffix); + suffix = " " + suffix; + } + + wxString category = gc.category; + if (type == Preset::TYPE_PRINTER && category.Contains("Extruder ")) { + std::string opt_idx = opt_key.substr(opt_key.find("#") + 1); + category = wxString::Format("%s %d", "Extruder", atoi(opt_idx.c_str()) + 1); + } + + return Option{ boost::nowide::widen(opt_key), type, + (label + suffix).ToStdWstring(), (_(label) + suffix_local).ToStdWstring(), + gc.group.ToStdWstring(), _(gc.group).ToStdWstring(), + gc.category.ToStdWstring(), GUI::Tab::translate_category(category, type).ToStdWstring() }; +} + +Option OptionsSearcher::get_option(const std::string& opt_key, const wxString& label, Preset::Type type) const +{ + auto it = std::lower_bound(options.begin(), options.end(), Option({ boost::nowide::widen(opt_key) })); + if(it->opt_key == boost::nowide::widen(opt_key)) + return options[it - options.begin()]; + if (groups_and_categories.find(opt_key) == groups_and_categories.end()) { + size_t pos = opt_key.find('#'); + if (pos == std::string::npos) + return options[it - options.begin()]; + + std::string zero_opt_key = opt_key.substr(0, pos + 1) + "0"; + + if(groups_and_categories.find(zero_opt_key) == groups_and_categories.end()) + return options[it - options.begin()]; + + return create_option(opt_key, label, type, groups_and_categories.at(zero_opt_key)); + } + + const GroupAndCategory& gc = groups_and_categories.at(opt_key); + if (gc.group.IsEmpty() || gc.category.IsEmpty()) + return options[it - options.begin()]; + + return create_option(opt_key, label, type, gc); +} + void OptionsSearcher::add_key(const std::string& opt_key, const wxString& group, const wxString& category) { groups_and_categories[opt_key] = GroupAndCategory{group, category}; diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index f8c9dffa6a..1f2909564d 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -117,6 +117,7 @@ public: const FoundOption& operator[](const size_t pos) const noexcept { return found[pos]; } const Option& get_option(size_t pos_in_filter) const; const Option& get_option(const std::string& opt_key) const; + Option get_option(const std::string& opt_key, const wxString& label, Preset::Type type) const; const std::vector& found_options() { return found; } const GroupAndCategory& get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 1cb599fc80..214c2632a6 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1160,7 +1160,7 @@ void Selection::erase() if (obj_ins.first == glv_obj_idx) { if (obj_ins.second.find(glv_ins_idx) != obj_ins.second.end()) { if (obj_ins.second.size() == model_object->instances.size()) - items_set.insert(ItemForDelete(ItemType::itVolume, glv_obj_idx, gl_vol->volume_idx())); + items_set.insert(ItemForDelete(ItemType::itObject, glv_obj_idx, -1)); else items_set.insert(ItemForDelete(ItemType::itInstance, glv_obj_idx, glv_ins_idx)); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index eb9659c8ab..fada37fe65 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -5,6 +5,9 @@ #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" +#if ENABLE_VALIDATE_CUSTOM_GCODE +#include "libslic3r/GCode/GCodeProcessor.hpp" +#endif // ENABLE_VALIDATE_CUSTOM_GCODE #include "slic3r/Utils/Http.hpp" #include "slic3r/Utils/PrintHost.hpp" @@ -121,7 +124,7 @@ Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) : m_config_manipulation = get_config_manipulation(); - Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { + Bind(wxEVT_SIZE, ([](wxSizeEvent &evt) { //for (auto page : m_pages) // if (! page.get()->IsShown()) // page->layout_valid = false; @@ -196,6 +199,7 @@ void Tab::create_preset_tab() m_scaled_buttons.reserve(6); m_scaled_buttons.reserve(2); + add_scaled_button(panel, &m_btn_compare_preset, "compare"); add_scaled_button(panel, &m_btn_save_preset, "save"); add_scaled_button(panel, &m_btn_delete_preset, "cross"); if (m_type == Preset::Type::TYPE_PRINTER) @@ -207,6 +211,7 @@ void Tab::create_preset_tab() add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name()); + m_btn_compare_preset->SetToolTip(_L("Compare this preset with some another")); // TRN "Save current Settings" m_btn_save_preset->SetToolTip(from_u8((boost::format(_utf8(L("Save current %s"))) % m_title).str())); m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); @@ -240,7 +245,7 @@ void Tab::create_preset_tab() if (dlg.ShowModal() == wxID_OK) wxGetApp().update_label_colours(); }); - m_search_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent) { wxGetApp().plater()->search(false); }); + m_search_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent) { wxGetApp().plater()->search(false); }); // Colors for ui "decoration" m_sys_label_clr = wxGetApp().get_label_clr_sys(); @@ -271,6 +276,9 @@ void Tab::create_preset_tab() m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(32 * scale_factor)); m_hsizer->Add(m_search_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->AddSpacer(int(8*scale_factor)); + m_hsizer->Add(m_btn_compare_preset, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->AddSpacer(int(16*scale_factor)); // m_hsizer->AddStretchSpacer(32); // StretchSpacer has a strange behavior under OSX, so // There is used just additional sizer for m_mode_sizer with right alignment @@ -338,6 +346,7 @@ void Tab::create_preset_tab() m_page_view->SetScrollbars(1, 20, 1, 2); m_hsizer->Add(m_page_view, 1, wxEXPAND | wxLEFT, 5); + m_btn_compare_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { compare_preset(); })); m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); })); m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); })); m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { @@ -485,7 +494,7 @@ void Tab::update_label_colours() m_modified_label_clr = wxGetApp().get_label_clr_modified(); //update options "decoration" - for (const auto opt : m_options_list) + for (const auto& opt : m_options_list) { const wxColour *color = &m_sys_label_clr; @@ -535,7 +544,7 @@ void Tab::update_label_colours() void Tab::decorate() { - for (const auto opt : m_options_list) + for (const auto& opt : m_options_list) { Field* field = nullptr; wxColour* colored_label_clr = nullptr; @@ -606,7 +615,7 @@ void Tab::update_changed_ui() const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL); auto dirty_options = m_presets->current_dirty_options(deep_compare); auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); - if (m_type == Slic3r::Preset::TYPE_PRINTER) { + if (m_type == Preset::TYPE_PRINTER && static_cast(this)->m_printer_technology == ptFFF) { TabPrinter* tab = static_cast(this); if (tab->m_initial_extruders_count != tab->m_extruders_count) dirty_options.emplace_back("extruders_count"); @@ -633,7 +642,7 @@ void Tab::init_options_list() if (!m_options_list.empty()) m_options_list.clear(); - for (const auto opt_key : m_config->keys()) + for (const std::string& opt_key : m_config->keys()) m_options_list.emplace(opt_key, m_opt_status_value); } @@ -650,7 +659,7 @@ void TabPrinter::init_options_list() if (!m_options_list.empty()) m_options_list.clear(); - for (const auto opt_key : m_config->keys()) + for (const std::string& opt_key : m_config->keys()) { if (opt_key == "bed_shape" || opt_key == "thumbnails") { m_options_list.emplace(opt_key, m_opt_status_value); @@ -667,7 +676,8 @@ void TabPrinter::init_options_list() default: m_options_list.emplace(opt_key, m_opt_status_value); break; } } - m_options_list.emplace("extruders_count", m_opt_status_value); + if (m_printer_technology == ptFFF) + m_options_list.emplace("extruders_count", m_opt_status_value); } void TabPrinter::msw_rescale() @@ -702,7 +712,7 @@ void TabSLAMaterial::init_options_list() if (!m_options_list.empty()) m_options_list.clear(); - for (const auto opt_key : m_config->keys()) + for (const std::string& opt_key : m_config->keys()) { if (opt_key == "compatible_prints" || opt_key == "compatible_printers") { m_options_list.emplace(opt_key, m_opt_status_value); @@ -1428,16 +1438,12 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Advanced")); optgroup->append_single_option_line("seam_position", category_path + "seam-position"); optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first"); + optgroup->append_single_option_line("gap_fill_enabled"); optgroup = page->new_optgroup(L("Fuzzy skin (experimental)")); - Option option = optgroup->get_option("fuzzy_skin_perimeter_mode"); + Option option = optgroup->get_option("fuzzy_skin"); option.opt.width = 30; optgroup->append_single_option_line(option); -#if 0 - option = optgroup->get_option("fuzzy_skin_shape"); - option.opt.width = 30; - optgroup->append_single_option_line(option); -#endif optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_thickness")); optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_point_dist")); @@ -1479,7 +1485,9 @@ void TabPrint::build() optgroup->append_single_option_line("min_skirt_length", category_path + "skirt"); optgroup = page->new_optgroup(L("Brim")); + optgroup->append_single_option_line("brim_type", category_path + "brim"); optgroup->append_single_option_line("brim_width", category_path + "brim"); + optgroup->append_single_option_line("brim_offset", category_path + "brim"); page = add_options_page(L("Support material"), "support"); category_path = "support-material_1698#"; @@ -1491,7 +1499,10 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Raft")); optgroup->append_single_option_line("raft_layers", category_path + "raft-layers"); -// # optgroup->append_single_option_line(get_option_("raft_contact_distance"); + optgroup->append_single_option_line("raft_first_layer_density", category_path + "raft-first-layer-density"); + optgroup->append_single_option_line("raft_first_layer_expansion", category_path + "raft-first-layer-expansion"); + optgroup->append_single_option_line("raft_contact_distance"); + optgroup->append_single_option_line("raft_expansion"); optgroup = page->new_optgroup(L("Options for support material and raft")); optgroup->append_single_option_line("support_material_contact_distance", category_path + "contact-z-distance"); @@ -1700,6 +1711,27 @@ void TabPrint::clear_pages() m_top_bottom_shell_thickness_explanation = nullptr; } +#if ENABLE_VALIDATE_CUSTOM_GCODE +static bool validate_custom_gcode(wxWindow* parent, const wxString& title, const std::string& gcode) +{ + std::vector tags; + bool invalid = GCodeProcessor::contains_reserved_tags(gcode, 5, tags); + if (parent != nullptr && invalid) { + wxString reports = _L_PLURAL("The following line", "The following lines", tags.size()); + reports += ":\n"; + for (const std::string& keyword : tags) { + reports += ";" + keyword + "\n"; + } + reports += _L("contain reserved keywords.") + "\n"; + reports += _L("Please remove them, as they may cause problems in g-code visualization and printing time estimation."); + + wxMessageDialog dialog(parent, reports, _L("Found reserved keywords in") + " " + title, wxICON_WARNING | wxOK); + dialog.ShowModal(); + } + return !invalid; +} +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + void TabFilament::add_filament_overrides_page() { PageShp page = add_options_page(L("Filament Overrides"), "wrench"); @@ -1719,7 +1751,7 @@ void TabFilament::add_filament_overrides_page() line.near_label_widget = [this, optgroup, opt_key, opt_index](wxWindow* parent) { wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, ""); - check_box->Bind(wxEVT_CHECKBOX, [this, optgroup, opt_key, opt_index](wxCommandEvent& evt) { + check_box->Bind(wxEVT_CHECKBOX, [optgroup, opt_key, opt_index](wxCommandEvent& evt) { const bool is_checked = evt.IsChecked(); Field* field = optgroup->get_fieldc(opt_key, opt_index); if (field != nullptr) { @@ -1923,6 +1955,11 @@ void TabFilament::build() page = add_options_page(L("Custom G-code"), "cog"); optgroup = page->new_optgroup(L("Start G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Start G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("start_filament_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -1930,6 +1967,11 @@ void TabFilament::build() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("End G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("End G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("end_filament_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2044,6 +2086,25 @@ void TabFilament::clear_pages() m_cooling_description_line = nullptr; } +#if ENABLE_VALIDATE_CUSTOM_GCODE +bool TabFilament::validate_custom_gcodes() const +{ + auto check_optgroup = [this](const wxString& title, const Slic3r::t_config_option_key& key) { + const ConfigOptionsGroupShp opt_group = m_active_page->get_optgroup(title); + return (opt_group != nullptr) ? + validate_custom_gcode((wxWindow*)this, title, boost::any_cast(opt_group->get_value(key))) : + true; + }; + + bool valid = true; + if (m_active_page->title() == L("Custom G-code")) { + valid &= check_optgroup(L("Start G-code"), "start_filament_gcode"); + valid &= check_optgroup(L("End G-code"), "end_filament_gcode"); + } + return valid; +} +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText, wxString text /*= wxEmptyString*/) { *StaticText = new ogStaticText(parent, text); @@ -2064,11 +2125,20 @@ bool Tab::current_preset_is_dirty() void TabPrinter::build() { m_presets = &m_preset_bundle->printers; - load_initial_data(); - m_printer_technology = m_presets->get_selected_preset().printer_technology(); - m_presets->get_selected_preset().printer_technology() == ptSLA ? build_sla() : build_fff(); + // For DiffPresetDialog we use options list which is saved in Searcher class. + // Options for the Searcher is added in the moment of pages creation. + // So, build first of all printer pages for non-selected printer technology... + std::string def_preset_name = "- default " + std::string(m_printer_technology == ptSLA ? "FFF" : "SLA") + " -"; + m_config = &m_presets->find_preset(def_preset_name)->config; + m_printer_technology == ptSLA ? build_fff() : build_sla(); + if (m_printer_technology == ptSLA) + m_extruders_count_old = 0;// revert this value + + // ... and than for selected printer technology + load_initial_data(); + m_printer_technology == ptSLA ? build_sla() : build_fff(); } void TabPrinter::build_print_host_upload_group(Page* page) @@ -2103,7 +2173,8 @@ void TabPrinter::build_fff() m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); wxGetApp().sidebar().update_objects_list_extruder_column(m_initial_extruders_count); - const Preset* parent_preset = m_presets->get_selected_preset_parent(); + const Preset* parent_preset = m_printer_technology == ptSLA ? nullptr // just for first build, if SLA printer preset is selected + : m_presets->get_selected_preset_parent(); m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); @@ -2214,8 +2285,19 @@ void TabPrinter::build_fff() const int gcode_field_height = 15; // 150 const int notes_field_height = 25; // 250 +#if ENABLE_VALIDATE_CUSTOM_GCODE + // WARNING !! + // if you are going to change any of the following optgroup/option titles + // or to add/remove optgroups/options + // update also TabPrinter::validate_custom_gcodes() +#endif // ENABLE_VALIDATE_CUSTOM_GCODE page = add_options_page(L("Custom G-code"), "cog"); optgroup = page->new_optgroup(L("Start G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Start G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("start_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2223,6 +2305,11 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("End G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("End G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("end_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2230,6 +2317,11 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Before layer change G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Before layer change G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("before_layer_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2237,6 +2329,11 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("After layer change G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("After layer change G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("layer_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2244,6 +2341,11 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Tool change G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Tool change G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("toolchange_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2251,6 +2353,11 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Between objects G-code (for sequential printing)"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("between_objects_gcode"); option.opt.full_width = true; option.opt.is_code = true; @@ -2258,18 +2365,33 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Color Change G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Color Change G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("color_change_gcode"); option.opt.is_code = true; option.opt.height = gcode_field_height;//150; optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Pause Print G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Pause Print G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("pause_print_gcode"); option.opt.is_code = true; option.opt.height = gcode_field_height;//150; optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Template Custom G-code"), 0); +#if ENABLE_VALIDATE_CUSTOM_GCODE + optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode(this, L("Template Custom G-code"), boost::any_cast(value)); + }; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE option = optgroup->get_option("template_custom_gcode"); option.opt.is_code = true; option.opt.height = gcode_field_height;//150; @@ -2287,7 +2409,7 @@ void TabPrinter::build_fff() build_preset_description_line(optgroup.get()); - build_unregular_pages(); + build_unregular_pages(true); } void TabPrinter::build_sla() @@ -2393,7 +2515,9 @@ void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::s auto option = optgroup->get_option(opt_key, 0); auto line = Line{ option.opt.full_label, "" }; line.append_option(option); - if (m_use_silent_mode) + if (m_use_silent_mode + || m_printer_technology == ptSLA // just for first build, if SLA printer preset is selected + ) line.append_option(optgroup->get_option(opt_key, 1)); optgroup->append_line(line); } @@ -2468,7 +2592,7 @@ PageShp TabPrinter::build_kinematics_page() * but "Machine limits" and "Single extruder MM setup" too * (These pages can changes according to the another values of a current preset) * */ -void TabPrinter::build_unregular_pages() +void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/) { size_t n_before_extruders = 2; // Count of pages before Extruder pages bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; @@ -2479,18 +2603,6 @@ void TabPrinter::build_unregular_pages() * */ Freeze(); -#ifdef __WXMSW__ - /* Workaround for correct layout of controls inside the created page: - * In some _strange_ way we should we should imitate page resizing. - */ -/* auto layout_page = [this](PageShp page) - { - const wxSize& sz = page->GetSize(); - page->SetSize(sz.x + 1, sz.y + 1); - page->SetSize(sz); - };*/ -#endif //__WXMSW__ - // Add/delete Kinematics page according to is_marlin_flavor size_t existed_page = 0; for (size_t i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already @@ -2502,12 +2614,12 @@ void TabPrinter::build_unregular_pages() break; } - if (existed_page < n_before_extruders && is_marlin_flavor) { + if (existed_page < n_before_extruders && (is_marlin_flavor || from_initial_build)) { auto page = build_kinematics_page(); -#ifdef __WXMSW__ -// layout_page(page); -#endif - m_pages.insert(m_pages.begin() + n_before_extruders, page); + if (from_initial_build && !is_marlin_flavor) + page->clear(); + else + m_pages.insert(m_pages.begin() + n_before_extruders, page); } if (is_marlin_flavor) @@ -2525,7 +2637,8 @@ void TabPrinter::build_unregular_pages() } m_has_single_extruder_MM_page = false; } - if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) { + if (from_initial_build || + (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page)) { // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves auto page = add_options_page(L("Single extruder MM setup"), "printer", true); auto optgroup = page->new_optgroup(L("Single extruder multimaterial parameters")); @@ -2534,8 +2647,12 @@ void TabPrinter::build_unregular_pages() optgroup->append_single_option_line("parking_pos_retraction"); optgroup->append_single_option_line("extra_loading_move"); optgroup->append_single_option_line("high_current_on_filament_swap"); - m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); - m_has_single_extruder_MM_page = true; + if (from_initial_build) + page->clear(); + else { + m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); + m_has_single_extruder_MM_page = true; + } } // Build missed extruder pages @@ -2640,10 +2757,6 @@ void TabPrinter::build_unregular_pages() line = optgroup->create_single_option_line("extruder_colour", wxEmptyString, extruder_idx); line.append_widget(reset_to_filament_color); optgroup->append_line(line); - -#ifdef __WXMSW__ -// layout_page(page); -#endif } // # remove extra pages @@ -2654,6 +2767,10 @@ void TabPrinter::build_unregular_pages() Thaw(); m_extruders_count_old = m_extruders_count; + + if (from_initial_build && m_printer_technology == ptSLA) + return; // next part of code is no needed to execute at this moment + rebuild_page_tree(); // Reload preset pages with current configuration values @@ -3185,6 +3302,9 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, load_current_preset(); } + + if (technology_changed) + wxGetApp().mainframe->diff_dialog.update_presets(); } // If the current preset is dirty, the user is asked whether the changes may be discarded. @@ -3335,7 +3455,9 @@ bool Tab::tree_sel_change_delayed() wxCheckForInterrupt(m_treectrl); if (m_page_switch_planned) throw UIBuildCanceled(); -#endif // WIN32 +#else // WIN32 + (void)this; // silence warning +#endif }); try { @@ -3372,6 +3494,11 @@ void Tab::OnKeyDown(wxKeyEvent& event) event.Skip(); } +void Tab::compare_preset() +{ + wxGetApp().mainframe->diff_dialog.show(m_type); +} + // Save the current preset into file. // This removes the "dirty" flag of the preset, possibly creates a new preset under a new name, // and activates the new preset. @@ -3441,6 +3568,9 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) for (Preset::Type preset_type : dependent) wxGetApp().get_tab(preset_type)->update_tab_ui(); } + + // update preset comboboxes in DiffPresetDlg + wxGetApp().mainframe->diff_dialog.update_presets(m_type); } // Called for a currently selected preset. @@ -3474,19 +3604,23 @@ void Tab::delete_preset() std::vector ph_printers_only = physical_printers.get_printers_with_only_preset(current_preset.name); if (!ph_printers.empty()) { - msg += _L("The physical printer(s) below is based on the preset, you are going to delete."); + msg += _L_PLURAL("The physical printer below is based on the preset, you are going to delete.", + "The physical printers below are based on the preset, you are going to delete.", ph_printers.size()); for (const std::string& printer : ph_printers) msg += "\n \"" + from_u8(printer) + "\","; msg.RemoveLast(); - msg += "\n" + _L("Note, that selected preset will be deleted from this/those printer(s) too.")+ "\n\n"; + msg += "\n" + _L_PLURAL("Note, that selected preset will be deleted from this printer too.", + "Note, that selected preset will be deleted from these printers too.", ph_printers.size()) + "\n\n"; } if (!ph_printers_only.empty()) { - msg += _L("The physical printer(s) below is based only on the preset, you are going to delete."); + msg += _L_PLURAL("The physical printer below is based only on the preset, you are going to delete.", + "The physical printers below are based only on the preset, you are going to delete.", ph_printers_only.size()); for (const std::string& printer : ph_printers_only) msg += "\n \"" + from_u8(printer) + "\","; msg.RemoveLast(); - msg += "\n" + _L("Note, that this/those printer(s) will be deleted after deleting of the selected preset.") + "\n\n"; + msg += "\n" + _L_PLURAL("Note, that this printer will be deleted after deleting of the selected preset.", + "Note, that these printers will be deleted after deleting of the selected preset.", ph_printers_only.size()) + "\n\n"; } } @@ -3707,6 +3841,34 @@ void TabPrinter::apply_extruder_cnt_from_cache() } } +#if ENABLE_VALIDATE_CUSTOM_GCODE +bool TabPrinter::validate_custom_gcodes() const +{ + auto check_optgroup = [this](const wxString& title, const Slic3r::t_config_option_key& key) { + const ConfigOptionsGroupShp opt_group = m_active_page->get_optgroup(title); + return (opt_group != nullptr) ? + validate_custom_gcode((wxWindow*)this, title, boost::any_cast(opt_group->get_value(key))) : + true; + }; + + bool valid = true; + if (m_printer_technology == ptFFF) { + if (m_active_page->title() == L("Custom G-code")) { + valid &= check_optgroup(L("Start G-code"), "start_gcode"); + valid &= check_optgroup(L("End G-code"), "end_gcode"); + valid &= check_optgroup(L("Before layer change G-code"), "before_layer_gcode"); + valid &= check_optgroup(L("After layer change G-code"), "layer_gcode"); + valid &= check_optgroup(L("Tool change G-code"), "toolchange_gcode"); + valid &= check_optgroup(L("Between objects G-code (for sequential printing)"), "between_objects_gcode"); + valid &= check_optgroup(L("Color Change G-code"), "color_change_gcode"); + valid &= check_optgroup(L("Pause Print G-code"), "pause_print_gcode"); + valid &= check_optgroup(L("Template Custom G-code"), "template_custom_gcode"); + } + } + return valid; +} +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + void TabPrinter::update_machine_limits_description(const MachineLimitsUsage usage) { wxString text; @@ -3895,7 +4057,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la #else auto tab = parent()->GetParent();// GetParent(); #endif - optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) { + optgroup->m_on_change = [tab](t_config_option_key opt_key, boost::any value) { //! This function will be called from OptionGroup. //! Using of CallAfter is redundant. //! And in some cases it causes update() function to be recalled again @@ -3905,21 +4067,21 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la //! }); }; - optgroup->m_get_initial_config = [this, tab]() { + optgroup->m_get_initial_config = [tab]() { DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset().config; return config; }; - optgroup->m_get_sys_config = [this, tab]() { + optgroup->m_get_sys_config = [tab]() { DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset_parent()->config; return config; }; - optgroup->have_sys_config = [this, tab]() { + optgroup->have_sys_config = [tab]() { return static_cast(tab)->m_presets->get_selected_preset_parent() != nullptr; }; - optgroup->rescale_extra_column_item = [this](wxWindow* win) { + optgroup->rescale_extra_column_item = [](wxWindow* win) { auto *ctrl = dynamic_cast(win); if (ctrl == nullptr) return; @@ -3932,6 +4094,18 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la return optgroup; } +#if ENABLE_VALIDATE_CUSTOM_GCODE +const ConfigOptionsGroupShp Page::get_optgroup(const wxString& title) const +{ + for (ConfigOptionsGroupShp optgroup : m_optgroups) { + if (optgroup->title == title) + return optgroup; + } + + return nullptr; +} +#endif // ENABLE_VALIDATE_CUSTOM_GCODE + void TabSLAMaterial::build() { m_presets = &m_preset_bundle->sla_materials; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 29588ba20e..add2b3aa5e 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -65,7 +65,7 @@ public: wxBoxSizer* vsizer() const { return m_vsizer; } wxWindow* parent() const { return m_parent; } - wxString title() const { return m_title; } + const wxString& title() const { return m_title; } size_t iconID() const { return m_iconID; } void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } void reload_config(); @@ -78,6 +78,9 @@ public: Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1); +#if ENABLE_VALIDATE_CUSTOM_GCODE + const ConfigOptionsGroupShp get_optgroup(const wxString& title) const; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE bool set_item_colour(const wxColour *clr) { if (m_item_color != clr) { @@ -112,6 +115,7 @@ protected: const wxString m_title; TabPresetComboBox* m_presets_choice; ScalableButton* m_search_btn; + ScalableButton* m_btn_compare_preset; ScalableButton* m_btn_save_preset; ScalableButton* m_btn_delete_preset; ScalableButton* m_btn_edit_ph_printer {nullptr}; @@ -290,6 +294,7 @@ public: void OnTreeSelChange(wxTreeEvent& event); void OnKeyDown(wxKeyEvent& event); + void compare_preset(); void save_preset(std::string name = std::string(), bool detach = false); void delete_preset(); void toggle_show_hide_incompatible(); @@ -381,7 +386,6 @@ public: private: ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr; ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr; - bool m_support_material_overhangs_queried = false; }; class TabFilament : public Tab @@ -408,6 +412,10 @@ public: void update() override; void clear_pages() override; bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptFFF; } + +#if ENABLE_VALIDATE_CUSTOM_GCODE + bool validate_custom_gcodes() const; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE }; class TabPrinter : public Tab @@ -456,7 +464,7 @@ public: void update_pages(); // update m_pages according to printer technology void extruders_count_changed(size_t extruders_count); PageShp build_kinematics_page(); - void build_unregular_pages(); + void build_unregular_pages(bool from_initial_build = false); void on_preset_loaded() override; void init_options_list() override; void msw_rescale() override; @@ -466,6 +474,10 @@ public: wxSizer* create_bed_shape_widget(wxWindow* parent); void cache_extruder_cnt(); void apply_extruder_cnt_from_cache(); + +#if ENABLE_VALIDATE_CUSTOM_GCODE + bool validate_custom_gcodes() const; +#endif // ENABLE_VALIDATE_CUSTOM_GCODE }; class TabSLAMaterial : public Tab diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index cd5183cb31..07a6fc7390 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include "libslic3r/PrintConfig.hpp" #include "libslic3r/PresetBundle.hpp" #include "format.hpp" @@ -22,6 +24,7 @@ //#include "fts_fuzzy_match.h" #include "BitmapCache.hpp" +#include "PresetComboBoxes.hpp" using boost::optional; @@ -36,7 +39,7 @@ namespace Slic3r { namespace GUI { // ---------------------------------------------------------------------------- -// ModelNode: a node inside UnsavedChangesModel +// ModelNode: a node inside DiffModel // ---------------------------------------------------------------------------- static const std::map type_icon_names = { @@ -198,9 +201,9 @@ void ModelNode::UpdateIcons() { // update icons for the colors, if any exists if (!m_old_color.IsEmpty()) - m_old_color_bmp = get_bitmap(m_toggle ? m_old_color : grey); + m_old_color_bmp = get_bitmap(m_toggle ? m_old_color : wxString::FromUTF8(grey.c_str())); if (!m_new_color.IsEmpty()) - m_new_color_bmp = get_bitmap(m_toggle ? m_new_color : grey); + m_new_color_bmp = get_bitmap(m_toggle ? m_new_color : wxString::FromUTF8(grey.c_str())); // update main icon, if any exists if (m_icon_name.empty()) @@ -215,21 +218,15 @@ void ModelNode::UpdateIcons() // ---------------------------------------------------------------------------- -// UnsavedChangesModel +// DiffModel // ---------------------------------------------------------------------------- -UnsavedChangesModel::UnsavedChangesModel(wxWindow* parent) : +DiffModel::DiffModel(wxWindow* parent) : m_parent_win(parent) { } -UnsavedChangesModel::~UnsavedChangesModel() -{ - for (ModelNode* preset_node : m_preset_nodes) - delete preset_node; -} - -wxDataViewItem UnsavedChangesModel::AddPreset(Preset::Type type, wxString preset_name, PrinterTechnology pt) +wxDataViewItem DiffModel::AddPreset(Preset::Type type, wxString preset_name, PrinterTechnology pt) { // "color" strings color_string(preset_name, def_text_color()); @@ -245,7 +242,7 @@ wxDataViewItem UnsavedChangesModel::AddPreset(Preset::Type type, wxString preset return child; } -ModelNode* UnsavedChangesModel::AddOption(ModelNode* group_node, wxString option_name, wxString old_value, wxString new_value) +ModelNode* DiffModel::AddOption(ModelNode* group_node, wxString option_name, wxString old_value, wxString new_value) { group_node->Append(std::make_unique(group_node, option_name, old_value, new_value)); ModelNode* option = group_node->GetChildren().back().get(); @@ -256,7 +253,7 @@ ModelNode* UnsavedChangesModel::AddOption(ModelNode* group_node, wxString option return option; } -ModelNode* UnsavedChangesModel::AddOptionWithGroup(ModelNode* category_node, wxString group_name, wxString option_name, wxString old_value, wxString new_value) +ModelNode* DiffModel::AddOptionWithGroup(ModelNode* category_node, wxString group_name, wxString option_name, wxString old_value, wxString new_value) { category_node->Append(std::make_unique(category_node, group_name)); ModelNode* group_node = category_node->GetChildren().back().get(); @@ -265,7 +262,7 @@ ModelNode* UnsavedChangesModel::AddOptionWithGroup(ModelNode* category_node, wxS return AddOption(group_node, option_name, old_value, new_value); } -ModelNode* UnsavedChangesModel::AddOptionWithGroupAndCategory(ModelNode* preset_node, wxString category_name, wxString group_name, +ModelNode* DiffModel::AddOptionWithGroupAndCategory(ModelNode* preset_node, wxString category_name, wxString group_name, wxString option_name, wxString old_value, wxString new_value, const std::string category_icon_name) { preset_node->Append(std::make_unique(preset_node, category_name, category_icon_name)); @@ -275,7 +272,7 @@ ModelNode* UnsavedChangesModel::AddOptionWithGroupAndCategory(ModelNode* preset_ return AddOptionWithGroup(category_node, group_name, option_name, old_value, new_value); } -wxDataViewItem UnsavedChangesModel::AddOption(Preset::Type type, wxString category_name, wxString group_name, wxString option_name, +wxDataViewItem DiffModel::AddOption(Preset::Type type, wxString category_name, wxString group_name, wxString option_name, wxString old_value, wxString new_value, const std::string category_icon_name) { // "color" strings @@ -288,7 +285,7 @@ wxDataViewItem UnsavedChangesModel::AddOption(Preset::Type type, wxString catego make_string_bold(group_name); // add items - for (ModelNode* preset : m_preset_nodes) + for (std::unique_ptr& preset : m_preset_nodes) if (preset->type() == type) { for (std::unique_ptr &category : preset->GetChildren()) @@ -301,7 +298,7 @@ wxDataViewItem UnsavedChangesModel::AddOption(Preset::Type type, wxString catego return wxDataViewItem((void*)AddOptionWithGroup(category.get(), group_name, option_name, old_value, new_value)); } - return wxDataViewItem((void*)AddOptionWithGroupAndCategory(preset, category_name, group_name, option_name, old_value, new_value, category_icon_name)); + return wxDataViewItem((void*)AddOptionWithGroupAndCategory(preset.get(), category_name, group_name, option_name, old_value, new_value, category_icon_name)); } return wxDataViewItem(nullptr); @@ -336,7 +333,7 @@ static void update_parents(ModelNode* node) } } -void UnsavedChangesModel::UpdateItemEnabling(wxDataViewItem item) +void DiffModel::UpdateItemEnabling(wxDataViewItem item) { assert(item.IsOk()); ModelNode* node = static_cast(item.GetID()); @@ -346,14 +343,14 @@ void UnsavedChangesModel::UpdateItemEnabling(wxDataViewItem item) update_parents(node); } -bool UnsavedChangesModel::IsEnabledItem(const wxDataViewItem& item) +bool DiffModel::IsEnabledItem(const wxDataViewItem& item) { assert(item.IsOk()); ModelNode* node = static_cast(item.GetID()); return node->IsToggled(); } -void UnsavedChangesModel::GetValue(wxVariant& variant, const wxDataViewItem& item, unsigned int col) const +void DiffModel::GetValue(wxVariant& variant, const wxDataViewItem& item, unsigned int col) const { assert(item.IsOk()); @@ -386,11 +383,11 @@ void UnsavedChangesModel::GetValue(wxVariant& variant, const wxDataViewItem& ite #endif //__linux__ default: - wxLogError("UnsavedChangesModel::GetValue: wrong column %d", col); + wxLogError("DiffModel::GetValue: wrong column %d", col); } } -bool UnsavedChangesModel::SetValue(const wxVariant& variant, const wxDataViewItem& item, unsigned int col) +bool DiffModel::SetValue(const wxVariant& variant, const wxDataViewItem& item, unsigned int col) { assert(item.IsOk()); @@ -440,12 +437,12 @@ bool UnsavedChangesModel::SetValue(const wxVariant& variant, const wxDataViewIte return true; } #endif //__linux__ default: - wxLogError("UnsavedChangesModel::SetValue: wrong column"); + wxLogError("DiffModel::SetValue: wrong column"); } return false; } -bool UnsavedChangesModel::IsEnabled(const wxDataViewItem& item, unsigned int col) const +bool DiffModel::IsEnabled(const wxDataViewItem& item, unsigned int col) const { assert(item.IsOk()); if (col == colToggle) @@ -455,7 +452,7 @@ bool UnsavedChangesModel::IsEnabled(const wxDataViewItem& item, unsigned int col return (static_cast(item.GetID()))->IsToggled(); } -wxDataViewItem UnsavedChangesModel::GetParent(const wxDataViewItem& item) const +wxDataViewItem DiffModel::GetParent(const wxDataViewItem& item) const { // the invisible root node has no parent if (!item.IsOk()) @@ -463,14 +460,13 @@ wxDataViewItem UnsavedChangesModel::GetParent(const wxDataViewItem& item) const ModelNode* node = static_cast(item.GetID()); - // "MyMusic" also has no parent if (node->IsRoot()) return wxDataViewItem(nullptr); return wxDataViewItem((void*)node->GetParent()); } -bool UnsavedChangesModel::IsContainer(const wxDataViewItem& item) const +bool DiffModel::IsContainer(const wxDataViewItem& item) const { // the invisble root node can have children if (!item.IsOk()) @@ -480,23 +476,19 @@ bool UnsavedChangesModel::IsContainer(const wxDataViewItem& item) const return node->IsContainer(); } -unsigned int UnsavedChangesModel::GetChildren(const wxDataViewItem& parent, wxDataViewItemArray& array) const +unsigned int DiffModel::GetChildren(const wxDataViewItem& parent, wxDataViewItemArray& array) const { - ModelNode* node = (ModelNode*)parent.GetID(); - if (!node) { - for (auto preset_node : m_preset_nodes) - array.Add(wxDataViewItem((void*)preset_node)); - return m_preset_nodes.size(); - } + ModelNode* parent_node = (ModelNode*)parent.GetID(); - for (std::unique_ptr &child : node->GetChildren()) + const ModelNodePtrArray& children = parent_node ? parent_node->GetChildren() : m_preset_nodes; + for (const std::unique_ptr& child : children) array.Add(wxDataViewItem((void*)child.get())); - return node->GetChildCount(); + return array.size(); } -wxString UnsavedChangesModel::GetColumnType(unsigned int col) const +wxString DiffModel::GetColumnType(unsigned int col) const { switch (col) { @@ -520,14 +512,234 @@ static void rescale_children(ModelNode* parent) } } -void UnsavedChangesModel::Rescale() +void DiffModel::Rescale() { - for (ModelNode* node : m_preset_nodes) { + for (std::unique_ptr &node : m_preset_nodes) { node->UpdateIcons(); - rescale_children(node); + rescale_children(node.get()); } } +wxDataViewItem DiffModel::Delete(const wxDataViewItem& item) +{ + auto ret_item = wxDataViewItem(nullptr); + ModelNode* node = static_cast(item.GetID()); + if (!node) // happens if item.IsOk()==false + return ret_item; + + // first remove the node from the parent's array of children; + // NOTE: m_preset_nodes is only a vector of _pointers_ + // thus removing the node from it doesn't result in freeing it + ModelNodePtrArray& children = node->GetChildren(); + // Delete all children + while (!children.empty()) + Delete(wxDataViewItem(children.back().get())); + + auto node_parent = node->GetParent(); + wxDataViewItem parent(node_parent); + + ModelNodePtrArray& parents_children = node_parent ? node_parent->GetChildren() : m_preset_nodes; + auto it = find_if(parents_children.begin(), parents_children.end(), + [node](std::unique_ptr& child) { return child.get() == node; }); + assert(it != parents_children.end()); + it = parents_children.erase(it); + + if (it != parents_children.end()) + ret_item = wxDataViewItem(it->get()); + + // set m_container to FALSE if parent has no child + if (node_parent) { +#ifndef __WXGTK__ + if (node_parent->GetChildCount() == 0) + node_parent->m_container = false; +#endif //__WXGTK__ + ret_item = parent; + } + + // notify control + ItemDeleted(parent, item); + return ret_item; +} + +void DiffModel::Clear() +{ + while (!m_preset_nodes.empty()) + Delete(wxDataViewItem(m_preset_nodes.back().get())); +} + + +static std::string get_pure_opt_key(std::string opt_key) +{ + int pos = opt_key.find("#"); + if (pos > 0) + boost::erase_tail(opt_key, opt_key.size() - pos); + return opt_key; +} + +// ---------------------------------------------------------------------------- +// DiffViewCtrl +// ---------------------------------------------------------------------------- + +DiffViewCtrl::DiffViewCtrl(wxWindow* parent, wxSize size) + : wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, size, wxBORDER_SIMPLE | wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES), + m_em_unit(em_unit(parent)) +{ + model = new DiffModel(parent); + this->AssociateModel(model); + model->SetAssociatedControl(this); + + this->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &DiffViewCtrl::context_menu, this); + this->Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &DiffViewCtrl::context_menu, this); + this->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &DiffViewCtrl::item_value_changed, this); +} + +void DiffViewCtrl::AppendBmpTextColumn(const wxString& label, unsigned model_column, int width, bool set_expander/* = false*/) +{ + m_columns_width.emplace(this->GetColumnCount(), width); +#ifdef __linux__ + wxDataViewIconTextRenderer* rd = new wxDataViewIconTextRenderer(); +#ifdef SUPPORTS_MARKUP + rd->EnableMarkup(true); +#endif + wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); +#else + wxDataViewColumn* column = new wxDataViewColumn(label, new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), model_column, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE); +#endif //__linux__ + this->AppendColumn(column); + if (set_expander) + this->SetExpanderColumn(column); + +} + +void DiffViewCtrl::AppendToggleColumn_(const wxString& label, unsigned model_column, int width) +{ + m_columns_width.emplace(this->GetColumnCount(), width); + AppendToggleColumn(label, model_column, wxDATAVIEW_CELL_ACTIVATABLE, width * m_em_unit); +} + +void DiffViewCtrl::Rescale(int em /*= 0*/) +{ + if (em > 0) { + for (auto item : m_columns_width) + GetColumn(item.first)->SetWidth(item.second * em); + m_em_unit = em; + } + + model->Rescale(); + Refresh(); +} + + +void DiffViewCtrl::Append( const std::string& opt_key, Preset::Type type, + wxString category_name, wxString group_name, wxString option_name, + wxString old_value, wxString new_value, const std::string category_icon_name) +{ + ItemData item_data = { opt_key, option_name, old_value, new_value, type }; + + wxString old_val = get_short_string(item_data.old_val); + wxString new_val = get_short_string(item_data.new_val); + if (old_val != item_data.old_val || new_val != item_data.new_val) + item_data.is_long = true; + + m_items_map.emplace(model->AddOption(type, category_name, group_name, option_name, old_val, new_val, category_icon_name), item_data); + +} + +void DiffViewCtrl::Clear() +{ + model->Clear(); + m_items_map.clear(); +} + +wxString DiffViewCtrl::get_short_string(wxString full_string) +{ + size_t max_len = 30; + if (full_string.IsEmpty() || full_string.StartsWith("#") || + (full_string.Find("\n") == wxNOT_FOUND && full_string.Length() < max_len)) + return full_string; + + m_has_long_strings = true; + + int n_pos = full_string.Find("\n"); + if (n_pos != wxNOT_FOUND && n_pos < (int)max_len) + max_len = n_pos; + + full_string.Truncate(max_len); + return full_string + dots; +} + +void DiffViewCtrl::context_menu(wxDataViewEvent& event) +{ + if (!m_has_long_strings) + return; + + wxDataViewItem item = event.GetItem(); + if (!item) { + wxPoint mouse_pos = wxGetMousePosition() - this->GetScreenPosition(); + wxDataViewColumn* col = nullptr; + this->HitTest(mouse_pos, item, col); + + if (!item) + item = this->GetSelection(); + + if (!item) + return; + } + + auto it = m_items_map.find(item); + if (it == m_items_map.end() || !it->second.is_long) + return; + FullCompareDialog(it->second.opt_name, it->second.old_val, it->second.new_val).ShowModal(); + +#ifdef __WXOSX__ + wxWindow* parent = this->GetParent(); + if (parent && parent->IsShown()) { + // if this dialog is shown it have to be Hide and show again to be placed on the very Top of windows + parent->Hide(); + parent->Show(); + } +#endif // __WXOSX__ +} + +void DiffViewCtrl::item_value_changed(wxDataViewEvent& event) +{ + if (event.GetColumn() != DiffModel::colToggle) + return; + + wxDataViewItem item = event.GetItem(); + + model->UpdateItemEnabling(item); + Refresh(); + + // update an enabling of the "save/move" buttons + m_empty_selection = selected_options().empty(); +} + +std::vector DiffViewCtrl::unselected_options(Preset::Type type) +{ + std::vector ret; + + for (auto item : m_items_map) { + if (item.second.opt_key == "extruders_count") + continue; + if (item.second.type == type && !model->IsEnabledItem(item.first)) + ret.emplace_back(get_pure_opt_key(item.second.opt_key)); + } + + return ret; +} + +std::vector DiffViewCtrl::selected_options() +{ + std::vector ret; + + for (auto item : m_items_map) + if (model->IsEnabledItem(item.first)) + ret.emplace_back(get_pure_opt_key(item.second.opt_key)); + + return ret; +} + //------------------------------------------ // UnsavedChangesDialog @@ -593,35 +805,11 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_ m_action_line = new wxStaticText(this, wxID_ANY, ""); m_action_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); - m_tree = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(em * 60, em * 30), wxBORDER_SIMPLE | wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES); - m_tree_model = new UnsavedChangesModel(this); - m_tree->AssociateModel(m_tree_model); - m_tree_model->SetAssociatedControl(m_tree); - - m_tree->AppendToggleColumn(L"\u2714", UnsavedChangesModel::colToggle, wxDATAVIEW_CELL_ACTIVATABLE, (wxLinux ? 8 : 6) * em); - - auto append_bmp_text_column = [this](const wxString& label, unsigned model_column, int width, bool set_expander = false) - { -#ifdef __linux__ - wxDataViewIconTextRenderer* rd = new wxDataViewIconTextRenderer(); -#ifdef SUPPORTS_MARKUP - rd->EnableMarkup(true); -#endif - wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); -#else - wxDataViewColumn* column = new wxDataViewColumn(label, new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), model_column, width, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE); -#endif //__linux__ - m_tree->AppendColumn(column); - if (set_expander) - m_tree->SetExpanderColumn(column); - }; - - append_bmp_text_column("" , UnsavedChangesModel::colIconText, 28 * em); - append_bmp_text_column(_L("Old Value"), UnsavedChangesModel::colOldValue, 12 * em); - append_bmp_text_column(_L("New Value"), UnsavedChangesModel::colNewValue, 12 * em); - - m_tree->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &UnsavedChangesDialog::item_value_changed, this); - m_tree->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &UnsavedChangesDialog::context_menu, this); + m_tree = new DiffViewCtrl(this, wxSize(em * 60, em * 30)); + m_tree->AppendToggleColumn_(L"\u2714" , DiffModel::colToggle, wxLinux ? 8 : 6); + m_tree->AppendBmpTextColumn("" , DiffModel::colIconText, 28); + m_tree->AppendBmpTextColumn(_L("Old Value"), DiffModel::colOldValue, 12); + m_tree->AppendBmpTextColumn(_L("New Value"), DiffModel::colNewValue, 12); // Add Buttons wxFont btn_font = this->GetFont().Scaled(1.4f); @@ -641,7 +829,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_ close(close_act); }); if (process_enable) - (*btn)->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(!m_empty_selection); }); + (*btn)->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_tree->has_selection()); }); (*btn)->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { show_info_line(Action::Undef); e.Skip(); }); }; @@ -698,45 +886,6 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_ show_info_line(Action::Undef); } -void UnsavedChangesDialog::item_value_changed(wxDataViewEvent& event) -{ - if (event.GetColumn() != UnsavedChangesModel::colToggle) - return; - - wxDataViewItem item = event.GetItem(); - - m_tree_model->UpdateItemEnabling(item); - m_tree->Refresh(); - - // update an enabling of the "save/move" buttons - m_empty_selection = get_selected_options().empty(); -} - -void UnsavedChangesDialog::context_menu(wxDataViewEvent& event) -{ - if (!m_has_long_strings) - return; - - wxDataViewItem item = event.GetItem(); - if (!item) - { - wxPoint mouse_pos = wxGetMousePosition() - m_tree->GetScreenPosition(); - wxDataViewColumn* col = nullptr; - m_tree->HitTest(mouse_pos, item, col); - - if (!item) - item = m_tree->GetSelection(); - - if (!item) - return; - } - - auto it = m_items_map.find(item); - if (it == m_items_map.end() || !it->second.is_long) - return; - FullCompareDialog(it->second.opt_name, it->second.old_val, it->second.new_val).ShowModal(); -} - void UnsavedChangesDialog::show_info_line(Action action, std::string preset_name) { if (action == Action::Undef && !m_has_long_strings) @@ -859,27 +1008,30 @@ wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConf return from_u8(_utf8(names[static_cast(val)])); } -static int get_id_from_opt_key(std::string opt_key) +static size_t get_id_from_opt_key(std::string opt_key) { int pos = opt_key.find("#"); if (pos > 0) { boost::erase_head(opt_key, pos + 1); - return atoi(opt_key.c_str()); + return static_cast(atoi(opt_key.c_str())); } return 0; } -static std::string get_pure_opt_key(std::string opt_key) +static wxString get_full_label(std::string opt_key, const DynamicPrintConfig& config) { - int pos = opt_key.find("#"); - if (pos > 0) - boost::erase_tail(opt_key, opt_key.size() - pos); - return opt_key; + opt_key = get_pure_opt_key(opt_key); + + if (config.option(opt_key)->is_nil()) + return _L("N/A"); + + const ConfigOptionDef* opt = config.def()->get(opt_key); + return opt->full_label.empty() ? opt->label : opt->full_label; } static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& config) { - int opt_idx = get_id_from_opt_key(opt_key); + size_t opt_idx = get_id_from_opt_key(opt_key); opt_key = get_pure_opt_key(opt_key); if (config.option(opt_key)->is_nil()) @@ -894,34 +1046,62 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& case coInt: return from_u8((boost::format("%1%") % config.opt_int(opt_key)).str()); case coInts: { - int val = is_nullable ? - config.opt(opt_key)->get_at(opt_idx) : - config.opt(opt_key)->get_at(opt_idx); - return from_u8((boost::format("%1%") % val).str()); + if (is_nullable) { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return from_u8((boost::format("%1%") % values->get_at(opt_idx)).str()); + } + else { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return from_u8((boost::format("%1%") % values->get_at(opt_idx)).str()); + } + return _L("Undef"); } case coBool: return config.opt_bool(opt_key) ? "true" : "false"; case coBools: { - bool val = is_nullable ? - config.opt(opt_key)->get_at(opt_idx) : - config.opt(opt_key)->get_at(opt_idx); - return val ? "true" : "false"; + if (is_nullable) { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return values->get_at(opt_idx) ? "true" : "false"; + } + else { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return values->get_at(opt_idx) ? "true" : "false"; + } + return _L("Undef"); } case coPercent: return from_u8((boost::format("%1%%%") % int(config.optptr(opt_key)->getFloat())).str()); case coPercents: { - double val = is_nullable ? - config.opt(opt_key)->get_at(opt_idx) : - config.opt(opt_key)->get_at(opt_idx); - return from_u8((boost::format("%1%%%") % int(val)).str()); + if (is_nullable) { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return from_u8((boost::format("%1%%%") % values->get_at(opt_idx)).str()); + } + else { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return from_u8((boost::format("%1%%%") % values->get_at(opt_idx)).str()); + } + return _L("Undef"); } case coFloat: return double_to_string(config.opt_float(opt_key)); case coFloats: { - double val = is_nullable ? - config.opt(opt_key)->get_at(opt_idx) : - config.opt(opt_key)->get_at(opt_idx); - return double_to_string(val); + if (is_nullable) { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return double_to_string(values->get_at(opt_idx)); + } + else { + auto values = config.opt(opt_key); + if (opt_idx < values->size()) + return double_to_string(values->get_at(opt_idx)); + } + return _L("Undef"); } case coString: return from_u8(config.opt_string(opt_key)); @@ -936,7 +1116,7 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& out.RemoveLast(1); return out; } - if (!strings->empty()) + if (!strings->empty() && opt_idx < strings->values.size()) return from_u8(strings->get_at(opt_idx)); } break; @@ -966,6 +1146,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return get_string_from_enum(opt_key, config); if (opt_key == "support_pillar_connection_mode") return get_string_from_enum(opt_key, config); + if (opt_key == "brim_type") + return get_string_from_enum(opt_key, config); break; } case coPoints: { @@ -985,23 +1167,6 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return out; } -wxString UnsavedChangesDialog::get_short_string(wxString full_string) -{ - int max_len = 30; - if (full_string.IsEmpty() || full_string.StartsWith("#") || - (full_string.Find("\n") == wxNOT_FOUND && full_string.Length() < size_t(max_len))) - return full_string; - - m_has_long_strings = true; - - int n_pos = full_string.Find("\n"); - if (n_pos != wxNOT_FOUND && n_pos < max_len) - max_len = n_pos; - - full_string.Truncate(max_len); - return full_string + dots; -} - void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header) { PresetCollection* presets = dependent_presets; @@ -1063,7 +1228,7 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres const std::map& category_icon_map = wxGetApp().get_tab(type)->get_category_icon_map(); - m_tree_model->AddPreset(type, from_u8(presets->get_edited_preset().name), old_pt); + m_tree->model->AddPreset(type, from_u8(presets->get_edited_preset().name), old_pt); // Collect dirty options. const bool deep_compare = (type == Preset::TYPE_PRINTER || type == Preset::TYPE_SLA_MATERIAL); @@ -1076,9 +1241,7 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres wxString old_val = from_u8((boost::format("%1%") % old_config.opt("extruder_colour")->values.size()).str()); wxString new_val = from_u8((boost::format("%1%") % new_config.opt("extruder_colour")->values.size()).str()); - ItemData item_data = { "extruders_count", local_label, old_val, new_val, type }; - m_items_map.emplace(m_tree_model->AddOption(type, _L("General"), _L("Capabilities"), local_label, old_val, new_val, category_icon_map.at("General")), item_data); - + m_tree->Append("extruders_count", type, _L("General"), _L("Capabilities"), local_label, old_val, new_val, category_icon_map.at("General")); } for (const std::string& opt_key : dirty_options) { @@ -1090,43 +1253,12 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres continue; } - ItemData item_data = { opt_key, option.label_local, get_string_value(opt_key, old_config), get_string_value(opt_key, new_config), type }; - - wxString old_val = get_short_string(item_data.old_val); - wxString new_val = get_short_string(item_data.new_val); - if (old_val != item_data.old_val || new_val != item_data.new_val) - item_data.is_long = true; - - m_items_map.emplace(m_tree_model->AddOption(type, option.category_local, option.group_local, option.label_local, old_val, new_val, category_icon_map.at(option.category)), item_data); + m_tree->Append(opt_key, type, option.category_local, option.group_local, option.label_local, + get_string_value(opt_key, old_config), get_string_value(opt_key, new_config), category_icon_map.at(option.category)); } } } -std::vector UnsavedChangesDialog::get_unselected_options(Preset::Type type) -{ - std::vector ret; - - for (auto item : m_items_map) { - if (item.second.opt_key == "extruders_count") - continue; - if (item.second.type == type && !m_tree_model->IsEnabledItem(item.first)) - ret.emplace_back(get_pure_opt_key(item.second.opt_key)); - } - - return ret; -} - -std::vector UnsavedChangesDialog::get_selected_options() -{ - std::vector ret; - - for (auto item : m_items_map) - if (m_tree_model->IsEnabledItem(item.first)) - ret.emplace_back(get_pure_opt_key(item.second.opt_key)); - - return ret; -} - void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect) { int em = em_unit(); @@ -1135,16 +1267,10 @@ void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect) for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn } ) if (btn) btn->msw_rescale(); - const wxSize& size = wxSize(80 * em, 30 * em); + const wxSize& size = wxSize(70 * em, 30 * em); SetMinSize(size); - m_tree->GetColumn(UnsavedChangesModel::colToggle )->SetWidth(6 * em); - m_tree->GetColumn(UnsavedChangesModel::colIconText)->SetWidth(30 * em); - m_tree->GetColumn(UnsavedChangesModel::colOldValue)->SetWidth(20 * em); - m_tree->GetColumn(UnsavedChangesModel::colNewValue)->SetWidth(20 * em); - - m_tree_model->Rescale(); - m_tree->Refresh(); + m_tree->Rescale(em); Fit(); Refresh(); @@ -1155,8 +1281,7 @@ void UnsavedChangesDialog::on_sys_color_changed() for (auto btn : { m_save_btn, m_transfer_btn, m_discard_btn } ) btn->msw_rescale(); // msw_rescale updates just icons, so use it - m_tree_model->Rescale(); - m_tree->Refresh(); + m_tree->Rescale(); Refresh(); } @@ -1188,16 +1313,45 @@ FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString grid_sizer->Add(text, 0, wxALL, border); }; - auto add_value = [grid_sizer, border, this](wxString label, bool is_colored = false) { - wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, label, wxDefaultPosition, wxSize(300, -1), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE | wxTE_RICH); - text->SetStyle(0, label.Len(), wxTextAttr(is_colored ? wxColour(orange) : wxNullColour, wxNullColour, this->GetFont())); - grid_sizer->Add(text, 1, wxALL | wxEXPAND, border); - }; - add_header(_L("Old value")); add_header(_L("New value")); - add_value(old_value); - add_value(new_value, true); + + auto get_set_from_val = [](wxString str) { + if (str.Find("\n") == wxNOT_FOUND) + str.Replace(" ", "\n"); + + std::set str_set; + + wxStringTokenizer strings(str, "\n"); + while (strings.HasMoreTokens()) + str_set.emplace(strings.GetNextToken()); + + return str_set; + }; + + std::set old_set = get_set_from_val(old_value); + std::set new_set = get_set_from_val(new_value); + std::set old_new_diff_set; + std::set new_old_diff_set; + + std::set_difference(old_set.begin(), old_set.end(), new_set.begin(), new_set.end(), std::inserter(old_new_diff_set, old_new_diff_set.begin())); + std::set_difference(new_set.begin(), new_set.end(), old_set.begin(), old_set.end(), std::inserter(new_old_diff_set, new_old_diff_set.begin())); + + auto add_value = [grid_sizer, border, this](wxString label, const std::set& diff_set, bool is_colored = false) { + wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, label, wxDefaultPosition, wxSize(400, 400), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE | wxTE_RICH); + text->SetStyle(0, label.Len(), wxTextAttr(is_colored ? wxColour(orange) : wxNullColour, wxNullColour, this->GetFont())); + + for (const wxString& str : diff_set) { + int pos = label.First(str); + if (pos == wxNOT_FOUND) + continue; + text->SetStyle(pos, pos + (int)str.Len(), wxTextAttr(is_colored ? wxColour(orange) : wxNullColour, wxNullColour, this->GetFont().Bold())); + } + + grid_sizer->Add(text, 1, wxALL | wxEXPAND, border); + }; + add_value(old_value, old_new_diff_set); + add_value(new_value, new_old_diff_set, true); sizer->Add(grid_sizer, 1, wxEXPAND); @@ -1213,6 +1367,383 @@ FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString } +static PresetCollection* get_preset_collection(Preset::Type type, PresetBundle* preset_bundle = nullptr) { + if (!preset_bundle) + preset_bundle = wxGetApp().preset_bundle; + return type == Preset::Type::TYPE_PRINT ? &preset_bundle->prints : + type == Preset::Type::TYPE_SLA_PRINT ? &preset_bundle->sla_prints : + type == Preset::Type::TYPE_FILAMENT ? &preset_bundle->filaments : + type == Preset::Type::TYPE_SLA_MATERIAL ? &preset_bundle->sla_materials : + type == Preset::Type::TYPE_PRINTER ? &preset_bundle->printers : + nullptr; +} + +//------------------------------------------ +// DiffPresetDialog +//------------------------------------------ +static std::string get_selection(PresetComboBox* preset_combo) +{ + return into_u8(preset_combo->GetString(preset_combo->GetSelection())); +} + +DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) + : DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology()) +{ + wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + SetBackgroundColour(bgr_clr); + +#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) + // ys_FIXME! temporary workaround for correct font scaling + // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, + // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT + this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); +#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT + + int border = 10; + int em = em_unit(); + + assert(wxGetApp().preset_bundle); + + m_preset_bundle_left = std::make_unique(*wxGetApp().preset_bundle); + m_preset_bundle_right = std::make_unique(*wxGetApp().preset_bundle); + + m_top_info_line = new wxStaticText(this, wxID_ANY, "Select presets to compare"); + m_top_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); + + m_bottom_info_line = new wxStaticText(this, wxID_ANY, ""); + m_bottom_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); + + wxBoxSizer* presets_sizer = new wxBoxSizer(wxVERTICAL); + + for (auto new_type : { Preset::TYPE_PRINT, Preset::TYPE_FILAMENT, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL, Preset::TYPE_PRINTER }) + { + const PresetCollection* collection = get_preset_collection(new_type); + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + PresetComboBox* presets_left; + PresetComboBox* presets_right; + ScalableButton* equal_bmp = new ScalableButton(this, wxID_ANY, "equal"); + + auto add_preset_combobox = [collection, sizer, new_type, em, this](PresetComboBox** cb_, PresetBundle* preset_bundle) { + *cb_ = new PresetComboBox(this, new_type, wxSize(em * 35, -1), preset_bundle); + PresetComboBox* cb = (*cb_); + cb->set_selection_changed_function([this, new_type, preset_bundle, cb](int selection) { + if (m_view_type == Preset::TYPE_INVALID) { + std::string preset_name = cb->GetString(selection).ToUTF8().data(); + update_compatibility(Preset::remove_suffix_modified(preset_name), new_type, preset_bundle); + } + update_tree(); + }); + if (collection->get_selected_idx() != (size_t)-1) + cb->update(collection->get_selected_preset().name); + + sizer->Add(cb, 1); + cb->Show(new_type == Preset::TYPE_PRINTER); + }; + add_preset_combobox(&presets_left, m_preset_bundle_left.get()); + sizer->Add(equal_bmp, 0, wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5); + add_preset_combobox(&presets_right, m_preset_bundle_right.get()); + presets_sizer->Add(sizer, 1, wxTOP, 5); + equal_bmp->Show(new_type == Preset::TYPE_PRINTER); + + m_preset_combos.push_back({ presets_left, equal_bmp, presets_right }); + + equal_bmp->Bind(wxEVT_BUTTON, [presets_left, presets_right, this](wxEvent&) { + std::string preset_name = get_selection(presets_left); + presets_right->update(preset_name); + if (m_view_type == Preset::TYPE_INVALID) + update_compatibility(Preset::remove_suffix_modified(preset_name), presets_right->get_type(), m_preset_bundle_right.get()); + update_tree(); + }); + } + + m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all preset (including incompatible)")); + m_show_all_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { + bool show_all = m_show_all_presets->GetValue(); + for (auto preset_combos : m_preset_combos) { + if (preset_combos.presets_left->get_type() == Preset::TYPE_PRINTER) + continue; + preset_combos.presets_left->show_all(show_all); + preset_combos.presets_right->show_all(show_all); + } + if (m_view_type == Preset::TYPE_INVALID) + update_tree(); + }); + + m_tree = new DiffViewCtrl(this, wxSize(em * 65, em * 40)); + m_tree->AppendBmpTextColumn("", DiffModel::colIconText, 35); + m_tree->AppendBmpTextColumn(_L("Left Preset Value"), DiffModel::colOldValue, 15); + m_tree->AppendBmpTextColumn(_L("Right Preset Value"),DiffModel::colNewValue, 15); + m_tree->Hide(); + + wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); + + topSizer->Add(m_top_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2 * border); + topSizer->Add(presets_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); + topSizer->Add(m_show_all_presets, 0, wxEXPAND | wxALL, border); + topSizer->Add(m_bottom_info_line, 0, wxEXPAND | wxALL, 2 * border); + topSizer->Add(m_tree, 1, wxEXPAND | wxALL, border); + + this->SetMinSize(wxSize(80 * em, 30 * em)); + this->SetSizer(topSizer); + topSizer->SetSizeHints(this); +} + +void DiffPresetDialog::update_controls_visibility(Preset::Type type /* = Preset::TYPE_INVALID*/) +{ + for (auto preset_combos : m_preset_combos) { + Preset::Type cb_type = preset_combos.presets_left->get_type(); + bool show = type != Preset::TYPE_INVALID ? type == cb_type : + cb_type == Preset::TYPE_PRINTER ? true : + m_pr_technology == ptFFF ? cb_type == Preset::TYPE_PRINT || cb_type == Preset::TYPE_FILAMENT : + cb_type == Preset::TYPE_SLA_PRINT || cb_type == Preset::TYPE_SLA_MATERIAL; + preset_combos.presets_left->Show(show); + preset_combos.equal_bmp->Show(show); + preset_combos.presets_right->Show(show); + + if (show) { + preset_combos.presets_left->update_from_bundle(); + preset_combos.presets_right->update_from_bundle(); + } + } + + m_show_all_presets->Show(type != Preset::TYPE_PRINTER); +} + +void DiffPresetDialog::update_bundles_from_app() +{ + *m_preset_bundle_left = *wxGetApp().preset_bundle; + *m_preset_bundle_right = *wxGetApp().preset_bundle; +} + +void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/) +{ + this->SetTitle(type == Preset::TYPE_INVALID ? _L("Compare Presets") : format_wxstr(_L("Compare %1% Presets"), wxGetApp().get_tab(type)->name())); + m_view_type = type; + + update_bundles_from_app(); + update_controls_visibility(type); + if (type == Preset::TYPE_INVALID) + Fit(); + + update_tree(); + + // if this dialog is shown it have to be Hide and show again to be placed on the very Top of windows + if (IsShown()) + Hide(); + Show(); +} + +void DiffPresetDialog::update_presets(Preset::Type type) +{ + m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology(); + + update_bundles_from_app(); + update_controls_visibility(type); + + if (type == Preset::TYPE_INVALID) + for (auto preset_combos : m_preset_combos) { + if (preset_combos.presets_left->get_type() == Preset::TYPE_PRINTER) { + preset_combos.presets_left->update_from_bundle (); + preset_combos.presets_right->update_from_bundle(); + break; + } + } + else + for (auto preset_combos : m_preset_combos) { + if (preset_combos.presets_left->get_type() == type) { + preset_combos.presets_left->update(); + preset_combos.presets_right->update(); + break; + } + } + + update_tree(); +} + +void DiffPresetDialog::update_tree() +{ + Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher(); + searcher.sort_options_by_opt_key(); + + m_tree->Clear(); + wxString bottom_info = ""; + bool show_tree = false; + + for (auto preset_combos : m_preset_combos) + { + if (!preset_combos.presets_left->IsShown()) + continue; + Preset::Type type = preset_combos.presets_left->get_type(); + + const PresetCollection* presets = get_preset_collection(type); + const Preset* left_preset = presets->find_preset(get_selection(preset_combos.presets_left)); + const Preset* right_preset = presets->find_preset(get_selection(preset_combos.presets_right)); + if (!left_preset || !right_preset) { + bottom_info = _L("One of the presets doesn't found"); + preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "question")); + preset_combos.equal_bmp->SetToolTip(bottom_info); + continue; + } + + const DynamicPrintConfig& left_config = left_preset->config; + const PrinterTechnology& left_pt = left_preset->printer_technology(); + const DynamicPrintConfig& right_congig = right_preset->config; + + if (left_pt != right_preset->printer_technology()) { + bottom_info = _L("Comparable printer presets has different printer technology"); + preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "question")); + preset_combos.equal_bmp->SetToolTip(bottom_info); + continue; + } + + // Collect dirty options. + const bool deep_compare = (type == Preset::TYPE_PRINTER || type == Preset::TYPE_SLA_MATERIAL); + auto dirty_options = type == Preset::TYPE_PRINTER && left_pt == ptFFF && + left_config.opt("extruder_colour")->values.size() < right_congig.opt("extruder_colour")->values.size() ? + presets->dirty_options(right_preset, left_preset, deep_compare) : + presets->dirty_options(left_preset, right_preset, deep_compare); + + if (dirty_options.empty()) { + bottom_info = _L("Presets are the same"); + preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "equal")); + preset_combos.equal_bmp->SetToolTip(bottom_info); + continue; + } + + show_tree = true; + preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "not_equal")); + preset_combos.equal_bmp->SetToolTip(_L("Presets are different.\n" + "Click this button to select the same as left preset for the right preset.")); + + m_tree->model->AddPreset(type, "\"" + from_u8(left_preset->name) + "\" vs \"" + from_u8(right_preset->name) + "\"", left_pt); + + const std::map& category_icon_map = wxGetApp().get_tab(type)->get_category_icon_map(); + + // process changes of extruders count + if (type == Preset::TYPE_PRINTER && left_pt == ptFFF && + left_config.opt("extruder_colour")->values.size() != right_congig.opt("extruder_colour")->values.size()) { + wxString local_label = _L("Extruders count"); + wxString left_val = from_u8((boost::format("%1%") % left_config.opt("extruder_colour")->values.size()).str()); + wxString right_val = from_u8((boost::format("%1%") % right_congig.opt("extruder_colour")->values.size()).str()); + + m_tree->Append("extruders_count", type, _L("General"), _L("Capabilities"), local_label, left_val, right_val, category_icon_map.at("General")); + } + + for (const std::string& opt_key : dirty_options) { + wxString left_val = get_string_value(opt_key, left_config); + wxString right_val = get_string_value(opt_key, right_congig); + + Search::Option option = searcher.get_option(opt_key, get_full_label(opt_key, left_config), type); + if (option.opt_key != boost::nowide::widen(opt_key)) { + // temporary solution, just for testing + m_tree->Append(opt_key, type, _L("Undef category"), _L("Undef group"), opt_key, left_val, right_val, "question"); + // When founded option isn't the correct one. + // It can be for dirty_options: "default_print_profile", "printer_model", "printer_settings_id", + // because of they don't exist in searcher + continue; + } + m_tree->Append(opt_key, type, option.category_local, option.group_local, option.label_local, + left_val, right_val, category_icon_map.at(option.category)); + } + } + + bool tree_was_shown = m_tree->IsShown(); + m_tree->Show(show_tree); + if (!show_tree) + m_bottom_info_line->SetLabel(bottom_info); + m_bottom_info_line->Show(!show_tree); + + if (tree_was_shown == m_tree->IsShown()) + Layout(); + else { + Fit(); + Refresh(); + } +} + +void DiffPresetDialog::on_dpi_changed(const wxRect&) +{ + int em = em_unit(); + + msw_buttons_rescale(this, em, { wxID_CANCEL}); + + const wxSize& size = wxSize(80 * em, 30 * em); + SetMinSize(size); + + for (auto preset_combos : m_preset_combos) { + preset_combos.presets_left->msw_rescale(); + preset_combos.equal_bmp->msw_rescale(); + preset_combos.presets_right->msw_rescale(); + } + + m_tree->Rescale(em); + + Fit(); + Refresh(); +} + +void DiffPresetDialog::on_sys_color_changed() +{ + // msw_rescale updates just icons, so use it + m_tree->Rescale(); + Refresh(); +} + +void DiffPresetDialog::update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle) +{ + PresetCollection* presets = get_preset_collection(type, preset_bundle); + + bool print_tab = type == Preset::TYPE_PRINT || type == Preset::TYPE_SLA_PRINT; + bool printer_tab = type == Preset::TYPE_PRINTER; + bool technology_changed = false; + + if (printer_tab) { + const Preset& new_printer_preset = *presets->find_preset(preset_name, true); + PrinterTechnology old_printer_technology = presets->get_selected_preset().printer_technology(); + PrinterTechnology new_printer_technology = new_printer_preset.printer_technology(); + + technology_changed = old_printer_technology != new_printer_technology; + } + + // Mark the print & filament enabled if they are compatible with the currently selected preset. + // The following method should not discard changes of current print or filament presets on change of a printer profile, + // if they are compatible with the current printer. + auto update_compatible_type = [](bool technology_changed, bool on_page, bool show_incompatible_presets) { + return technology_changed ? PresetSelectCompatibleType::Always : + on_page ? PresetSelectCompatibleType::Never : + show_incompatible_presets ? PresetSelectCompatibleType::OnlyIfWasCompatible : PresetSelectCompatibleType::Always; + }; + if (print_tab || printer_tab) + preset_bundle->update_compatible( + update_compatible_type(technology_changed, print_tab, true), + update_compatible_type(technology_changed, false, true)); + + bool is_left_presets = preset_bundle == m_preset_bundle_left.get(); + PrinterTechnology pr_tech = preset_bundle->printers.get_selected_preset().printer_technology(); + + // update preset comboboxes + for (auto preset_combos : m_preset_combos) + { + PresetComboBox* cb = is_left_presets ? preset_combos.presets_left : preset_combos.presets_right; + Preset::Type presets_type = cb->get_type(); + if ((print_tab && ( + (pr_tech == ptFFF && presets_type == Preset::TYPE_FILAMENT) || + (pr_tech == ptSLA && presets_type == Preset::TYPE_SLA_MATERIAL) )) || + (printer_tab && ( + (pr_tech == ptFFF && (presets_type == Preset::TYPE_PRINT || presets_type == Preset::TYPE_FILAMENT) ) || + (pr_tech == ptSLA && (presets_type == Preset::TYPE_SLA_PRINT || presets_type == Preset::TYPE_SLA_MATERIAL) )) )) + cb->update(); + } + + if (technology_changed && + m_preset_bundle_left.get()->printers.get_selected_preset().printer_technology() == + m_preset_bundle_right.get()->printers.get_selected_preset().printer_technology()) + { + m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology(); + update_controls_visibility(); + } +} } diff --git a/src/slic3r/GUI/UnsavedChangesDialog.hpp b/src/slic3r/GUI/UnsavedChangesDialog.hpp index 232802b661..06838d9361 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.hpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.hpp @@ -7,7 +7,7 @@ #include "GUI_Utils.hpp" #include "wxExtensions.hpp" -#include "libslic3r/Preset.hpp" +#include "libslic3r/PresetBundle.hpp" class ScalableButton; class wxStaticText; @@ -16,10 +16,12 @@ namespace Slic3r { namespace GUI{ // ---------------------------------------------------------------------------- -// ModelNode: a node inside UnsavedChangesModel +// ModelNode: a node inside DiffModel // ---------------------------------------------------------------------------- class ModelNode; +class PresetComboBox; +class MainFrame; using ModelNodePtrArray = std::vector>; // On all of 3 different platforms Bitmap+Text icon column looks different @@ -42,17 +44,6 @@ class ModelNode wxString m_old_color; wxString m_new_color; - // TODO/FIXME: - // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) - // needs to know in advance if a node is or _will be_ a container. - // Thus implementing: - // bool IsContainer() const - // { return m_children.size()>0; } - // doesn't work with wxGTK when UnsavedChangesModel::AddToClassical is called - // AND the classical node was removed (a new node temporary without children - // would be added to the control) - bool m_container {true}; - #ifdef __linux__ wxIcon get_bitmap(const wxString& color); #else @@ -75,6 +66,17 @@ public: wxString m_old_value; wxString m_new_value; + // TODO/FIXME: + // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) + // needs to know in advance if a node is or _will be_ a container. + // Thus implementing: + // bool IsContainer() const + // { return m_children.size()>0; } + // doesn't work with wxGTK when DiffModel::AddToClassical is called + // AND the classical node was removed (a new node temporary without children + // would be added to the control) + bool m_container {true}; + // preset(root) node ModelNode(Preset::Type preset_type, wxWindow* parent_win, const wxString& text, const std::string& icon_name); @@ -107,13 +109,13 @@ public: // ---------------------------------------------------------------------------- -// UnsavedChangesModel +// DiffModel // ---------------------------------------------------------------------------- -class UnsavedChangesModel : public wxDataViewModel +class DiffModel : public wxDataViewModel { wxWindow* m_parent_win { nullptr }; - std::vector m_preset_nodes; + ModelNodePtrArray m_preset_nodes; wxDataViewCtrl* m_ctrl{ nullptr }; @@ -143,8 +145,8 @@ public: colMax }; - UnsavedChangesModel(wxWindow* parent); - ~UnsavedChangesModel(); + DiffModel(wxWindow* parent); + ~DiffModel() {} void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } @@ -159,6 +161,9 @@ public: wxString GetColumnType(unsigned int col) const override; void Rescale(); + wxDataViewItem Delete(const wxDataViewItem& item); + void Clear(); + wxDataViewItem GetParent(const wxDataViewItem& item) const override; unsigned int GetChildren(const wxDataViewItem& parent, wxDataViewItemArray& array) const override; @@ -173,14 +178,60 @@ public: }; +// ---------------------------------------------------------------------------- +// DiffViewCtrl +// ---------------------------------------------------------------------------- + +class DiffViewCtrl : public wxDataViewCtrl +{ + bool m_has_long_strings{ false }; + bool m_empty_selection { false }; + int m_em_unit; + + struct ItemData + { + std::string opt_key; + wxString opt_name; + wxString old_val; + wxString new_val; + Preset::Type type; + bool is_long{ false }; + }; + + // tree items related to the options + std::map m_items_map; + std::map m_columns_width; + +public: + DiffViewCtrl(wxWindow* parent, wxSize size); + ~DiffViewCtrl() {} + + DiffModel* model{ nullptr }; + + void AppendBmpTextColumn(const wxString& label, unsigned model_column, int width, bool set_expander = false); + void AppendToggleColumn_(const wxString& label, unsigned model_column, int width); + void Rescale(int em = 0); + void Append(const std::string& opt_key, Preset::Type type, wxString category_name, wxString group_name, wxString option_name, + wxString old_value, wxString new_value, const std::string category_icon_name); + void Clear(); + + wxString get_short_string(wxString full_string); + bool has_selection() { return !m_empty_selection; } + void context_menu(wxDataViewEvent& event); + void item_value_changed(wxDataViewEvent& event); + void set_em_unit(int em) { m_em_unit = em; } + + std::vector unselected_options(Preset::Type type); + std::vector selected_options(); +}; + + //------------------------------------------ // UnsavedChangesDialog //------------------------------------------ class UnsavedChangesDialog : public DPIDialog { - wxDataViewCtrl* m_tree { nullptr }; - UnsavedChangesModel* m_tree_model { nullptr }; - + DiffViewCtrl* m_tree { nullptr }; ScalableButton* m_save_btn { nullptr }; ScalableButton* m_transfer_btn { nullptr }; ScalableButton* m_discard_btn { nullptr }; @@ -188,7 +239,6 @@ class UnsavedChangesDialog : public DPIDialog wxStaticText* m_info_line { nullptr }; wxCheckBox* m_remember_choice { nullptr }; - bool m_empty_selection { false }; bool m_has_long_strings { false }; int m_save_btn_id { wxID_ANY }; int m_move_btn_id { wxID_ANY }; @@ -209,19 +259,6 @@ class UnsavedChangesDialog : public DPIDialog // selected action after Dialog closing Action m_exit_action {Action::Undef}; - - struct ItemData - { - std::string opt_key; - wxString opt_name; - wxString old_val; - wxString new_val; - Preset::Type type; - bool is_long {false}; - }; - // tree items related to the options - std::map m_items_map; - // preset names which are modified in SavePresetDialog and related types std::vector> names_and_types; @@ -230,13 +267,9 @@ public: UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset); ~UnsavedChangesDialog() {} - wxString get_short_string(wxString full_string); - void build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header = ""); void update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header); void update_tree(Preset::Type type, PresetCollection *presets); - void item_value_changed(wxDataViewEvent &event); - void context_menu(wxDataViewEvent &event); void show_info_line(Action action, std::string preset_name = ""); void update_config(Action action); void close(Action action); @@ -251,8 +284,8 @@ public: // short version of the previous function, for the case, when just one preset is modified std::string get_preset_name() { return names_and_types[0].first; } - std::vector get_unselected_options(Preset::Type type); - std::vector get_selected_options(); + std::vector get_unselected_options(Preset::Type type) { return m_tree->unselected_options(type); } + std::vector get_selected_options() { return m_tree->selected_options(); } protected: void on_dpi_changed(const wxRect& suggested_rect) override; @@ -270,6 +303,48 @@ public: ~FullCompareDialog() {} }; + +//------------------------------------------ +// DiffPresetDialog +//------------------------------------------ +class DiffPresetDialog : public DPIDialog +{ + DiffViewCtrl* m_tree { nullptr }; + wxStaticText* m_top_info_line { nullptr }; + wxStaticText* m_bottom_info_line { nullptr }; + wxCheckBox* m_show_all_presets { nullptr }; + + Preset::Type m_view_type { Preset::TYPE_INVALID }; + PrinterTechnology m_pr_technology; + std::unique_ptr m_preset_bundle_left; + std::unique_ptr m_preset_bundle_right; + + void update_tree(); + void update_bundles_from_app(); + void update_controls_visibility(Preset::Type type = Preset::TYPE_INVALID); + void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle); + + struct DiffPresets + { + PresetComboBox* presets_left { nullptr }; + ScalableButton* equal_bmp { nullptr }; + PresetComboBox* presets_right { nullptr }; + }; + + std::vector m_preset_combos; + +public: + DiffPresetDialog(MainFrame* mainframe); + ~DiffPresetDialog() {} + + void show(Preset::Type type = Preset::TYPE_INVALID); + void update_presets(Preset::Type type = Preset::TYPE_INVALID); + +protected: + void on_dpi_changed(const wxRect& suggested_rect) override; + void on_sys_color_changed() override; +}; + } } diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index 970cd85284..1c3c831b89 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -263,9 +263,39 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, con gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("unloaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); gridsizer_simple->Add(new wxStaticText(m_page_simple,wxID_ANY,wxString(_(L("loaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); + auto add_spin_ctrl = [this](std::vector& vec, float initial) + { + wxSpinCtrl* spin_ctrl = new wxSpinCtrl(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), wxSP_ARROW_KEYS | wxALIGN_RIGHT, 0, 300, (int)initial); + vec.push_back(spin_ctrl); + +#ifdef __WXOSX__ + // On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value + // when it was changed from the text control, so the on_change callback + // gets the old one, and on_kill_focus resets the control to the old value. + // As a workaround, we get the new value from $event->GetString and store + // here temporarily so that we can return it from get_value() + spin_ctrl->Bind(wxEVT_TEXT, ([spin_ctrl](wxCommandEvent e) + { + long value; + const bool parsed = e.GetString().ToLong(&value); + int tmp_value = parsed && value >= INT_MIN && value <= INT_MAX ? (int)value : INT_MIN; + + // Forcibly set the input value for SpinControl, since the value + // inserted from the keyboard or clipboard is not updated under OSX + if (tmp_value != INT_MIN) { + spin_ctrl->SetValue(tmp_value); + + // But in SetValue() is executed m_text_ctrl->SelectAll(), so + // discard this selection and set insertion point to the end of string + spin_ctrl->GetText()->SetInsertionPointEnd(); + } + }), spin_ctrl->GetId()); +#endif + }; + for (unsigned int i=0;i get_extruder_color_icons(bool thin_icon/* = false*/) const int icon_width = lround((thin_icon ? 1.6 : 3.2) * em); const int icon_height = lround(1.6 * em); + bool dark_mode = Slic3r::GUI::wxGetApp().dark_mode(); + for (const std::string& color : colors) { std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width); @@ -476,7 +478,7 @@ std::vector get_extruder_color_icons(bool thin_icon/* = false*/) // Paint the color icon. Slic3r::GUI::BitmapCache::parse_color(color, rgb); // there is no neede to scale created solid bitmap - bitmap = bmp_cache.insert(bitmap_key, bmp_cache.mksolid(icon_width, icon_height, rgb, true)); + bitmap = bmp_cache.insert(bitmap_key, bmp_cache.mksolid(icon_width, icon_height, rgb, false, 1, dark_mode)); } bmps.emplace_back(bitmap); } diff --git a/src/slic3r/Utils/Bonjour.cpp b/src/slic3r/Utils/Bonjour.cpp index 28b3b2228a..f121e6e87a 100644 --- a/src/slic3r/Utils/Bonjour.cpp +++ b/src/slic3r/Utils/Bonjour.cpp @@ -226,7 +226,7 @@ struct DnsResource } dataoffset = offset; - res.data = std::move(std::vector(buffer.begin() + offset, buffer.begin() + offset + rdlength)); + res.data = std::vector(buffer.begin() + offset, buffer.begin() + offset + rdlength); offset += rdlength; return std::move(res); diff --git a/src/slic3r/Utils/FlashAir.cpp b/src/slic3r/Utils/FlashAir.cpp index 22eaddecef..2337ac2904 100644 --- a/src/slic3r/Utils/FlashAir.cpp +++ b/src/slic3r/Utils/FlashAir.cpp @@ -50,7 +50,7 @@ bool FlashAir::test(wxString &msg) const res = false; msg = format_error(body, error, status); }) - .on_complete([&, this](std::string body, unsigned) { + .on_complete([&](std::string body, unsigned) { BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got upload enabled: %2%") % name % body; res = boost::starts_with(body, "1"); diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 94a8c9a56d..2afb7ed504 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -553,7 +553,7 @@ void Http::cancel() Http Http::get(std::string url) { - return std::move(Http{std::move(url)}); + return Http{std::move(url)}; } Http Http::post(std::string url) diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index adbd72aabd..512e96b94d 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -2,9 +2,12 @@ #import +#import #import #import +@interface MacDarkMode : NSObject {} +@end @implementation MacDarkMode diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index ed1c61bd60..f1b36096c6 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -20,7 +20,7 @@ public: OctoPrint(DynamicPrintConfig *config); ~OctoPrint() override = default; - const char* get_name() const; + const char* get_name() const override; bool test(wxString &curl_msg) const override; wxString get_test_ok_msg () const override; diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 60dfe05c78..f0310073fd 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -206,7 +206,7 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe tmp_path.string()); Http::get(url) - .on_progress([this](Http::Progress, bool &cancel) { + .on_progress([](Http::Progress, bool &cancel) { if (cancel) { cancel = true; } }) .on_error([&](std::string body, std::string error, unsigned http_status) { @@ -406,7 +406,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version BOOST_LOG_TRIVIAL(info) << "Checking for cached configuration updates..."; // Over all indices from the cache directory: - for (const auto idx : index_db) { + for (const Index& idx : index_db) { auto bundle_path = vendor_path / (idx.vendor() + ".ini"); auto bundle_path_idx = vendor_path / idx.path().filename(); @@ -679,11 +679,11 @@ void PresetUpdater::sync(PresetBundle *preset_bundle) // into the closure (but perhaps the compiler can elide this). VendorMap vendors = preset_bundle->vendors; - p->thread = std::move(std::thread([this, vendors]() { + p->thread = std::thread([this, vendors]() { this->p->prune_tmps(); this->p->sync_version(); this->p->sync_config(std::move(vendors)); - })); + }); } void PresetUpdater::slic3r_update_notify() diff --git a/src/slic3r/Utils/Repetier.cpp b/src/slic3r/Utils/Repetier.cpp index 115ea010ef..7b66922d70 100644 --- a/src/slic3r/Utils/Repetier.cpp +++ b/src/slic3r/Utils/Repetier.cpp @@ -190,7 +190,7 @@ bool Repetier::get_groups(wxArrayString& groups) const http.on_error([&](std::string body, std::string error, unsigned status) { BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; }) - .on_complete([&, this](std::string body, unsigned) { + .on_complete([&](std::string body, unsigned) { BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got groups: %2%") % name % body; try { @@ -233,7 +233,7 @@ bool Repetier::get_printers(wxArrayString& printers) const BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error listing printers: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; res = false; }) - .on_complete([&, this](std::string body, unsigned http_status) { + .on_complete([&](std::string body, unsigned http_status) { BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got printers: %2%, HTTP status: %3%") % name % body % http_status; if (http_status != 200) diff --git a/src/slic3r/Utils/Repetier.hpp b/src/slic3r/Utils/Repetier.hpp index d94d7ec56a..5141dc040b 100644 --- a/src/slic3r/Utils/Repetier.hpp +++ b/src/slic3r/Utils/Repetier.hpp @@ -19,7 +19,7 @@ public: Repetier(DynamicPrintConfig *config); ~Repetier() override = default; - const char* get_name() const; + const char* get_name() const override; bool test(wxString &curl_msg) const override; wxString get_test_ok_msg () const override; diff --git a/src/slic3r/Utils/RetinaHelper.hpp b/src/slic3r/Utils/RetinaHelper.hpp index 659bc7f562..336fc17c4f 100644 --- a/src/slic3r/Utils/RetinaHelper.hpp +++ b/src/slic3r/Utils/RetinaHelper.hpp @@ -18,7 +18,9 @@ public: float get_scale_factor(); private: +#ifdef __WXGTK3__ wxWindow* m_window; +#endif // __WXGTK3__ void* m_self; }; diff --git a/src/slic3r/Utils/RetinaHelperImpl.mm b/src/slic3r/Utils/RetinaHelperImpl.mm index de0402d34c..509029a10e 100644 --- a/src/slic3r/Utils/RetinaHelperImpl.mm +++ b/src/slic3r/Utils/RetinaHelperImpl.mm @@ -11,8 +11,7 @@ namespace Slic3r { namespace GUI { -RetinaHelper::RetinaHelper(wxWindow* window) : - m_window(window) +RetinaHelper::RetinaHelper(wxWindow *window) { m_self = nullptr; m_self = [[RetinaHelperImpl alloc] initWithView:window->GetHandle() handler:window->GetEventHandler()]; @@ -20,7 +19,7 @@ RetinaHelper::RetinaHelper(wxWindow* window) : RetinaHelper::~RetinaHelper() { - [m_self release]; + [(id)m_self release]; } void RetinaHelper::set_use_retina(bool aValue) diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index d82d9e31db..697c1209de 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -209,7 +209,7 @@ public: bool is_immutable() const override { return true; } bool is_optional() const override { return m_optional; } // If it is an immutable object, return its pointer. There is a map assigning a temporary ObjectID to the immutable object pointer. - const void* immutable_object_ptr() const { return (const void*)m_shared_object.get(); } + const void* immutable_object_ptr() const override { return (const void*)m_shared_object.get(); } // Estimated size in memory, to be used to drop least recently used snapshots. size_t memsize() const override { diff --git a/src/slic3r/pchheader.hpp b/src/slic3r/pchheader.hpp index ebdabe8366..816733f453 100644 --- a/src/slic3r/pchheader.hpp +++ b/src/slic3r/pchheader.hpp @@ -78,10 +78,17 @@ #include #include #include + +// boost/property_tree/json_parser/detail/parser.hpp includes boost/bind.hpp, which is deprecated. +// Suppress the following boost message: +// The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. +#define BOOST_BIND_GLOBAL_PLACEHOLDERS #include #include #include #include +#undef BOOST_BIND_GLOBAL_PLACEHOLDERS + #include #include diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp index c98cdcf430..222e94d990 100644 --- a/tests/fff_print/test_fill.cpp +++ b/tests/fff_print/test_fill.cpp @@ -126,7 +126,7 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { filler->angle = 0; Surface surface(stTop, expolygon); - auto flow = Slic3r::Flow(0.69, 0.4, 0.50); + auto flow = Slic3r::Flow(0.69f, 0.4f, 0.50f); FillParams fill_params; fill_params.density = 1.0; @@ -435,7 +435,7 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacin filler->bounding_box = get_extents(expolygon.contour); filler->angle = float(angle); - Flow flow(flow_spacing, 0.4, flow_spacing); + Flow flow(float(flow_spacing), 0.4f, float(flow_spacing)); filler->spacing = flow.spacing(); FillParams fill_params; diff --git a/tests/fff_print/test_printobject.cpp b/tests/fff_print/test_printobject.cpp index 84df95201a..8d322f58fe 100644 --- a/tests/fff_print/test_printobject.cpp +++ b/tests/fff_print/test_printobject.cpp @@ -18,7 +18,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 2 }, { "nozzle_diameter", 3 } }); - const std::vector &layers = print.objects().front()->layers(); + ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); THEN("The output vector has 10 entries") { REQUIRE(layers.size() == 10); } @@ -37,7 +37,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 10 }, { "nozzle_diameter", 11 } }); - const std::vector &layers = print.objects().front()->layers(); + ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); THEN("The output vector has 3 entries") { REQUIRE(layers.size() == 3); } @@ -55,7 +55,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { { "layer_height", 15 }, { "nozzle_diameter", 16 } }); - const std::vector &layers = print.objects().front()->layers(); + ConstLayerPtrsAdaptor layers = print.objects().front()->layers(); THEN("The output vector has 2 entries") { REQUIRE(layers.size() == 2); } diff --git a/tests/fff_print/test_support_material.cpp b/tests/fff_print/test_support_material.cpp index 01d8581323..1b85532d31 100644 --- a/tests/fff_print/test_support_material.cpp +++ b/tests/fff_print/test_support_material.cpp @@ -27,7 +27,7 @@ SCENARIO("SupportMaterial: support_layers_z and contact_distance", "[SupportMate auto check = [](Slic3r::Print &print, bool &first_support_layer_height_ok, bool &layer_height_minimum_ok, bool &layer_height_maximum_ok, bool &top_spacing_ok) { - const std::vector &support_layers = print.objects().front()->support_layers(); + ConstSupportLayerPtrsAdaptor support_layers = print.objects().front()->support_layers(); first_support_layer_height_ok = support_layers.front()->print_z == print.default_object_config().first_layer_height.value; diff --git a/tests/libslic3r/test_voronoi.cpp b/tests/libslic3r/test_voronoi.cpp index 3e0759d0c9..3921030565 100644 --- a/tests/libslic3r/test_voronoi.cpp +++ b/tests/libslic3r/test_voronoi.cpp @@ -176,13 +176,13 @@ TEST_CASE("Voronoi missing edges - Alessandro gapfill 12707", "[Voronoi]") std::mt19937 gen; std::uniform_int_distribution dist(-100, 100); - for (Point &p : poly.points) { #if 0 + for (Point &p : poly.points) { // Wiggle the points a bit to find out whether this fixes the voronoi diagram for this particular polygon. p.x() = (p.x() += dist(gen)); p.y() = (p.y() += dist(gen)); -#endif } +#endif REQUIRE(intersecting_edges({ poly }).empty()); @@ -267,7 +267,7 @@ TEST_CASE("Voronoi weirdness", "[Voronoi]") }; // coord_t shift = 35058881; - coord_t shift_ok = 17000000; +// coord_t shift_ok = 17000000; coord_t shift = 35058881; Polygon poly { // <-4, 0>: bug diff --git a/tests/sla_print/sla_supptgen_tests.cpp b/tests/sla_print/sla_supptgen_tests.cpp index ee9013a44c..e160504de8 100644 --- a/tests/sla_print/sla_supptgen_tests.cpp +++ b/tests/sla_print/sla_supptgen_tests.cpp @@ -12,7 +12,7 @@ TEST_CASE("Overhanging point should be supported", "[SupGen]") { // Pyramid with 45 deg slope TriangleMesh mesh = make_pyramid(10.f, 10.f); - mesh.rotate_y(PI); + mesh.rotate_y(float(PI)); mesh.require_shared_vertices(); mesh.WriteOBJFile("Pyramid.obj"); @@ -81,7 +81,7 @@ TEST_CASE("Overhanging edge should be supported", "[SupGen]") { float width = 10.f, depth = 10.f, height = 5.f; TriangleMesh mesh = make_prism(width, depth, height); - mesh.rotate_y(PI); // rotate on its back + mesh.rotate_y(float(PI)); // rotate on its back mesh.translate(0., 0., height); mesh.require_shared_vertices(); mesh.WriteOBJFile("Prism.obj"); diff --git a/xs/t/04_expolygon.t b/xs/t/04_expolygon.t index 39da22f0a9..65e274ab9a 100644 --- a/xs/t/04_expolygon.t +++ b/xs/t/04_expolygon.t @@ -5,7 +5,7 @@ use warnings; use List::Util qw(first sum); use Slic3r::XS; -use Test::More tests => 31; +use Test::More tests => 21; use constant PI => 4 * atan2(1, 1); @@ -105,32 +105,4 @@ is $expolygon->area, 100*100-20*20, 'area'; is_deeply $collection->[0]->clone->pp, $collection->[0]->pp, 'clone collection item'; } -{ - my $expolygon = Slic3r::ExPolygon->new($square); - my $polygons = $expolygon->get_trapezoids2(PI/2); - is scalar(@$polygons), 1, 'correct number of trapezoids returned'; - is scalar(@{$polygons->[0]}), 4, 'trapezoid has 4 points'; - is $polygons->[0]->area, $expolygon->area, 'trapezoid has correct area'; -} - -{ - my $polygons = $expolygon->get_trapezoids2(PI/2); - is scalar(@$polygons), 4, 'correct number of trapezoids returned'; - - # trapezoid polygons might have more than 4 points in case of collinear segments - $polygons = [ map @{$_->simplify(1)}, @$polygons ]; - ok !defined(first { @$_ != 4 } @$polygons), 'all trapezoids have 4 points'; - - is scalar(grep { $_->area == 40*100 } @$polygons), 2, 'trapezoids have expected area'; - is scalar(grep { $_->area == 20*40 } @$polygons), 2, 'trapezoids have expected area'; -} - -{ - my $expolygon = Slic3r::ExPolygon->new([ [0,100],[100,0],[200,0],[300,100],[200,200],[100,200] ]); - my $polygons = $expolygon->get_trapezoids2(PI/2); - is scalar(@$polygons), 3, 'correct number of trapezoids returned'; - is scalar(grep { $_->area == 100*200/2 } @$polygons), 2, 'trapezoids have expected area'; - is scalar(grep { $_->area == 100*200 } @$polygons), 1, 'trapezoids have expected area'; -} - __END__ diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index bb138732fb..a57bcfbcb8 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -31,10 +31,6 @@ Polygons simplify_p(double tolerance); Polylines medial_axis(double max_width, double min_width) %code{% THIS->medial_axis(max_width, min_width, &RETVAL); %}; - Polygons get_trapezoids2(double angle) - %code{% THIS->get_trapezoids2(&RETVAL, angle); %}; - Polygons triangulate() - %code{% THIS->triangulate(&RETVAL); %}; %{ ExPolygon* diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp index 4545984bbb..78a5dde376 100644 --- a/xs/xsp/GCode.xsp +++ b/xs/xsp/GCode.xsp @@ -11,7 +11,9 @@ %code{% RETVAL = new CoolingBuffer(*gcode); %}; ~CoolingBuffer(); Ref gcodegen(); - std::string process_layer(std::string gcode, size_t layer_id); + std::string process_layer(std::string gcode, size_t layer_id) + %code{% RETVAL = THIS->process_layer(std::move(gcode), layer_id, true); %}; + }; %name{Slic3r::GCode} class GCode { diff --git a/xs/xsp/Layer.xsp b/xs/xsp/Layer.xsp index fdcc26eb62..5d006e676f 100644 --- a/xs/xsp/Layer.xsp +++ b/xs/xsp/Layer.xsp @@ -18,8 +18,6 @@ %code%{ RETVAL = &THIS->thin_fills; %}; Ref fill_surfaces() %code%{ RETVAL = &THIS->fill_surfaces; %}; - Polygons bridged() - %code%{ RETVAL = THIS->bridged; %}; Ref perimeters() %code%{ RETVAL = &THIS->perimeters; %}; Ref fills() diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index d9872aa7e3..cc3dac2247 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -95,16 +95,16 @@ _constant() int wipe_tower_number_of_toolchanges() %code%{ RETVAL = THIS->wipe_tower_data().number_of_toolchanges; %}; PrintObjectPtrs* objects() - %code%{ RETVAL = const_cast(&THIS->objects()); %}; + %code%{ RETVAL = const_cast(&THIS->objects_mutable()); %}; Ref get_object(int idx) - %code%{ RETVAL = THIS->objects()[idx]; %}; + %code%{ RETVAL = THIS->objects_mutable()[idx]; %}; size_t object_count() %code%{ RETVAL = THIS->objects().size(); %}; PrintRegionPtrs* regions() - %code%{ RETVAL = const_cast(&THIS->regions()); %}; + %code%{ RETVAL = const_cast(&THIS->regions_mutable()); %}; Ref get_region(int idx) - %code%{ RETVAL = THIS->regions()[idx]; %}; + %code%{ RETVAL = THIS->regions_mutable()[idx]; %}; size_t region_count() %code%{ RETVAL = THIS->regions().size(); %};