diff --git a/.github/workflows/conan-package-create.yml b/.github/workflows/conan-package-create.yml
index 701a978cd8..e8329fa7b1 100644
--- a/.github/workflows/conan-package-create.yml
+++ b/.github/workflows/conan-package-create.yml
@@ -1,158 +1,153 @@
name: Create and Upload Conan package
on:
- workflow_call:
- inputs:
- project_name:
- required: true
- type: string
+ workflow_call:
+ inputs:
+ project_name:
+ required: true
+ type: string
- recipe_id_full:
- required: true
- type: string
+ recipe_id_full:
+ required: true
+ type: string
- build_id:
- required: true
- type: number
+ build_id:
+ required: true
+ type: number
- build_info:
- required: false
- default: true
- type: boolean
+ build_info:
+ required: false
+ default: true
+ type: boolean
- recipe_id_latest:
- required: false
- type: string
+ recipe_id_latest:
+ required: false
+ type: string
- runs_on:
- required: true
- type: string
+ runs_on:
+ required: true
+ type: string
- python_version:
- required: true
- type: string
+ python_version:
+ required: true
+ type: string
- conan_config_branch:
- required: false
- type: string
+ conan_config_branch:
+ required: false
+ type: string
- conan_logging_level:
- required: false
- type: string
+ conan_logging_level:
+ required: false
+ type: string
- conan_clean_local_cache:
- required: false
- type: boolean
- default: false
+ conan_clean_local_cache:
+ required: false
+ type: boolean
+ default: false
- conan_upload_community:
- required: false
- default: true
- type: boolean
+ conan_upload_community:
+ required: false
+ default: true
+ type: boolean
env:
- CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD: ${{ secrets.CONAN_PASS }}
- CONAN_LOG_RUN_TO_OUTPUT: 1
- CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
- CONAN_NON_INTERACTIVE: 1
+ CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD: ${{ secrets.CONAN_PASS }}
+ CONAN_LOG_RUN_TO_OUTPUT: 1
+ CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
+ CONAN_NON_INTERACTIVE: 1
jobs:
- conan-package-create:
- runs-on: ${{ inputs.runs_on }}
+ conan-package-create:
+ runs-on: ${{ inputs.runs_on }}
- steps:
- - name: Checkout
- uses: actions/checkout@v3
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
- - name: Setup Python and pip
- uses: actions/setup-python@v4
- with:
- python-version: ${{ inputs.python_version }}
- cache: 'pip'
- cache-dependency-path: .github/workflows/requirements-conan-package.txt
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ inputs.python_version }}
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
- - name: Install Python requirements for runner
- run: pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt
- # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo
+ - name: Install Python requirements for runner
+ run: pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt
+ # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo
- - name: Use Conan download cache (Bash)
- if: ${{ runner.os != 'Windows' }}
- run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
+ - name: Use Conan download cache (Bash)
+ if: ${{ runner.os != 'Windows' }}
+ run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
- - name: Use Conan download cache (Powershell)
- if: ${{ runner.os == 'Windows' }}
- run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache"
+ - name: Use Conan download cache (Powershell)
+ if: ${{ runner.os == 'Windows' }}
+ run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache"
- - name: Cache Conan local repository packages (Bash)
- uses: actions/cache@v3
- if: ${{ runner.os != 'Windows' }}
- with:
- path: |
- $HOME/.conan/data
- $HOME/.conan/conan_download_cache
- key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache
+ - name: Cache Conan local repository packages (Bash)
+ uses: actions/cache@v3
+ if: ${{ runner.os != 'Windows' }}
+ with:
+ path: |
+ $HOME/.conan/data
+ $HOME/.conan/conan_download_cache
+ key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache
- - name: Cache Conan local repository packages (Powershell)
- uses: actions/cache@v3
- if: ${{ runner.os == 'Windows' }}
- with:
- path: |
- C:\Users\runneradmin\.conan\data
- C:\.conan
- C:\Users\runneradmin\.conan\conan_download_cache
- key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache
+ - name: Cache Conan local repository packages (Powershell)
+ uses: actions/cache@v3
+ if: ${{ runner.os == 'Windows' }}
+ with:
+ path: |
+ C:\Users\runneradmin\.conan\data
+ C:\.conan
+ C:\Users\runneradmin\.conan\conan_download_cache
+ key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache
- - name: Install MacOS system requirements
- if: ${{ runner.os == 'Macos' }}
- run: brew install autoconf automake ninja
+ - name: Install MacOS system requirements
+ if: ${{ runner.os == 'Macos' }}
+ run: brew install autoconf automake ninja
- # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
- # This is maybe because grub caches the disk it uses last time, which is recreated each time.
- - name: Install Linux system requirements
- if: ${{ runner.os == 'Linux' }}
- run: |
- sudo rm /var/cache/debconf/config.dat
- sudo dpkg --configure -a
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt update
- sudo apt upgrade
- sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison -y
+ # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
+ # This is maybe because grub caches the disk it uses last time, which is recreated each time.
+ - name: Install Linux system requirements
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ sudo rm /var/cache/debconf/config.dat
+ sudo dpkg --configure -a
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ sudo apt update
+ sudo apt upgrade
+ sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison -y
- - name: Install GCC-12 on ubuntu-22.04
- if: ${{ startsWith(inputs.runs_on, 'ubuntu-22.04') }}
- run: |
- sudo apt install g++-12 gcc-12 -y
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12
+ - name: Install GCC-132 on ubuntu
+ if: ${{ startsWith(inputs.runs_on, 'ubuntu') }}
+ run: |
+ sudo apt install g++-13 gcc-13 -y
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
- - name: Use GCC-10 on ubuntu-20.04
- if: ${{ startsWith(inputs.runs_on, 'ubuntu-20.04') }}
- run: |
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
+ - name: Create the default Conan profile
+ run: conan profile new default --detect
- - name: Create the default Conan profile
- run: conan profile new default --detect
+ - name: Get Conan configuration from branch
+ if: ${{ inputs.conan_config_branch != '' }}
+ run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}"
- - name: Get Conan configuration from branch
- if: ${{ inputs.conan_config_branch != '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}"
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
- - name: Get Conan configuration
- if: ${{ inputs.conan_config_branch == '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git
+ - name: Add Cura private Artifactory remote
+ run: conan remote add cura-private https://ultimaker.jfrog.io/artifactory/api/conan/cura-private True
- - name: Add Cura private Artifactory remote
- run: conan remote add cura-private https://ultimaker.jfrog.io/artifactory/api/conan/cura-private True
+ - name: Create the Packages
+ run: conan install ${{ inputs.recipe_id_full }} --build=missing --update -c tools.build:skip_test=True
- - name: Create the Packages
- run: conan install ${{ inputs.recipe_id_full }} --build=missing --update
+ - name: Upload the Package(s)
+ if: ${{ always() && inputs.conan_upload_community }}
+ run: conan upload ${{ inputs.recipe_id_full }} -r cura --all -c
- - name: Upload the Package(s)
- if: ${{ always() && inputs.conan_upload_community }}
- run: conan upload ${{ inputs.recipe_id_full }} -r cura --all -c
-
- - name: Upload the Package(s) to the private Artifactory
- if: ${{ always() && ! inputs.conan_upload_community }}
- run: conan upload ${{ inputs.recipe_id_full }} -r cura-private --all -c
+ - name: Upload the Package(s) to the private Artifactory
+ if: ${{ always() && ! inputs.conan_upload_community }}
+ run: conan upload ${{ inputs.recipe_id_full }} -r cura-private --all -c
diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml
index 9949621251..34652de39b 100644
--- a/.github/workflows/conan-package.yml
+++ b/.github/workflows/conan-package.yml
@@ -49,15 +49,15 @@ on:
- '[1-9].[0-9][0-9].[0-9]*'
env:
- CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
- CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }}
- CONAN_LOG_RUN_TO_OUTPUT: 1
- CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
- CONAN_NON_INTERACTIVE: 1
+ CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
+ CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }}
+ CONAN_LOG_RUN_TO_OUTPUT: 1
+ CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
+ CONAN_NON_INTERACTIVE: 1
-permissions: {}
+permissions: { }
jobs:
conan-recipe-version:
permissions:
@@ -103,18 +103,23 @@ jobs:
sudo apt update
sudo apt upgrade
sudo apt install efibootmgr build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison g++-12 gcc-12 -y
- sudo apt install g++-12 gcc-12 -y
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12
+
+ - name: Install GCC-13
+ run: |
+ sudo apt install g++-13 gcc-13 -y
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
- name: Create the default Conan profile
run: conan profile new default --detect --force
- name: Get Conan configuration
- run: conan config install https://github.com/Ultimaker/conan-config.git
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
- name: Create the Packages
- run: conan create . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o ${{ needs.conan-recipe-version.outputs.project_name }}:devtools=True
+ run: conan create . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o ${{ needs.conan-recipe-version.outputs.project_name }}:devtools=True -c tools.build:skip_test=True
- name: Create the latest alias
if: always()
diff --git a/.github/workflows/conan-recipe-export.yml b/.github/workflows/conan-recipe-export.yml
index 869a9de59e..ba5aaa49a1 100644
--- a/.github/workflows/conan-recipe-export.yml
+++ b/.github/workflows/conan-recipe-export.yml
@@ -1,106 +1,107 @@
name: Export Conan Recipe to server
on:
- workflow_call:
- inputs:
- recipe_id_full:
- required: true
- type: string
+ workflow_call:
+ inputs:
+ recipe_id_full:
+ required: true
+ type: string
- recipe_id_latest:
- required: false
- type: string
+ recipe_id_latest:
+ required: false
+ type: string
- runs_on:
- required: true
- type: string
+ runs_on:
+ required: true
+ type: string
- python_version:
- required: true
- type: string
+ python_version:
+ required: true
+ type: string
- conan_config_branch:
- required: false
- type: string
+ conan_config_branch:
+ required: false
+ type: string
- conan_logging_level:
- required: false
- type: string
+ conan_logging_level:
+ required: false
+ type: string
- conan_export_binaries:
- required: false
- type: boolean
+ conan_export_binaries:
+ required: false
+ type: boolean
- conan_upload_community:
- required: false
- default: true
- type: boolean
+ conan_upload_community:
+ required: false
+ default: true
+ type: boolean
env:
- CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD: ${{ secrets.CONAN_PASS }}
- CONAN_LOG_RUN_TO_OUTPUT: 1
- CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
- CONAN_NON_INTERACTIVE: 1
+ CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD: ${{ secrets.CONAN_PASS }}
+ CONAN_LOG_RUN_TO_OUTPUT: 1
+ CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
+ CONAN_NON_INTERACTIVE: 1
jobs:
- package-export:
- runs-on: ${{ inputs.runs_on }}
+ package-export:
+ runs-on: ${{ inputs.runs_on }}
- steps:
- - name: Checkout project
- uses: actions/checkout@v3
+ steps:
+ - name: Checkout project
+ uses: actions/checkout@v3
- - name: Setup Python and pip
- uses: actions/setup-python@v4
- with:
- python-version: ${{ inputs.python_version }}
- cache: 'pip'
- cache-dependency-path: .github/workflows/requirements-conan-package.txt
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ inputs.python_version }}
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
- - name: Install Python requirements and Create default Conan profile
- run: |
- pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt
- conan profile new default --detect
- # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo
+ - name: Install Python requirements and Create default Conan profile
+ run: |
+ pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt
+ conan profile new default --detect
+ # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo
- - name: Cache Conan local repository packages
- uses: actions/cache@v3
- with:
- path: $HOME/.conan/data
- key: ${{ runner.os }}-conan-export-cache
+ - name: Cache Conan local repository packages
+ uses: actions/cache@v3
+ with:
+ path: $HOME/.conan/data
+ key: ${{ runner.os }}-conan-export-cache
- - name: Get Conan configuration from branch
- if: ${{ inputs.conan_config_branch != '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}"
+ - name: Get Conan configuration from branch
+ if: ${{ inputs.conan_config_branch != '' }}
+ run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}"
- - name: Get Conan configuration
- if: ${{ inputs.conan_config_branch == '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
- - name: Add Cura private Artifactory remote
- run: conan remote add cura-private https://ultimaker.jfrog.io/artifactory/api/conan/cura-private True
+ - name: Add Cura private Artifactory remote
+ run: conan remote add cura-private https://ultimaker.jfrog.io/artifactory/api/conan/cura-private True
- - name: Export the Package (binaries)
- if: ${{ inputs.conan_export_binaries }}
- run: conan create . ${{ inputs.recipe_id_full }} --build=missing --update
+ - name: Export the Package (binaries)
+ if: ${{ inputs.conan_export_binaries }}
+ run: conan create . ${{ inputs.recipe_id_full }} --build=missing --update -c tools.build:skip_test=True
- - name: Export the Package
- if: ${{ !inputs.conan_export_binaries }}
- run: conan export . ${{ inputs.recipe_id_full }}
+ - name: Export the Package
+ if: ${{ !inputs.conan_export_binaries }}
+ run: conan export . ${{ inputs.recipe_id_full }}
- - name: Create the latest alias
- if: always()
- run: conan alias ${{ inputs.recipe_id_latest }} ${{ inputs.recipe_id_full }}
+ - name: Create the latest alias
+ if: always()
+ run: conan alias ${{ inputs.recipe_id_latest }} ${{ inputs.recipe_id_full }}
- - name: Upload the Package(s)
- if: ${{ always() && inputs.conan_upload_community }}
- run: |
- conan upload ${{ inputs.recipe_id_full }} -r cura --all -c
- conan upload ${{ inputs.recipe_id_latest }} -r cura -c
+ - name: Upload the Package(s)
+ if: ${{ always() && inputs.conan_upload_community }}
+ run: |
+ conan upload ${{ inputs.recipe_id_full }} -r cura --all -c
+ conan upload ${{ inputs.recipe_id_latest }} -r cura -c
- - name: Upload the Package(s) to the private Artifactory
- if: ${{ always() && ! inputs.conan_upload_community }}
- run: |
- conan upload ${{ inputs.recipe_id_full }} -r cura-private --all -c
- conan upload ${{ inputs.recipe_id_latest }} -r cura-private -c
+ - name: Upload the Package(s) to the private Artifactory
+ if: ${{ always() && ! inputs.conan_upload_community }}
+ run: |
+ conan upload ${{ inputs.recipe_id_full }} -r cura-private --all -c
+ conan upload ${{ inputs.recipe_id_latest }} -r cura-private -c
diff --git a/.github/workflows/cura-all-installers.yml b/.github/workflows/cura-all-installers.yml
deleted file mode 100644
index 4729c4198a..0000000000
--- a/.github/workflows/cura-all-installers.yml
+++ /dev/null
@@ -1,151 +0,0 @@
-name: Cura All Installers
-run-name: ${{ inputs.cura_conan_version }} for exe ${{ inputs.build_windows_exe }}, msi ${{ inputs.build_windows_msi }}, dmg ${{ inputs.build_macos }}, pkg ${{ inputs.build_macos_installer }}, appimage ${{ inputs.build_linux }} - enterprise ${{ inputs.enterprise }}
-
-on:
- workflow_dispatch:
- inputs:
- cura_conan_version:
- description: 'Cura Conan Version'
- default: 'cura/latest@ultimaker/testing'
- required: true
- type: string
- conan_args:
- description: 'Conan args: eq.: --require-override'
- default: ''
- required: false
- type: string
- conan_config:
- description: 'Conan config branch to use'
- default: ''
- required: false
- type: string
- enterprise:
- description: 'Build Cura as an Enterprise edition'
- default: false
- required: true
- type: boolean
- staging:
- description: 'Use staging API'
- default: false
- required: true
- type: boolean
- installer:
- description: 'Create the installer'
- default: true
- required: true
- type: boolean
- build_windows_exe:
- description: 'Build for Windows exe'
- default: false
- required: true
- type: boolean
- build_windows_msi:
- description: 'Build for msi+pkg'
- default: true
- required: true
- type: boolean
- build_linux:
- description: 'Build for Linux'
- default: true
- required: true
- type: boolean
- build_macos:
- description: 'Build dmg for MacOS'
- default: true
- required: true
- type: boolean
-
- # Run the nightly at 3:25 UTC on working days
- schedule:
- - cron: '25 3 * * 1-5'
-
-jobs:
- windows-installer-create-exe:
- if: ${{ inputs.build_windows_exe }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'windows-2022'
- os_name: 'win64'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: false
- secrets: inherit
-
- windows-installer-create-msi:
- if: ${{ inputs.build_windows_msi }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'windows-2022'
- os_name: 'win64'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: true
- secrets: inherit
-
- linux-installer-create:
- if: ${{ inputs.build_linux }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'ubuntu-20.04'
- os_name: 'linux'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: false
- secrets: inherit
-
- linux-modern-installer-create:
- if: ${{ inputs.build_linux }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'ubuntu-22.04'
- os_name: 'linux-modern'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: false
- secrets: inherit
-
- macos-dmg-create:
- if: ${{ inputs.build_macos }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'macos-11'
- os_name: 'mac'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: false
- secrets: inherit
-
- macos-installer-create:
- if: ${{ inputs.build_macos }}
- uses: ./.github/workflows/cura-installer.yml
- with:
- platform: 'macos-11'
- os_name: 'mac'
- cura_conan_version: ${{ inputs.cura_conan_version }}
- conan_args: ${{ inputs.conan_args }}
- conan_config: ${{ inputs.conan_config }}
- enterprise: ${{ inputs.enterprise }}
- staging: ${{ inputs.staging }}
- installer: ${{ inputs.installer }}
- msi_installer: true
- secrets: inherit
diff --git a/.github/workflows/cura-installer.yml b/.github/workflows/cura-installer.yml
deleted file mode 100644
index 9572b31aee..0000000000
--- a/.github/workflows/cura-installer.yml
+++ /dev/null
@@ -1,390 +0,0 @@
-name: Cura Installer
-run-name: ${{ inputs.cura_conan_version }} for ${{ inputs.platform }} by @${{ github.actor }}
-
-on:
- workflow_call:
- inputs:
- platform:
- description: 'Selected Installer OS'
- default: 'ubuntu-20.04'
- required: true
- type: string
- os_name:
- description: 'OS Friendly Name'
- default: 'linux'
- required: true
- type: string
- cura_conan_version:
- description: 'Cura Conan Version'
- default: 'cura/latest@ultimaker/testing'
- required: true
- type: string
- conan_args:
- description: 'Conan args: eq.: --require-override'
- default: ''
- required: false
- type: string
- conan_config:
- description: 'Conan config branch to use'
- default: ''
- required: false
- type: string
- enterprise:
- description: 'Build Cura as an Enterprise edition'
- default: false
- required: true
- type: boolean
- staging:
- description: 'Use staging API'
- default: false
- required: true
- type: boolean
- installer:
- description: 'Create the installer'
- default: true
- required: true
- type: boolean
- msi_installer:
- description: 'Create the msi'
- default: false
- required: true
- type: boolean
-
-env:
- CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
- CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }}
- CONAN_LOG_RUN_TO_OUTPUT: 1
- CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }}
- CONAN_NON_INTERACTIVE: 1
- CODESIGN_IDENTITY: ${{ secrets.CODESIGN_IDENTITY }}
- MAC_NOTARIZE_USER: ${{ secrets.MAC_NOTARIZE_USER }}
- MAC_NOTARIZE_PASS: ${{ secrets.MAC_NOTARIZE_PASS }}
- MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }}
- MACOS_CERT_INSTALLER_P12: ${{ secrets.MACOS_CERT_INSTALLER_P12 }}
- MACOS_CERT_USER: ${{ secrets.MACOS_CERT_USER }}
- GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
- MACOS_CERT_PASSPHRASE: ${{ secrets.MACOS_CERT_PASSPHRASE }}
- WIN_CERT_INSTALLER_CER: ${{ secrets.WIN_CERT_INSTALLER_CER }}
- WIN_CERT_INSTALLER_CER_PASS: ${{ secrets.WIN_CERT_INSTALLER_CER_PASS }}
- CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }}
- ENTERPRISE: ${{ inputs.enterprise }}
- STAGING: ${{ inputs.staging }}
-
-jobs:
- cura-installer-create:
- runs-on: ${{ inputs.platform }}
-
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - name: Setup Python and pip
- uses: actions/setup-python@v4
- with:
- python-version: '3.10.x'
- cache: 'pip'
- cache-dependency-path: .github/workflows/requirements-conan-package.txt
-
- - name: Install Python requirements for runner
- run: pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt
- # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo
-
- - name: Use Conan download cache (Bash)
- if: ${{ runner.os != 'Windows' }}
- run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
-
- - name: Use Conan download cache (Powershell)
- if: ${{ runner.os == 'Windows' }}
- run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache"
-
- - name: Cache Conan local repository packages (Bash)
- uses: actions/cache@v3
- if: ${{ runner.os != 'Windows' }}
- with:
- path: |
- $HOME/.conan/data
- $HOME/.conan/conan_download_cache
- key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache
-
- - name: Cache Conan local repository packages (Powershell)
- uses: actions/cache@v3
- if: ${{ runner.os == 'Windows' }}
- with:
- path: |
- C:\Users\runneradmin\.conan\data
- C:\.conan
- C:\Users\runneradmin\.conan\conan_download_cache
- key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache
-
- - name: Install MacOS system requirements
- if: ${{ runner.os == 'Macos' }}
- run: brew install autoconf automake ninja create-dmg # Delete create-dmg when deprecating dmg
-
- - name: Hack needed specifically for ubuntu-22.04 from mid-Feb 2023 onwards
- if: ${{ runner.os == 'Linux' && startsWith(inputs.platform, 'ubuntu-22.04') }}
- run: sudo apt remove libodbc2 libodbcinst2 unixodbc-common -y
-
- # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
- # This is maybe because grub caches the disk it uses last time, which is recreated each time.
- - name: Install Linux system requirements
- if: ${{ runner.os == 'Linux' }}
- run: |
- sudo rm /var/cache/debconf/config.dat
- sudo dpkg --configure -a
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt update
- sudo apt upgrade
- sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y
- wget --no-check-certificate --quiet https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O $GITHUB_WORKSPACE/appimagetool
- chmod +x $GITHUB_WORKSPACE/appimagetool
- echo "APPIMAGETOOL_LOCATION=$GITHUB_WORKSPACE/appimagetool" >> $GITHUB_ENV
-
- - name: Install GCC-12 on ubuntu-22.04
- if: ${{ startsWith(inputs.platform, 'ubuntu-22.04') }}
- run: |
- sudo apt install g++-12 gcc-12 -y
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12
-
- - name: Use GCC-10 on ubuntu-20.04
- if: ${{ startsWith(inputs.platform, 'ubuntu-20.04') }}
- run: |
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
-
- - name: Create the default Conan profile
- run: conan profile new default --detect
-
- - name: Configure GPG Key Linux (Bash)
- if: ${{ runner.os == 'Linux' }}
- run: echo -n "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import
-
- - name: Configure Macos keychain Developer Cert(Bash)
- id: macos-keychain-developer-cert
- if: ${{ runner.os == 'Macos' }}
- uses: apple-actions/import-codesign-certs@v1
- with:
- keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
- p12-file-base64: ${{ secrets.MACOS_CERT_P12 }}
- p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }}
-
- - name: Configure Macos keychain Installer Cert (Bash)
- id: macos-keychain-installer-cert
- if: ${{ runner.os == 'Macos' }}
- uses: apple-actions/import-codesign-certs@v1
- with:
- keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
- create-keychain: false # keychain is created in previous use of action.
- p12-file-base64: ${{ secrets.MACOS_CERT_INSTALLER_P12 }}
- p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }}
-
- - name: Create PFX certificate from BASE64_PFX_CONTENT secret
- if: ${{ runner.os == 'Windows' }}
- id: create-pfx
- env:
- PFX_CONTENT: ${{ secrets.WIN_CERT_INSTALLER_CER }}
- run: |
- $pfxPath = Join-Path -Path $env:RUNNER_TEMP -ChildPath "cert.pfx";
- $encodedBytes = [System.Convert]::FromBase64String($env:PFX_CONTENT);
- Set-Content $pfxPath -Value $encodedBytes -AsByteStream;
- echo "PFX_PATH=$pfxPath" >> $env:GITHUB_OUTPUT;
-
- - name: Get Conan configuration from branch
- if: ${{ inputs.conan_config != '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config }}"
-
- - name: Get Conan configuration
- if: ${{ inputs.conan_config == '' }}
- run: conan config install https://github.com/Ultimaker/conan-config.git
-
- - name: Create the Packages (Bash)
- if: ${{ runner.os != 'Windows' }}
- run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING --json "cura_inst/conan_install_info.json"
-
- - name: Create the Packages (Powershell)
- if: ${{ runner.os == 'Windows' }}
- run: conan install $Env:CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$Env:ENTERPRISE -o cura:staging=$Env:STAGING --json "cura_inst/conan_install_info.json"
-
- - name: Set Environment variables for Cura (bash)
- if: ${{ runner.os != 'Windows' }}
- run: |
- . ./cura_inst/bin/activate_github_actions_env.sh
- . ./cura_inst/bin/activate_github_actions_version_env.sh
-
- - name: Set Environment variables for Cura (Powershell)
- if: ${{ runner.os == 'Windows' }}
- run: |
- echo "${Env:WIX}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- .\cura_inst\Scripts\activate_github_actions_env.ps1
- .\cura_inst\Scripts\activate_github_actions_version_env.ps1
-
- - name: Unlock Macos keychain (Bash)
- if: ${{ runner.os == 'Macos' }}
- run: security unlock -p $TEMP_KEYCHAIN_PASSWORD signing_temp.keychain
- env:
- TEMP_KEYCHAIN_PASSWORD: ${{ steps.macos-keychain-developer-cert.outputs.keychain-password }}
-
- # FIXME: This is a workaround to ensure that we use and pack a shared library for OpenSSL 1.1.1l. We currently compile
- # OpenSSL statically for CPython, but our Python Dependenies (such as PyQt6) require a shared library.
- # Because Conan won't allow for building the same library with two different options (easily) we need to install it explicitly
- # and do a manual copy to the VirtualEnv, such that Pyinstaller can find it.
-
- - name: Install OpenSSL shared
- run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy
-
- - name: Copy OpenSSL shared (Bash)
- if: ${{ runner.os != 'Windows' }}
- run: |
- cp ./openssl/lib/*.so* ./cura_inst/bin/ || true
- cp ./openssl/lib/*.dylib* ./cura_inst/bin/ || true
-
- - name: Copy OpenSSL shared (Powershell)
- if: ${{ runner.os == 'Windows' }}
- run: |
- cp openssl/bin/*.dll ./cura_inst/Scripts/
- cp openssl/lib/*.lib ./cura_inst/Lib/
-
- - name: Create the Cura dist
- run: pyinstaller ./cura_inst/UltiMaker-Cura.spec
-
- - name: Output the name file name and extension
- id: filename
- shell: python
- run: |
- import os
- enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else ""
- installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-${{ inputs.os_name }}"
- if "${{ runner.os }}" == "Windows":
- installer_ext = "msi" if "${{ inputs.msi_installer }}" == "true" else "exe"
- elif "${{ runner.os }}" == "macOS":
- installer_ext = "pkg" if "${{ inputs.msi_installer }}" == "true" else "dmg"
- else:
- installer_ext = "AppImage"
- output_env = os.environ["GITHUB_OUTPUT"]
- content = ""
- if os.path.exists(output_env):
- with open(output_env, "r") as f:
- content = f.read()
- with open(output_env, "w") as f:
- f.write(content)
- f.writelines(f"INSTALLER_FILENAME={installer_filename}\n")
- f.writelines(f"INSTALLER_EXT={installer_ext}\n")
- f.writelines(f"FULL_INSTALLER_FILENAME={installer_filename}.{installer_ext}\n")
-
- - name: Summarize the used Conan dependencies
- shell: python
- run: |
- import os
- import json
- from pathlib import Path
-
- conan_install_info_path = Path("cura_inst/conan_install_info.json")
- conan_info = {"installed": []}
- if os.path.exists(conan_install_info_path):
- with open(conan_install_info_path, "r") as f:
- conan_info = json.load(f)
- sorted_deps = sorted([dep["recipe"]["id"].replace('#', r' rev: ') for dep in conan_info["installed"]])
-
- summary_env = os.environ["GITHUB_STEP_SUMMARY"]
- content = ""
- if os.path.exists(summary_env):
- with open(summary_env, "r") as f:
- content = f.read()
-
- with open(summary_env, "w") as f:
- f.write(content)
- f.writelines("# ${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}\n")
- f.writelines("## Conan packages:\n")
- for dep in sorted_deps:
- f.writelines(f"`{dep}`\n")
-
- - name: Summarize the used Python modules
- shell: python
- run: |
- import os
- import pkg_resources
- summary_env = os.environ["GITHUB_STEP_SUMMARY"]
- content = ""
- if os.path.exists(summary_env):
- with open(summary_env, "r") as f:
- content = f.read()
-
- with open(summary_env, "w") as f:
- f.write(content)
- f.writelines("## Python modules:\n")
- for package in pkg_resources.working_set:
- f.writelines(f"`{package.key}/{package.version}`\n")
-
- - name: Archive the artifacts (bash)
- if: ${{ !inputs.installer && runner.os != 'Windows' }}
- run: tar -zcf "./${{ steps.filename.outputs.INSTALLER_FILENAME }}.tar.gz" "./UltiMaker-Cura/"
- working-directory: dist
-
- - name: Archive the artifacts (Powershell)
- if: ${{ !inputs.installer && runner.os == 'Windows' }}
- run: Compress-Archive -Path ".\UltiMaker-Cura" -DestinationPath ".\${{ steps.filename.outputs.INSTALLER_FILENAME }}.zip"
- working-directory: dist
-
- - name: Create the Windows exe installer (Powershell)
- if: ${{ inputs.installer && runner.os == 'Windows' && !inputs.msi_installer }}
- run: |
- python ..\cura_inst\packaging\NSIS\create_windows_installer.py ../cura_inst . "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}"
- working-directory: dist
-
- - name: Create the Windows msi installer (Powershell)
- if: ${{ inputs.installer && runner.os == 'Windows' && inputs.msi_installer }}
- run: |
- python ..\cura_inst\packaging\msi\create_windows_msi.py ..\cura_inst .\UltiMaker-Cura "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}" "$Env:CURA_APP_NAME"
- working-directory: dist
-
- - name: Sign the Windows exe installer (Powershell)
- if: ${{ inputs.installer && runner.os == 'Windows' && !inputs.msi_installer }}
- env:
- PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }}
- run: |
- & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}"
- working-directory: dist
-
- - name: Sign the Windows msi installer (Powershell)
- if: ${{ inputs.installer && runner.os == 'Windows' && inputs.msi_installer }}
- env:
- PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }}
- run: |
- & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}"
- working-directory: dist
-
- - name: Create the Linux AppImage (Bash)
- if: ${{ inputs.installer && runner.os == 'Linux' }}
- run: python ../cura_inst/packaging/AppImage/create_appimage.py ./UltiMaker-Cura $CURA_VERSION_FULL "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}"
- working-directory: dist
-
- - name: Create the MacOS dmg and/or pkg (Bash)
- if: ${{ github.event.inputs.installer == 'true' && runner.os == 'Macos' }}
- run: python ../cura_inst/packaging/MacOS/build_macos.py ../cura_inst . $CURA_CONAN_VERSION "${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}" "$CURA_APP_NAME"
- working-directory: dist
-
- - name: Upload the artifacts
- uses: actions/upload-artifact@v3
- with:
- name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-${{ steps.filename.outputs.INSTALLER_EXT }}
- path: |
- dist/*.tar.gz
- dist/*.zip
- dist/${{ steps.filename.outputs.FULL_INSTALLER_FILENAME }}
- dist/*.asc
- retention-days: 5
-
- notify-export:
- if: ${{ always() }}
- needs: [ cura-installer-create ]
-
- uses: ultimaker/cura/.github/workflows/notify.yml@main
- with:
- success: ${{ contains(join(needs.*.result, ','), 'success') }}
- success_title: "Create the Cura distributions"
- success_body: "Installers for ${{ inputs.cura_conan_version }}"
- failure_title: "Failed to create the Cura distributions"
- failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}"
- secrets: inherit
diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml
new file mode 100644
index 0000000000..ead3b7a87a
--- /dev/null
+++ b/.github/workflows/installers.yml
@@ -0,0 +1,82 @@
+name: All installers
+run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+
+jobs:
+ windows-installer:
+ uses: ./.github/workflows/windows.yml
+ with:
+ cura_conan_version: ${{ inputs.cura_conan_version }}
+ conan_args: ${{ inputs.conan_args }}
+ enterprise: ${{ inputs.enterprise }}
+ staging: ${{ inputs.staging }}
+ architecture: X64
+ operating_system: windows-2022
+ secrets: inherit
+
+ linux-modern-installer:
+ uses: ./.github/workflows/linux.yml
+ with:
+ cura_conan_version: ${{ inputs.cura_conan_version }}
+ conan_args: ${{ inputs.conan_args }}
+ enterprise: ${{ inputs.enterprise }}
+ staging: ${{ inputs.staging }}
+ architecture: X64
+ operating_system: ubuntu-22.04
+ secrets: inherit
+
+ linux-legacy-installer:
+ uses: ./.github/workflows/linux.yml
+ with:
+ cura_conan_version: ${{ inputs.cura_conan_version }}
+ conan_args: ${{ inputs.conan_args }}
+ enterprise: ${{ inputs.enterprise }}
+ staging: ${{ inputs.staging }}
+ architecture: X64
+ operating_system: ubuntu-20.04
+ secrets: inherit
+
+ macos-installer:
+ uses: ./.github/workflows/macos.yml
+ with:
+ cura_conan_version: ${{ inputs.cura_conan_version }}
+ conan_args: ${{ inputs.conan_args }}
+ enterprise: ${{ inputs.enterprise }}
+ staging: ${{ inputs.staging }}
+ architecture: X64
+ operating_system: macos-11.0
+ secrets: inherit
+
+ macos-arm-installer:
+ uses: ./.github/workflows/macos.yml
+ with:
+ cura_conan_version: ${{ inputs.cura_conan_version }}
+ conan_args: ${{ inputs.conan_args }}
+ enterprise: ${{ inputs.enterprise }}
+ staging: ${{ inputs.staging }}
+ architecture: ARM64
+ operating_system: self-hosted
+ secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
new file mode 100644
index 0000000000..2e15584299
--- /dev/null
+++ b/.github/workflows/linux.yml
@@ -0,0 +1,264 @@
+name: Linux Installer
+run-name: ${{ inputs.cura_conan_version }} for Linux-${{ inputs.architecture }} by @${{ github.actor }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: choice
+ options:
+ - X64
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'ubuntu-22.04'
+ type: choice
+ options:
+ - ubuntu-22.04
+ - ubuntu-20.04
+ workflow_call:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: string
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'ubuntu-22.04'
+ type: string
+
+env:
+ CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+ CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }}
+ ENTERPRISE: ${{ inputs.enterprise }}
+ STAGING: ${{ inputs.staging }}
+
+jobs:
+ cura-installer-create:
+ runs-on: ${{ inputs.operating_system }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10.x'
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
+
+ - name: Install Python requirements for runner
+ run: pip install -r .github/workflows/requirements-conan-package.txt
+
+ - name: Cache Conan local repository packages (Bash)
+ uses: actions/cache@v3
+ with:
+ path: |
+ $HOME/.conan/data
+ $HOME/.conan/conan_download_cache
+ key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache
+
+ - name: Hack needed specifically for ubuntu-22.04 from mid-Feb 2023 onwards
+ if: ${{ startsWith(inputs.operating_system, 'ubuntu-22.04') }}
+ run: sudo apt remove libodbc2 libodbcinst2 unixodbc-common -y
+
+ # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
+ # This is maybe because grub caches the disk it uses last time, which is recreated each time.
+ - name: Install Linux system requirements
+ run: |
+ sudo rm /var/cache/debconf/config.dat
+ sudo dpkg --configure -a
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ sudo apt update
+ sudo apt upgrade
+ sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y
+ wget --no-check-certificate --quiet https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O $GITHUB_WORKSPACE/appimagetool
+ chmod +x $GITHUB_WORKSPACE/appimagetool
+ echo "APPIMAGETOOL_LOCATION=$GITHUB_WORKSPACE/appimagetool" >> $GITHUB_ENV
+
+ - name: Install GCC-13
+ run: |
+ sudo apt install g++-13 gcc-13 -y
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
+
+ - name: Create the default Conan profile
+ run: conan profile new default --detect --force
+
+ - name: Configure GPG Key Linux (Bash)
+ run: echo -n "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import
+
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
+
+ - name: Use Conan download cache (Bash)
+ run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
+
+ - name: Create the Packages (Bash)
+ run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING --json "cura_inst/conan_install_info.json"
+
+ - name: Upload the Package(s)
+ if: always()
+ run: |
+ conan upload "*" -r cura --all -c
+
+ - name: Set Environment variables for Cura (bash)
+ run: |
+ . ./cura_inst/bin/activate_github_actions_env.sh
+ . ./cura_inst/bin/activate_github_actions_version_env.sh
+
+ # FIXME: This is a workaround to ensure that we use and pack a shared library for OpenSSL 1.1.1l. We currently compile
+ # OpenSSL statically for CPython, but our Python Dependenies (such as PyQt6) require a shared library.
+ # Because Conan won't allow for building the same library with two different options (easily) we need to install it explicitly
+ # and do a manual copy to the VirtualEnv, such that Pyinstaller can find it.
+
+ - name: Install OpenSSL shared
+ run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy
+
+ - name: Copy OpenSSL shared (Bash)
+ run: |
+ cp ./openssl/lib/*.so* ./cura_inst/bin/ || true
+ cp ./openssl/lib/*.dylib* ./cura_inst/bin/ || true
+
+ - name: Create the Cura dist
+ run: pyinstaller ./cura_inst/UltiMaker-Cura.spec
+
+ - name: Output the name file name and extension
+ id: filename
+ shell: python
+ run: |
+ import os
+ enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else ""
+ if "${{ inputs.operating_system }}" == "ubuntu-22.04":
+ installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-linux-modern-${{ inputs.architecture }}"
+ else:
+ installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-linux-${{ inputs.architecture }}"
+ output_env = os.environ["GITHUB_OUTPUT"]
+ content = ""
+ if os.path.exists(output_env):
+ with open(output_env, "r") as f:
+ content = f.read()
+ with open(output_env, "w") as f:
+ f.write(content)
+ f.writelines(f"INSTALLER_FILENAME={installer_filename}\n")
+
+ - name: Summarize the used Conan dependencies
+ shell: python
+ run: |
+ import os
+ import json
+ from pathlib import Path
+
+ conan_install_info_path = Path("cura_inst/conan_install_info.json")
+ conan_info = {"installed": []}
+ if os.path.exists(conan_install_info_path):
+ with open(conan_install_info_path, "r") as f:
+ conan_info = json.load(f)
+ sorted_deps = sorted([dep["recipe"]["id"].replace('#', r' rev: ') for dep in conan_info["installed"]])
+
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n")
+ f.writelines("## Conan packages:\n")
+ for dep in sorted_deps:
+ f.writelines(f"`{dep}`\n")
+
+ - name: Summarize the used Python modules
+ shell: python
+ run: |
+ import os
+ import pkg_resources
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("## Python modules:\n")
+ for package in pkg_resources.working_set:
+ f.writelines(f"`{package.key}/{package.version}`\n")
+
+ - name: Create the Linux AppImage (Bash)
+ run: |
+ python ../cura_inst/packaging/AppImage/create_appimage.py ./UltiMaker-Cura $CURA_VERSION_FULL "${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage"
+ chmod +x "${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage"
+ working-directory: dist
+
+ - name: Upload the AppImage
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-AppImage
+ path: |
+ dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage
+ retention-days: 5
+
+ notify-export:
+ if: ${{ always() }}
+ needs: [ cura-installer-create ]
+
+ uses: ultimaker/cura/.github/workflows/notify.yml@main
+ with:
+ success: ${{ contains(join(needs.*.result, ','), 'success') }}
+ success_title: "Create the Cura distributions"
+ success_body: "Installers for ${{ inputs.cura_conan_version }}"
+ failure_title: "Failed to create the Cura distributions"
+ failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}"
+ secrets: inherit
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
new file mode 100644
index 0000000000..af1fc3d12b
--- /dev/null
+++ b/.github/workflows/macos.yml
@@ -0,0 +1,279 @@
+name: Macos Installer
+run-name: ${{ inputs.cura_conan_version }} for Macos-${{ inputs.architecture }} by @${{ github.actor }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: choice
+ options:
+ - X64
+ - ARM64
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'macos-11'
+ type: choice
+ options:
+ - self-hosted
+ - macos-11
+ - macos-12
+ workflow_call:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: string
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'macos-11'
+ type: string
+
+env:
+ CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
+ CODESIGN_IDENTITY: ${{ secrets.CODESIGN_IDENTITY }}
+ MAC_NOTARIZE_USER: ${{ secrets.MAC_NOTARIZE_USER }}
+ MAC_NOTARIZE_PASS: ${{ secrets.MAC_NOTARIZE_PASS }}
+ MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }}
+ MACOS_CERT_INSTALLER_P12: ${{ secrets.MACOS_CERT_INSTALLER_P12 }}
+ MACOS_CERT_USER: ${{ secrets.MACOS_CERT_USER }}
+ MACOS_CERT_PASSPHRASE: ${{ secrets.MACOS_CERT_PASSPHRASE }}
+ CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }}
+ ENTERPRISE: ${{ inputs.enterprise }}
+ STAGING: ${{ inputs.staging }}
+
+jobs:
+ cura-installer-create:
+ runs-on: ${{ inputs.operating_system }}
+
+ outputs:
+ INSTALLER_FILENAME: ${{ steps.filename.outputs.INSTALLER_FILENAME }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10.x'
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
+
+ - name: Install Python requirements for runner
+ run: pip install -r .github/workflows/requirements-conan-package.txt
+
+ - name: Cache Conan local repository packages (Bash)
+ uses: actions/cache@v3
+ with:
+ path: |
+ $HOME/.conan/data
+ $HOME/.conan/conan_download_cache
+ key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache
+
+ - name: Install MacOS system requirements
+ run: brew install cmake autoconf automake ninja create-dmg
+
+ - name: Create the default Conan profile
+ run: conan profile new default --detect --force
+
+ - name: Remove Macos keychain (Bash)
+ run: security delete-keychain signing_temp.keychain || true
+
+ - name: Configure Macos keychain Developer Cert(Bash)
+ id: macos-keychain-developer-cert
+ uses: apple-actions/import-codesign-certs@v1
+ with:
+ keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
+ p12-file-base64: ${{ secrets.MACOS_CERT_P12 }}
+ p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }}
+
+ - name: Configure Macos keychain Installer Cert (Bash)
+ id: macos-keychain-installer-cert
+ uses: apple-actions/import-codesign-certs@v1
+ with:
+ keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
+ create-keychain: false # keychain is created in previous use of action.
+ p12-file-base64: ${{ secrets.MACOS_CERT_INSTALLER_P12 }}
+ p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }}
+
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
+
+ - name: Use Conan download cache (Bash)
+ run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
+
+ - name: Create the Packages (Bash)
+ run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING --json "cura_inst/conan_install_info.json"
+
+ - name: Upload the Package(s)
+ if: always()
+ run: |
+ conan upload "*" -r cura --all -c
+
+ - name: Set Environment variables for Cura (bash)
+ run: |
+ . ./cura_inst/bin/activate_github_actions_env.sh
+ . ./cura_inst/bin/activate_github_actions_version_env.sh
+
+ - name: Unlock Macos keychain (Bash)
+ run: security unlock -p $TEMP_KEYCHAIN_PASSWORD signing_temp.keychain
+ env:
+ TEMP_KEYCHAIN_PASSWORD: ${{ steps.macos-keychain-developer-cert.outputs.keychain-password }}
+
+ # FIXME: This is a workaround to ensure that we use and pack a shared library for OpenSSL 1.1.1l. We currently compile
+ # OpenSSL statically for CPython, but our Python Dependenies (such as PyQt6) require a shared library.
+ # Because Conan won't allow for building the same library with two different options (easily) we need to install it explicitly
+ # and do a manual copy to the VirtualEnv, such that Pyinstaller can find it.
+ - name: Install OpenSSL shared
+ run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy
+
+ - name: Copy OpenSSL shared (Bash)
+ run: |
+ cp ./openssl/lib/*.so* ./cura_inst/bin/ || true
+ cp ./openssl/lib/*.dylib* ./cura_inst/bin/ || true
+
+ - name: Create the Cura dist
+ run: pyinstaller ./cura_inst/UltiMaker-Cura.spec
+
+ - name: Output the name file name and extension
+ id: filename
+ shell: python
+ run: |
+ import os
+ enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else ""
+ installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-${{ inputs.architecture }}"
+ output_env = os.environ["GITHUB_OUTPUT"]
+ content = ""
+ if os.path.exists(output_env):
+ with open(output_env, "r") as f:
+ content = f.read()
+ with open(output_env, "w") as f:
+ f.write(content)
+ f.writelines(f"INSTALLER_FILENAME={installer_filename}\n")
+
+ - name: Summarize the used Conan dependencies
+ shell: python
+ run: |
+ import os
+ import json
+ from pathlib import Path
+
+ conan_install_info_path = Path("cura_inst/conan_install_info.json")
+ conan_info = {"installed": []}
+ if os.path.exists(conan_install_info_path):
+ with open(conan_install_info_path, "r") as f:
+ conan_info = json.load(f)
+ sorted_deps = sorted([dep["recipe"]["id"].replace('#', r' rev: ') for dep in conan_info["installed"]])
+
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n")
+ f.writelines("## Conan packages:\n")
+ for dep in sorted_deps:
+ f.writelines(f"`{dep}`\n")
+
+ - name: Summarize the used Python modules
+ shell: python
+ run: |
+ import os
+ import pkg_resources
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("## Python modules:\n")
+ for package in pkg_resources.working_set:
+ f.writelines(f"`{package.key}/{package.version}`\n")
+
+ - name: Create the Macos dmg (Bash)
+ run: python ../cura_inst/packaging/MacOS/build_macos.py --source_path ../cura_inst --dist_path . --cura_conan_version $CURA_CONAN_VERSION --filename "${{ steps.filename.outputs.INSTALLER_FILENAME }}" --build_dmg --build_pkg --app_name "$CURA_APP_NAME"
+ working-directory: dist
+
+ - name: Upload the dmg
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-dmg
+ path: |
+ dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.dmg
+ retention-days: 5
+
+ - name: Upload the pkg
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-pkg
+ path: |
+ dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.pkg
+ retention-days: 5
+
+
+ notify-export:
+ if: ${{ always() }}
+ needs: [ cura-installer-create ]
+
+ uses: ultimaker/cura/.github/workflows/notify.yml@main
+ with:
+ success: ${{ contains(join(needs.*.result, ','), 'success') }}
+ success_title: "Create the Cura distributions"
+ success_body: "Installers for ${{ inputs.cura_conan_version }}"
+ failure_title: "Failed to create the Cura distributions"
+ failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}"
+ secrets: inherit
diff --git a/.github/workflows/requirements-conan-package.txt b/.github/workflows/requirements-conan-package.txt
index 26d167db2b..9380d1cb98 100644
--- a/.github/workflows/requirements-conan-package.txt
+++ b/.github/workflows/requirements-conan-package.txt
@@ -1,2 +1,2 @@
-conan==1.56.0
+conan>=1.60.2,<2.0.0
sip
diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml
index f08acbdb04..8321f42a23 100644
--- a/.github/workflows/unit-test.yml
+++ b/.github/workflows/unit-test.yml
@@ -2,163 +2,165 @@
name: unit-test
on:
- push:
- paths:
- - 'plugins/**'
- - 'resources/**'
- - 'cura/**'
- - 'icons/**'
- - 'tests/**'
- - 'packaging/**'
- - '.github/workflows/conan-*.yml'
- - '.github/workflows/unit-test.yml'
- - '.github/workflows/notify.yml'
- - '.github/workflows/requirements-conan-package.txt'
- - 'requirements*.txt'
- - 'conanfile.py'
- - 'conandata.yml'
- - 'GitVersion.yml'
- - '*.jinja'
- branches:
- - main
- - 'CURA-*'
- - '[1-9]+.[0-9]+'
- tags:
- - '[0-9]+.[0-9]+.[0-9]+'
- - '[0-9]+.[0-9]+-beta'
- pull_request:
- paths:
- - 'plugins/**'
- - 'resources/**'
- - 'cura/**'
- - 'icons/**'
- - 'tests/**'
- - 'packaging/**'
- - '.github/workflows/conan-*.yml'
- - '.github/workflows/unit-test.yml'
- - '.github/workflows/notify.yml'
- - '.github/workflows/requirements-conan-package.txt'
- - 'requirements*.txt'
- - 'conanfile.py'
- - 'conandata.yml'
- - 'GitVersion.yml'
- - '*.jinja'
- branches:
- - main
- - '[1-9]+.[0-9]+'
- tags:
- - '[0-9]+.[0-9]+.[0-9]+'
- - '[0-9]+.[0-9]+-beta'
+ push:
+ paths:
+ - 'plugins/**'
+ - 'resources/**'
+ - 'cura/**'
+ - 'icons/**'
+ - 'tests/**'
+ - 'packaging/**'
+ - '.github/workflows/conan-*.yml'
+ - '.github/workflows/unit-test.yml'
+ - '.github/workflows/notify.yml'
+ - '.github/workflows/requirements-conan-package.txt'
+ - 'requirements*.txt'
+ - 'conanfile.py'
+ - 'conandata.yml'
+ - 'GitVersion.yml'
+ - '*.jinja'
+ branches:
+ - main
+ - 'CURA-*'
+ - '[1-9]+.[0-9]+'
+ tags:
+ - '[0-9]+.[0-9]+.[0-9]+'
+ - '[0-9]+.[0-9]+-beta'
+ pull_request:
+ paths:
+ - 'plugins/**'
+ - 'resources/**'
+ - 'cura/**'
+ - 'icons/**'
+ - 'tests/**'
+ - 'packaging/**'
+ - '.github/workflows/conan-*.yml'
+ - '.github/workflows/unit-test.yml'
+ - '.github/workflows/notify.yml'
+ - '.github/workflows/requirements-conan-package.txt'
+ - 'requirements*.txt'
+ - 'conanfile.py'
+ - 'conandata.yml'
+ - 'GitVersion.yml'
+ - '*.jinja'
+ branches:
+ - main
+ - '[1-9]+.[0-9]+'
+ tags:
+ - '[0-9]+.[0-9]+.[0-9]+'
+ - '[0-9]+.[0-9]+-beta'
env:
- CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
- CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }}
- CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }}
- CONAN_LOG_RUN_TO_OUTPUT: 1
- CONAN_LOGGING_LEVEL: info
- CONAN_NON_INTERACTIVE: 1
+ CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
+ CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }}
+ CONAN_LOG_RUN_TO_OUTPUT: 1
+ CONAN_LOGGING_LEVEL: info
+ CONAN_NON_INTERACTIVE: 1
permissions:
contents: read
jobs:
- conan-recipe-version:
- uses: ultimaker/cura/.github/workflows/conan-recipe-version.yml@main
+ conan-recipe-version:
+ uses: ultimaker/cura/.github/workflows/conan-recipe-version.yml@main
+ with:
+ project_name: cura
+
+ testing:
+ runs-on: ubuntu-22.04
+ needs: [ conan-recipe-version ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
with:
- project_name: cura
+ fetch-depth: 2
- testing:
- runs-on: ubuntu-22.04
- needs: [ conan-recipe-version ]
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.11.x'
+ architecture: 'x64'
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- with:
- fetch-depth: 2
+ - name: Install Python requirements and Create default Conan profile
+ run: pip install -r requirements-conan-package.txt
+ working-directory: .github/workflows/
- - name: Setup Python and pip
- uses: actions/setup-python@v4
- with:
- python-version: '3.11.x'
- architecture: 'x64'
- cache: 'pip'
- cache-dependency-path: .github/workflows/requirements-conan-package.txt
+ - name: Use Conan download cache (Bash)
+ if: ${{ runner.os != 'Windows' }}
+ run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
- - name: Install Python requirements and Create default Conan profile
- run: pip install -r requirements-conan-package.txt
- working-directory: .github/workflows/
+ - name: Cache Conan local repository packages (Bash)
+ uses: actions/cache@v3
+ if: ${{ runner.os != 'Windows' }}
+ with:
+ path: |
+ $HOME/.conan/data
+ $HOME/.conan/conan_download_cache
+ key: conan-${{ runner.os }}-${{ runner.arch }}-unit-cache
- - name: Use Conan download cache (Bash)
- if: ${{ runner.os != 'Windows' }}
- run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache"
+ # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
+ # This is maybe because grub caches the disk it uses last time, which is recreated each time.
+ - name: Install Linux system requirements
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ sudo rm /var/cache/debconf/config.dat
+ sudo dpkg --configure -a
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ sudo apt update
+ sudo apt upgrade
+ sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y
- - name: Cache Conan local repository packages (Bash)
- uses: actions/cache@v3
- if: ${{ runner.os != 'Windows' }}
- with:
- path: |
- $HOME/.conan/data
- $HOME/.conan/conan_download_cache
- key: conan-${{ runner.os }}-${{ runner.arch }}-unit-cache
+ - name: Install GCC-13
+ run: |
+ sudo apt install g++-13 gcc-13 -y
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
- # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
- # This is maybe because grub caches the disk it uses last time, which is recreated each time.
- - name: Install Linux system requirements
- if: ${{ runner.os == 'Linux' }}
- run: |
- sudo rm /var/cache/debconf/config.dat
- sudo dpkg --configure -a
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt update
- sudo apt upgrade
- sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
- - name: Install GCC-12 on ubuntu-22.04
- run: |
- sudo apt install g++-12 gcc-12 -y
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12
-
- - name: Get Conan configuration
- run: conan config install https://github.com/Ultimaker/conan-config.git
+ - name: Get Conan profile
+ run: conan profile new default --detect --force
- - name: Get Conan profile
- run: conan profile new default --detect --force
+ - name: Install dependencies
+ run: conan install . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o cura:devtools=True -g VirtualPythonEnv -if venv
- - name: Install dependencies
- run: conan install . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o cura:devtools=True -g VirtualPythonEnv -if venv
+ - name: Upload the Dependency package(s)
+ run: conan upload "*" -r cura --all -c
- - name: Upload the Dependency package(s)
- run: conan upload "*" -r cura --all -c
+ - name: Set Environment variables for Cura (bash)
+ if: ${{ runner.os != 'Windows' }}
+ run: |
+ . ./venv/bin/activate_github_actions_env.sh
- - name: Set Environment variables for Cura (bash)
- if: ${{ runner.os != 'Windows' }}
- run: |
- . ./venv/bin/activate_github_actions_env.sh
+ - name: Run Unit Test
+ id: run-test
+ run: |
+ pytest --junitxml=junit_cura.xml
+ working-directory: tests
- - name: Run Unit Test
- id: run-test
- run: |
- pytest --junitxml=junit_cura.xml
- working-directory: tests
+ - name: Save PR metadata
+ if: always()
+ run: |
+ echo ${{ github.event.number }} > pr-id.txt
+ echo ${{ github.event.pull_request.head.repo.full_name }} > pr-head-repo.txt
+ echo ${{ github.event.pull_request.head.ref }} > pr-head-ref.txt
+ working-directory: tests
- - name: Save PR metadata
- if: always()
- run: |
- echo ${{ github.event.number }} > pr-id.txt
- echo ${{ github.event.pull_request.head.repo.full_name }} > pr-head-repo.txt
- echo ${{ github.event.pull_request.head.ref }} > pr-head-ref.txt
- working-directory: tests
-
- - name: Upload Test Results
- if: always()
- uses: actions/upload-artifact@v3
- with:
- name: test-result
- path: |
- tests/**/*.xml
- tests/pr-id.txt
- tests/pr-head-repo.txt
- tests/pr-head-ref.txt
+ - name: Upload Test Results
+ if: always()
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-result
+ path: |
+ tests/**/*.xml
+ tests/pr-id.txt
+ tests/pr-head-repo.txt
+ tests/pr-head-ref.txt
diff --git a/.github/workflows/update-translation.yml b/.github/workflows/update-translation.yml
index 65693be937..55ce144666 100644
--- a/.github/workflows/update-translation.yml
+++ b/.github/workflows/update-translation.yml
@@ -1,82 +1,87 @@
name: update-translations
on:
- push:
- paths:
- - 'plugins/**'
- - 'resources/**'
- - 'cura/**'
- - 'icons/**'
- - 'tests/**'
- - 'packaging/**'
- - '.github/workflows/conan-*.yml'
- - '.github/workflows/notify.yml'
- - '.github/workflows/requirements-conan-package.txt'
- - 'requirements*.txt'
- - 'conanfile.py'
- - 'conandata.yml'
- - 'GitVersion.yml'
- - '*.jinja'
- branches:
- - '[1-9].[0-9]'
- - '[1-9].[0-9][0-9]'
- tags:
- - '[1-9].[0-9].[0-9]*'
- - '[1-9].[0-9].[0-9]'
- - '[1-9].[0-9][0-9].[0-9]*'
+ push:
+ paths:
+ - 'plugins/**'
+ - 'resources/**'
+ - 'cura/**'
+ - 'icons/**'
+ - 'tests/**'
+ - 'packaging/**'
+ - '.github/workflows/conan-*.yml'
+ - '.github/workflows/notify.yml'
+ - '.github/workflows/requirements-conan-package.txt'
+ - 'requirements*.txt'
+ - 'conanfile.py'
+ - 'conandata.yml'
+ - 'GitVersion.yml'
+ - '*.jinja'
+ branches:
+ - '[1-9].[0-9]'
+ - '[1-9].[0-9][0-9]'
+ tags:
+ - '[1-9].[0-9].[0-9]*'
+ - '[1-9].[0-9].[0-9]'
+ - '[1-9].[0-9][0-9].[0-9]*'
jobs:
- update-translations:
- name: Update translations
+ update-translations:
+ name: Update translations
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
- - name: Cache Conan data
- id: cache-conan
- uses: actions/cache@v3
- with:
- path: ~/.conan
- key: ${{ runner.os }}-conan
+ - name: Cache Conan data
+ id: cache-conan
+ uses: actions/cache@v3
+ with:
+ path: ~/.conan
+ key: ${{ runner.os }}-conan
- - name: Setup Python and pip
- uses: actions/setup-python@v4
- with:
- python-version: 3.10.x
- cache: pip
- cache-dependency-path: .github/workflows/requirements-conan-package.txt
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: 3.11.x
+ cache: pip
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
- - name: Install Python requirements for runner
- run: pip install -r .github/workflows/requirements-conan-package.txt
+ - name: Install Python requirements for runner
+ run: pip install -r .github/workflows/requirements-conan-package.txt
- # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
- # This is maybe because grub caches the disk it uses last time, which is recreated each time.
- - name: Install Linux system requirements
- if: ${{ runner.os == 'Linux' }}
- run: |
- sudo rm /var/cache/debconf/config.dat
- sudo dpkg --configure -a
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt update
- sudo apt upgrade
- sudo apt install efibootmgr build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison g++-12 gcc-12 -y
- sudo apt install g++-12 gcc-12 -y
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12
+ # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest.
+ # This is maybe because grub caches the disk it uses last time, which is recreated each time.
+ - name: Install Linux system requirements
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ sudo rm /var/cache/debconf/config.dat
+ sudo dpkg --configure -a
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ sudo apt update
+ sudo apt upgrade
+ sudo apt install efibootmgr build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison g++-12 gcc-12 -y
- - name: Create the default Conan profile
- run: conan profile new default --detect --force
+ - name: Install GCC-13
+ run: |
+ sudo apt install g++-13 gcc-13 -y
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
- - name: Get Conan configuration
- run: conan config install https://github.com/Ultimaker/conan-config.git
+ - name: Create the default Conan profile
+ run: conan profile new default --detect --force
- - name: generate the files using Conan install
- run: conan install . --build=missing --update -o cura:devtools=True
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
- - uses: stefanzweifel/git-auto-commit-action@v4
- with:
- file_pattern: resources/i18n/*.po resources/i18n/*.pot
- status_options: --untracked-files=no
- commit_message: update translations
+ - name: generate the files using Conan install
+ run: conan install . --build=missing --update -o cura:devtools=True
+
+ - uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ file_pattern: resources/i18n/*.po resources/i18n/*.pot
+ status_options: --untracked-files=no
+ commit_message: update translations
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
new file mode 100644
index 0000000000..df9056d454
--- /dev/null
+++ b/.github/workflows/windows.yml
@@ -0,0 +1,270 @@
+name: Windows Installer
+run-name: ${{ inputs.cura_conan_version }} for Windows-${{ inputs.architecture }} by @${{ github.actor }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: choice
+ options:
+ - X64
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'windows-2022'
+ type: choice
+ options:
+ - windows-2022
+ workflow_call:
+ inputs:
+ cura_conan_version:
+ description: 'Cura Conan Version'
+ default: 'cura/latest@ultimaker/testing'
+ required: true
+ type: string
+ conan_args:
+ description: 'Conan args: eq.: --require-override'
+ default: ''
+ required: false
+ type: string
+ enterprise:
+ description: 'Build Cura as an Enterprise edition'
+ default: false
+ required: true
+ type: boolean
+ staging:
+ description: 'Use staging API'
+ default: false
+ required: true
+ type: boolean
+ architecture:
+ description: 'Architecture'
+ required: true
+ default: 'X64'
+ type: string
+ operating_system:
+ description: 'OS'
+ required: true
+ default: 'windows-2022'
+ type: string
+
+env:
+ CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }}
+ CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }}
+ WIN_CERT_INSTALLER_CER: ${{ secrets.WIN_CERT_INSTALLER_CER }}
+ WIN_CERT_INSTALLER_CER_PASS: ${{ secrets.WIN_CERT_INSTALLER_CER_PASS }}
+ CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }}
+ ENTERPRISE: ${{ inputs.enterprise }}
+ STAGING: ${{ inputs.staging }}
+
+jobs:
+ cura-installer-create:
+ runs-on: ${{ inputs.operating_system }}
+
+ outputs:
+ INSTALLER_FILENAME: ${{ steps.filename.outputs.INSTALLER_FILENAME }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup Python and pip
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10.x'
+ cache: 'pip'
+ cache-dependency-path: .github/workflows/requirements-conan-package.txt
+
+ - name: Install Python requirements for runner
+ run: pip install -r .github/workflows/requirements-conan-package.txt
+
+ - name: Cache Conan local repository packages (Powershell)
+ uses: actions/cache@v3
+ with:
+ path: |
+ C:\Users\runneradmin\.conan\data
+ C:\.conan
+ C:\Users\runneradmin\.conan\conan_download_cache
+ key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache
+
+ - name: Create the default Conan profile
+ run: conan profile new default --detect --force
+
+ - name: Get Conan configuration
+ run: |
+ conan config install https://github.com/Ultimaker/conan-config.git
+ conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}"
+
+ - name: Use Conan download cache (Powershell)
+ run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache"
+
+ - name: Create the Packages (Powershell)
+ run: conan install $Env:CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$Env:ENTERPRISE -o cura:staging=$Env:STAGING --json "cura_inst/conan_install_info.json"
+
+ - name: Upload the Package(s)
+ if: always()
+ run: |
+ conan upload "*" -r cura --all -c
+
+ - name: Set Environment variables for Cura (Powershell)
+ run: |
+ echo "${Env:WIX}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ .\cura_inst\Scripts\activate_github_actions_env.ps1
+ .\cura_inst\Scripts\activate_github_actions_version_env.ps1
+
+ - name: Install OpenSSL shared
+ run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy
+
+ - name: Copy OpenSSL shared (Powershell)
+ run: |
+ cp openssl/bin/*.dll ./cura_inst/Scripts/
+ cp openssl/lib/*.lib ./cura_inst/Lib/
+
+ - name: Create the Cura dist
+ run: pyinstaller ./cura_inst/UltiMaker-Cura.spec
+
+ - name: Output the name file name and extension
+ id: filename
+ shell: python
+ run: |
+ import os
+ enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else ""
+ installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-win64-${{ inputs.architecture }}"
+ output_env = os.environ["GITHUB_OUTPUT"]
+ content = ""
+ if os.path.exists(output_env):
+ with open(output_env, "r") as f:
+ content = f.read()
+ with open(output_env, "w") as f:
+ f.write(content)
+ f.writelines(f"INSTALLER_FILENAME={installer_filename}\n")
+
+ - name: Summarize the used Conan dependencies
+ shell: python
+ run: |
+ import os
+ import json
+ from pathlib import Path
+
+ conan_install_info_path = Path("cura_inst/conan_install_info.json")
+ conan_info = {"installed": []}
+ if os.path.exists(conan_install_info_path):
+ with open(conan_install_info_path, "r") as f:
+ conan_info = json.load(f)
+ sorted_deps = sorted([dep["recipe"]["id"].replace('#', r' rev: ') for dep in conan_info["installed"]])
+
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n")
+ f.writelines("## Conan packages:\n")
+ for dep in sorted_deps:
+ f.writelines(f"`{dep}`\n")
+
+ - name: Summarize the used Python modules
+ shell: python
+ run: |
+ import os
+ import pkg_resources
+ summary_env = os.environ["GITHUB_STEP_SUMMARY"]
+ content = ""
+ if os.path.exists(summary_env):
+ with open(summary_env, "r") as f:
+ content = f.read()
+
+ with open(summary_env, "w") as f:
+ f.write(content)
+ f.writelines("## Python modules:\n")
+ for package in pkg_resources.working_set:
+ f.writelines(f"`{package.key}/{package.version}`\n")
+
+ - name: Create PFX certificate from BASE64_PFX_CONTENT secret
+ id: create-pfx
+ env:
+ PFX_CONTENT: ${{ secrets.WIN_CERT_INSTALLER_CER }}
+ run: |
+ $pfxPath = Join-Path -Path $env:RUNNER_TEMP -ChildPath "cert.pfx";
+ $encodedBytes = [System.Convert]::FromBase64String($env:PFX_CONTENT);
+ Set-Content $pfxPath -Value $encodedBytes -AsByteStream;
+ echo "PFX_PATH=$pfxPath" >> $env:GITHUB_OUTPUT;
+
+ - name: Create the Windows msi installer (Powershell)
+ run: |
+ python ..\cura_inst\packaging\msi\create_windows_msi.py ..\cura_inst .\UltiMaker-Cura "${{steps.filename.outputs.INSTALLER_FILENAME }}.msi" "$Env:CURA_APP_NAME"
+ working-directory: dist
+
+ - name: Sign the Windows msi installer (Powershell)
+ env:
+ PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }}
+ run: |
+ & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{steps.filename.outputs.INSTALLER_FILENAME }}.msi"
+ working-directory: dist
+
+ - name: Create the Windows exe installer (Powershell)
+ run: |
+ python ..\cura_inst\packaging\NSIS\create_windows_installer.py ../cura_inst . "${{steps.filename.outputs.INSTALLER_FILENAME }}.exe"
+ working-directory: dist
+
+ - name: Sign the Windows exe installer (Powershell)
+ env:
+ PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }}
+ run: |
+ & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{steps.filename.outputs.INSTALLER_FILENAME }}.exe"
+ working-directory: dist
+
+ - name: Upload the msi
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{steps.filename.outputs.INSTALLER_FILENAME }}-msi
+ path: |
+ dist/${{steps.filename.outputs.INSTALLER_FILENAME }}.msi
+ retention-days: 5
+
+ - name: Upload the exe
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{steps.filename.outputs.INSTALLER_FILENAME }}-exe
+ path: |
+ dist/${{steps.filename.outputs.INSTALLER_FILENAME }}.exe
+ retention-days: 5
+
+ notify-export:
+ if: ${{ always() }}
+ needs: [ cura-installer-create ]
+
+ uses: ultimaker/cura/.github/workflows/notify.yml@main
+ with:
+ success: ${{ contains(join(needs.*.result, ','), 'success') }}
+ success_title: "Create the Cura distributions"
+ success_body: "Installers for ${{ inputs.cura_conan_version }}"
+ failure_title: "Failed to create the Cura distributions"
+ failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}"
+ secrets: inherit
diff --git a/CITATION.cff b/CITATION.cff
index 627cfa2515..7a93bbf099 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -18,8 +18,8 @@ url: "https://ultimaker.com/software/ultimaker-cura"
repository-code: "https://github.com/Ultimaker/Cura"
license: LGPL-3.0
license-url: "https://github.com/Ultimaker/Cura/blob/main/LICENSE"
-version: 5.2.1
-date-released: "2022-10-19"
+version: 5.4.0
+date-released: "2023-07-04"
keywords:
- Ultimaker
- Cura
diff --git a/FUNDING.yml b/FUNDING.yml
new file mode 100644
index 0000000000..2d108a74e1
--- /dev/null
+++ b/FUNDING.yml
@@ -0,0 +1 @@
+github: [ultimaker]
diff --git a/conanfile.py b/conanfile.py
index 77cecf1134..1ab7d939af 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -10,7 +10,7 @@ from conan.tools.env import VirtualRunEnv, Environment, VirtualBuildEnv
from conan.tools.scm import Version
from conan.errors import ConanInvalidConfiguration, ConanException
-required_conan_version = ">=1.54 <=1.56.0 || >=1.58.0 <2.0.0"
+required_conan_version = ">=1.58.0 <2.0.0"
class CuraConan(ConanFile):
@@ -293,6 +293,7 @@ class CuraConan(ConanFile):
self.options["pysavitar"].shared = True
self.options["pynest2d"].shared = True
self.options["cpython"].shared = True
+ self.options["boost"].header_only = True
def validate(self):
version = self.conf_info.get("user.cura:version", default = self.version, check_type = str)
@@ -300,10 +301,11 @@ class CuraConan(ConanFile):
raise ConanInvalidConfiguration("Only versions 5+ are support")
def requirements(self):
- self.requires("pyarcus/5.2.2")
+ self.requires("boost/1.82.0")
+ self.requires("pyarcus/(latest)@ultimaker/cura_10951")
self.requires("curaengine/(latest)@ultimaker/testing")
- self.requires("pysavitar/5.2.2")
- self.requires("pynest2d/5.2.2")
+ self.requires("pysavitar/(latest)@ultimaker/cura_10951")
+ self.requires("pynest2d/(latest)@ultimaker/cura_10951")
self.requires("uranium/(latest)@ultimaker/testing")
self.requires("cura_binary_data/(latest)@ultimaker/testing")
self.requires("cpython/3.10.4")
@@ -338,7 +340,38 @@ class CuraConan(ConanFile):
vr.generate()
self._generate_cura_version(os.path.join(self.source_folder, "cura"))
+ self._generate_about_versions(os.path.join(self.source_folder, "resources","qml", "Dialogs"))
+ if not self.in_local_cache:
+ # Copy CuraEngine.exe to bindirs of Virtual Python Environment
+ curaengine = self.dependencies["curaengine"].cpp_info
+ copy(self, "CuraEngine.exe", curaengine.bindirs[0], self.source_folder, keep_path = False)
+ copy(self, "CuraEngine", curaengine.bindirs[0], self.source_folder, keep_path = False)
+
+ # Copy resources of cura_binary_data
+ cura_binary_data = self.dependencies["cura_binary_data"].cpp_info
+ copy(self, "*", cura_binary_data.resdirs[0], str(self._share_dir.joinpath("cura")), keep_path = True)
+ copy(self, "*", cura_binary_data.resdirs[1], str(self._share_dir.joinpath("uranium")), keep_path = True)
+ if self.settings.os == "Windows":
+ copy(self, "*", cura_binary_data.resdirs[2], str(self._share_dir.joinpath("windows")), keep_path = True)
+
+ for dependency in self.dependencies.host.values():
+ for bindir in dependency.cpp_info.bindirs:
+ copy(self, "*.dll", bindir, str(self._site_packages), keep_path = False)
+ for libdir in dependency.cpp_info.libdirs:
+ copy(self, "*.pyd", libdir, str(self._site_packages), keep_path = False)
+ copy(self, "*.pyi", libdir, str(self._site_packages), keep_path = False)
+ copy(self, "*.dylib", libdir, str(self._base_dir.joinpath("lib")), keep_path = False)
+
+ # Copy materials (flat)
+ rmdir(self, os.path.join(self.source_folder, "resources", "materials"))
+ fdm_materials = self.dependencies["fdm_materials"].cpp_info
+ copy(self, "*", fdm_materials.resdirs[0], self.source_folder)
+
+ # Copy internal resources
+ if self.options.internal:
+ cura_private_data = self.dependencies["cura_private_data"].cpp_info
+ copy(self, "*", cura_private_data.resdirs[0], str(self._share_dir.joinpath("cura")))
if self.options.devtools:
entitlements_file = "'{}'".format(os.path.join(self.source_folder, "packaging", "MacOS", "cura.entitlements"))
@@ -357,8 +390,6 @@ class CuraConan(ConanFile):
pot = self.python_requires["translationextractor"].module.ExtractTranslations(self, cpp_info.bindirs[0])
pot.generate()
- self._generate_about_versions(os.path.join(self.source_folder, "resources","qml", "Dialogs"))
-
def build(self):
if self.options.devtools:
if self.settings.os != "Windows" or self.conf.get("tools.microsoft.bash:path", check_type = str):
@@ -370,29 +401,6 @@ class CuraConan(ConanFile):
cpp_info = self.dependencies["gettext"].cpp_info
self.run(f"{cpp_info.bindirs[0]}/msgfmt {po_file} -o {mo_file} -f", env="conanbuild", ignore_errors=True)
- def imports(self):
- self.copy("CuraEngine.exe", root_package = "curaengine", src = "@bindirs", dst = "", keep_path = False)
- self.copy("CuraEngine", root_package = "curaengine", src = "@bindirs", dst = "", keep_path = False)
-
- rmdir(self, os.path.join(self.source_folder, "resources", "materials"))
- self.copy("*.fdm_material", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False)
- self.copy("*.sig", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False)
-
- if self.options.internal:
- self.copy("*", root_package = "cura_private_data", src = self.deps_cpp_info["cura_private_data"].resdirs[0],
- dst = self._share_dir.joinpath("cura", "resources"), keep_path = True)
-
- # Copy resources of cura_binary_data
- self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[0],
- dst = self._share_dir.joinpath("cura", "resources"), keep_path = True)
- self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[1],
- dst =self._share_dir.joinpath("uranium", "resources"), keep_path = True)
-
- self.copy("*.dll", src = "@bindirs", dst = self._site_packages)
- self.copy("*.pyd", src = "@libdirs", dst = self._site_packages)
- self.copy("*.pyi", src = "@libdirs", dst = self._site_packages)
- self.copy("*.dylib", src = "@libdirs", dst = self._script_dir)
-
def deploy(self):
# Copy CuraEngine.exe to bindirs of Virtual Python Environment
curaengine = self.dependencies["curaengine"].cpp_info
diff --git a/cura/Arranging/ArrangeObjectsJob.py b/cura/Arranging/ArrangeObjectsJob.py
index 6ba6717191..48d2436482 100644
--- a/cura/Arranging/ArrangeObjectsJob.py
+++ b/cura/Arranging/ArrangeObjectsJob.py
@@ -8,17 +8,20 @@ from UM.Logger import Logger
from UM.Message import Message
from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog
-from cura.Arranging.Nest2DArrange import arrange
+from cura.Arranging.GridArrange import GridArrange
+from cura.Arranging.Nest2DArrange import Nest2DArrange
i18n_catalog = i18nCatalog("cura")
class ArrangeObjectsJob(Job):
- def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset = 8) -> None:
+ def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset = 8,
+ *, grid_arrange: bool = False) -> None:
super().__init__()
self._nodes = nodes
self._fixed_nodes = fixed_nodes
self._min_offset = min_offset
+ self._grid_arrange = grid_arrange
def run(self):
found_solution_for_all = False
@@ -29,10 +32,18 @@ class ArrangeObjectsJob(Job):
title = i18n_catalog.i18nc("@info:title", "Finding Location"))
status_message.show()
+ if self._grid_arrange:
+ arranger = GridArrange(self._nodes, Application.getInstance().getBuildVolume(), self._fixed_nodes)
+ else:
+ arranger = Nest2DArrange(self._nodes, Application.getInstance().getBuildVolume(), self._fixed_nodes,
+ factor=1000)
+
+ found_solution_for_all = False
try:
- found_solution_for_all = arrange(self._nodes, Application.getInstance().getBuildVolume(), self._fixed_nodes)
+ found_solution_for_all = arranger.arrange()
except: # If the thread crashes, the message should still close
- Logger.logException("e", "Unable to arrange the objects on the buildplate. The arrange algorithm has crashed.")
+ Logger.logException("e",
+ "Unable to arrange the objects on the buildplate. The arrange algorithm has crashed.")
status_message.hide()
diff --git a/cura/Arranging/Arranger.py b/cura/Arranging/Arranger.py
new file mode 100644
index 0000000000..f7f9870cf9
--- /dev/null
+++ b/cura/Arranging/Arranger.py
@@ -0,0 +1,28 @@
+from typing import List, TYPE_CHECKING, Optional, Tuple, Set
+
+if TYPE_CHECKING:
+ from UM.Operations.GroupedOperation import GroupedOperation
+
+
+class Arranger:
+ def createGroupOperationForArrange(self, *, add_new_nodes_in_scene: bool = False) -> Tuple["GroupedOperation", int]:
+ """
+ Find placement for a set of scene nodes, but don't actually move them just yet.
+ :param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
+ :return: tuple (found_solution_for_all, node_items)
+ WHERE
+ found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
+ node_items: A list of the nodes return by libnest2d, which contain the new positions on the buildplate
+ """
+ raise NotImplementedError
+
+ def arrange(self, *, add_new_nodes_in_scene: bool = False) -> bool:
+ """
+ Find placement for a set of scene nodes, and move them by using a single grouped operation.
+ :param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
+ :return: found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
+ """
+ grouped_operation, not_fit_count = self.createGroupOperationForArrange(
+ add_new_nodes_in_scene=add_new_nodes_in_scene)
+ grouped_operation.push()
+ return not_fit_count == 0
diff --git a/cura/Arranging/GridArrange.py b/cura/Arranging/GridArrange.py
new file mode 100644
index 0000000000..493c81b27c
--- /dev/null
+++ b/cura/Arranging/GridArrange.py
@@ -0,0 +1,331 @@
+import math
+from typing import List, TYPE_CHECKING, Tuple, Set
+
+if TYPE_CHECKING:
+ from UM.Scene.SceneNode import SceneNode
+ from cura.BuildVolume import BuildVolume
+
+from UM.Application import Application
+from UM.Math.Vector import Vector
+from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
+from UM.Operations.GroupedOperation import GroupedOperation
+from UM.Operations.TranslateOperation import TranslateOperation
+from cura.Arranging.Arranger import Arranger
+
+
+class GridArrange(Arranger):
+ def __init__(self, nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: List["SceneNode"] = None):
+ if fixed_nodes is None:
+ fixed_nodes = []
+ self._nodes_to_arrange = nodes_to_arrange
+ self._build_volume = build_volume
+ self._build_volume_bounding_box = build_volume.getBoundingBox()
+ self._fixed_nodes = fixed_nodes
+
+ self._margin_x: float = 1
+ self._margin_y: float = 1
+
+ self._grid_width = 0
+ self._grid_height = 0
+ for node in self._nodes_to_arrange:
+ bounding_box = node.getBoundingBox()
+ self._grid_width = max(self._grid_width, bounding_box.width)
+ self._grid_height = max(self._grid_height, bounding_box.depth)
+ self._grid_width += self._margin_x
+ self._grid_height += self._margin_y
+
+ # Round up the grid size to the nearest cm
+ grid_precision = 10 # 1cm
+ self._grid_width = math.ceil(self._grid_width / grid_precision) * grid_precision
+ self._grid_height = math.ceil(self._grid_height / grid_precision) * grid_precision
+
+ self._offset_x = 0
+ self._offset_y = 0
+ self._findOptimalGridOffset()
+
+ coord_initial_leftover_x = self._build_volume_bounding_box.right + 2 * self._grid_width
+ coord_initial_leftover_y = (self._build_volume_bounding_box.back + self._build_volume_bounding_box.front) * 0.5
+ self._initial_leftover_grid_x, self._initial_leftover_grid_y = self._coordSpaceToGridSpace(
+ coord_initial_leftover_x, coord_initial_leftover_y)
+ self._initial_leftover_grid_x = math.floor(self._initial_leftover_grid_x)
+ self._initial_leftover_grid_y = math.floor(self._initial_leftover_grid_y)
+
+ # Find grid indexes that intersect with fixed objects
+ self._fixed_nodes_grid_ids = set()
+ for node in self._fixed_nodes:
+ self._fixed_nodes_grid_ids = self._fixed_nodes_grid_ids.union(
+ self._intersectingGridIdxInclusive(node.getBoundingBox()))
+
+ #grid indexes that are in disallowed area
+ for polygon in self._build_volume.getDisallowedAreas():
+ self._fixed_nodes_grid_ids = self._fixed_nodes_grid_ids.union(
+ self._getIntersectingGridIdForPolygon(polygon))
+
+ self._build_plate_grid_ids = self._intersectingGridIdxExclusive(self._build_volume_bounding_box)
+
+ # Filter out the corner grid squares if the build plate shape is elliptic
+ if self._build_volume.getShape() == "elliptic":
+ self._build_plate_grid_ids = set(
+ filter(lambda grid_id: self._checkGridUnderDiscSpace(grid_id[0], grid_id[1]),
+ self._build_plate_grid_ids))
+
+ self._allowed_grid_idx = self._build_plate_grid_ids.difference(self._fixed_nodes_grid_ids)
+
+ def createGroupOperationForArrange(self, *, add_new_nodes_in_scene: bool = False) -> Tuple[GroupedOperation, int]:
+ # Find the sequence in which items are placed
+ coord_build_plate_center_x = self._build_volume_bounding_box.width * 0.5 + self._build_volume_bounding_box.left
+ coord_build_plate_center_y = self._build_volume_bounding_box.depth * 0.5 + self._build_volume_bounding_box.back
+ grid_build_plate_center_x, grid_build_plate_center_y = self._coordSpaceToGridSpace(coord_build_plate_center_x,
+ coord_build_plate_center_y)
+
+ sequence: List[Tuple[int, int]] = list(self._allowed_grid_idx)
+ sequence.sort(key=lambda grid_id: (grid_build_plate_center_x - grid_id[0]) ** 2 + (
+ grid_build_plate_center_y - grid_id[1]) ** 2)
+ scene_root = Application.getInstance().getController().getScene().getRoot()
+ grouped_operation = GroupedOperation()
+
+ for grid_id, node in zip(sequence, self._nodes_to_arrange):
+ if add_new_nodes_in_scene:
+ grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
+ grid_x, grid_y = grid_id
+ operation = self._moveNodeOnGrid(node, grid_x, grid_y)
+ grouped_operation.addOperation(operation)
+
+ leftover_nodes = self._nodes_to_arrange[len(sequence):]
+
+ left_over_grid_y = self._initial_leftover_grid_y
+ for node in leftover_nodes:
+ if add_new_nodes_in_scene:
+ grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
+ # find the first next grid position that isn't occupied by a fixed node
+ while (self._initial_leftover_grid_x, left_over_grid_y) in self._fixed_nodes_grid_ids:
+ left_over_grid_y = left_over_grid_y - 1
+
+ operation = self._moveNodeOnGrid(node, self._initial_leftover_grid_x, left_over_grid_y)
+ grouped_operation.addOperation(operation)
+ left_over_grid_y = left_over_grid_y - 1
+
+ return grouped_operation, len(leftover_nodes)
+
+ def _findOptimalGridOffset(self):
+ if len(self._fixed_nodes) == 0:
+ self._offset_x = 0
+ self._offset_y = 0
+ return
+
+ if len(self._fixed_nodes) == 1:
+ center_grid_x = 0.5 * self._grid_width + self._build_volume_bounding_box.left
+ center_grid_y = 0.5 * self._grid_height + self._build_volume_bounding_box.back
+
+ bounding_box = self._fixed_nodes[0].getBoundingBox()
+ center_node_x = (bounding_box.left + bounding_box.right) * 0.5
+ center_node_y = (bounding_box.back + bounding_box.front) * 0.5
+
+ self._offset_x = center_node_x - center_grid_x
+ self._offset_y = center_node_y - center_grid_y
+
+ return
+
+ # If there are multiple fixed nodes, an optimal solution is not always possible
+ # We will try to find an offset that minimizes the number of grid intersections
+ # with fixed nodes. The algorithm below achieves this by utilizing a scanline
+ # algorithm. In this algorithm each axis is solved separately as offsetting
+ # is completely independent in each axis. The comments explaining the algorithm
+ # below are for the x-axis, but the same applies for the y-axis.
+ #
+ # Each node either occupies ceil((node.right - node.right) / grid_width) or
+ # ceil((node.right - node.right) / grid_width) + 1 grid squares. We will call
+ # these the node's "footprint".
+ #
+ # ┌────────────────┐
+ # minimum foot-print │ NODE │
+ # └────────────────┘
+ # │ grid 1 │ grid 2 │ grid 3 │ grid 4 | grid 5 |
+ # ┌────────────────┐
+ # maximum foot-print │ NODE │
+ # └────────────────┘
+ #
+ # The algorithm will find the grid offset such that the number of nodes with
+ # a _minimal_ footprint is _maximized_.
+
+ # The scanline algorithm works as follows, we create events for both end points
+ # of each node's footprint. The event have two properties,
+ # - the coordinate: the amount the endpoint can move to the
+ # left before it crosses a grid line
+ # - the change: either +1 or -1, indicating whether crossing the grid line
+ # would result in a minimal footprint node becoming a maximal footprint
+ class Event:
+ def __init__(self, coord: float, change: float):
+ self.coord = coord
+ self.change = change
+
+ # create events for both the horizontal and vertical axis
+ events_horizontal: List[Event] = []
+ events_vertical: List[Event] = []
+
+ for node in self._fixed_nodes:
+ bounding_box = node.getBoundingBox()
+
+ left = bounding_box.left - self._build_volume_bounding_box.left
+ right = bounding_box.right - self._build_volume_bounding_box.left
+ back = bounding_box.back - self._build_volume_bounding_box.back
+ front = bounding_box.front - self._build_volume_bounding_box.back
+
+ value_left = math.ceil(left / self._grid_width) * self._grid_width - left
+ value_right = math.ceil(right / self._grid_width) * self._grid_width - right
+ value_back = math.ceil(back / self._grid_height) * self._grid_height - back
+ value_front = math.ceil(front / self._grid_height) * self._grid_height - front
+
+ # give nodes a weight according to their size. This
+ # weight is heuristically chosen to be proportional to
+ # the number of grid squares the node-boundary occupies
+ weight = bounding_box.width + bounding_box.depth
+
+ events_horizontal.append(Event(value_left, weight))
+ events_horizontal.append(Event(value_right, -weight))
+ events_vertical.append(Event(value_back, weight))
+ events_vertical.append(Event(value_front, -weight))
+
+ events_horizontal.sort(key=lambda event: event.coord)
+ events_vertical.sort(key=lambda event: event.coord)
+
+ def findOptimalShiftAxis(events: List[Event], interval: float) -> float:
+ # executing the actual scanline algorithm
+ # iteratively go through events (left to right) and keep track of the
+ # current footprint. The optimal location is the one with the minimal
+ # footprint. If there are multiple locations with the same minimal
+ # footprint, the optimal location is the one with the largest range
+ # between the left and right endpoint of the footprint.
+ prev_offset = events[-1].coord - interval
+ current_minimal_footprint_count = 0
+
+ best_minimal_footprint_count = float('inf')
+ best_offset_span = float('-inf')
+ best_offset = 0.0
+
+ for event in events:
+ offset_span = event.coord - prev_offset
+
+ if current_minimal_footprint_count < best_minimal_footprint_count or (
+ current_minimal_footprint_count == best_minimal_footprint_count and offset_span > best_offset_span):
+ best_minimal_footprint_count = current_minimal_footprint_count
+ best_offset_span = offset_span
+ best_offset = event.coord
+
+ current_minimal_footprint_count += event.change
+ prev_offset = event.coord
+
+ return best_offset - best_offset_span * 0.5
+
+ center_grid_x = 0.5 * self._grid_width
+ center_grid_y = 0.5 * self._grid_height
+
+ optimal_center_x = self._grid_width - findOptimalShiftAxis(events_horizontal, self._grid_width)
+ optimal_center_y = self._grid_height - findOptimalShiftAxis(events_vertical, self._grid_height)
+
+ self._offset_x = optimal_center_x - center_grid_x
+ self._offset_y = optimal_center_y - center_grid_y
+
+ def _moveNodeOnGrid(self, node: "SceneNode", grid_x: int, grid_y: int) -> "Operation.Operation":
+ coord_grid_x, coord_grid_y = self._gridSpaceToCoordSpace(grid_x, grid_y)
+ center_grid_x = coord_grid_x + (0.5 * self._grid_width)
+ center_grid_y = coord_grid_y + (0.5 * self._grid_height)
+
+ bounding_box = node.getBoundingBox()
+ center_node_x = (bounding_box.left + bounding_box.right) * 0.5
+ center_node_y = (bounding_box.back + bounding_box.front) * 0.5
+
+ delta_x = center_grid_x - center_node_x
+ delta_y = center_grid_y - center_node_y
+
+ return TranslateOperation(node, Vector(delta_x, 0, delta_y))
+
+ def _getGridCornerPoints(self, bounding_box: "BoundingVolume") -> Tuple[float, float, float, float]:
+ coord_x1 = bounding_box.left
+ coord_x2 = bounding_box.right
+ coord_y1 = bounding_box.back
+ coord_y2 = bounding_box.front
+ grid_x1, grid_y1 = self._coordSpaceToGridSpace(coord_x1, coord_y1)
+ grid_x2, grid_y2 = self._coordSpaceToGridSpace(coord_x2, coord_y2)
+ return grid_x1, grid_y1, grid_x2, grid_y2
+
+ def _getIntersectingGridIdForPolygon(self, polygon)-> Set[Tuple[int, int]]:
+ # (x0, y0)
+ # |
+ # v
+ # ┌─────────────┐
+ # │ │
+ # │ │
+ # └─────────────┘ < (x1, y1)
+ x0 = float('inf')
+ y0 = float('inf')
+ x1 = float('-inf')
+ y1 = float('-inf')
+ grid_idx = set()
+ for [x, y] in polygon.getPoints():
+ x0 = min(x0, x)
+ y0 = min(y0, y)
+ x1 = max(x1, x)
+ y1 = max(y1, y)
+ grid_x1, grid_y1 = self._coordSpaceToGridSpace(x0, y0)
+ grid_x2, grid_y2 = self._coordSpaceToGridSpace(x1, y1)
+
+ for grid_x in range(math.floor(grid_x1), math.ceil(grid_x2)):
+ for grid_y in range(math.floor(grid_y1), math.ceil(grid_y2)):
+ grid_idx.add((grid_x, grid_y))
+ return grid_idx
+
+ def _intersectingGridIdxInclusive(self, bounding_box: "BoundingVolume") -> Set[Tuple[int, int]]:
+ grid_x1, grid_y1, grid_x2, grid_y2 = self._getGridCornerPoints(bounding_box)
+ grid_idx = set()
+ for grid_x in range(math.floor(grid_x1), math.ceil(grid_x2)):
+ for grid_y in range(math.floor(grid_y1), math.ceil(grid_y2)):
+ grid_idx.add((grid_x, grid_y))
+ return grid_idx
+
+ def _intersectingGridIdxExclusive(self, bounding_box: "BoundingVolume") -> Set[Tuple[int, int]]:
+ grid_x1, grid_y1, grid_x2, grid_y2 = self._getGridCornerPoints(bounding_box)
+ grid_idx = set()
+ for grid_x in range(math.ceil(grid_x1), math.floor(grid_x2)):
+ for grid_y in range(math.ceil(grid_y1), math.floor(grid_y2)):
+ grid_idx.add((grid_x, grid_y))
+ return grid_idx
+
+ def _gridSpaceToCoordSpace(self, x: float, y: float) -> Tuple[float, float]:
+ grid_x = x * self._grid_width + self._build_volume_bounding_box.left + self._offset_x
+ grid_y = y * self._grid_height + self._build_volume_bounding_box.back + self._offset_y
+ return grid_x, grid_y
+
+ def _coordSpaceToGridSpace(self, grid_x: float, grid_y: float) -> Tuple[float, float]:
+ coord_x = (grid_x - self._build_volume_bounding_box.left - self._offset_x) / self._grid_width
+ coord_y = (grid_y - self._build_volume_bounding_box.back - self._offset_y) / self._grid_height
+ return coord_x, coord_y
+
+ def _checkGridUnderDiscSpace(self, grid_x: int, grid_y: int) -> bool:
+ left, back = self._gridSpaceToCoordSpace(grid_x, grid_y)
+ right, front = self._gridSpaceToCoordSpace(grid_x + 1, grid_y + 1)
+ corners = [(left, back), (right, back), (right, front), (left, front)]
+ return all([self._checkPointUnderDiscSpace(x, y) for x, y in corners])
+
+ def _checkPointUnderDiscSpace(self, x: float, y: float) -> bool:
+ disc_x, disc_y = self._coordSpaceToDiscSpace(x, y)
+ distance_to_center_squared = disc_x ** 2 + disc_y ** 2
+ return distance_to_center_squared <= 1.0
+
+ def _coordSpaceToDiscSpace(self, x: float, y: float) -> Tuple[float, float]:
+ # Transform coordinate system to
+ #
+ # coord_build_plate_left = -1
+ # | coord_build_plate_right = 1
+ # v (0,1) v
+ # ┌───────┬───────┐ < coord_build_plate_back = -1
+ # │ │ │
+ # │ │(0,0) │
+ # (-1,0)├───────o───────┤(1,0)
+ # │ │ │
+ # │ │ │
+ # └───────┴───────┘ < coord_build_plate_front = +1
+ # (0,-1)
+ disc_x = ((x - self._build_volume_bounding_box.left) / self._build_volume_bounding_box.width) * 2.0 - 1.0
+ disc_y = ((y - self._build_volume_bounding_box.back) / self._build_volume_bounding_box.depth) * 2.0 - 1.0
+ return disc_x, disc_y
diff --git a/cura/Arranging/Nest2DArrange.py b/cura/Arranging/Nest2DArrange.py
index 21427f1194..5fcd36c1a3 100644
--- a/cura/Arranging/Nest2DArrange.py
+++ b/cura/Arranging/Nest2DArrange.py
@@ -15,149 +15,137 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.RotateOperation import RotateOperation
from UM.Operations.TranslateOperation import TranslateOperation
-
+from cura.Arranging.Arranger import Arranger
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
from cura.BuildVolume import BuildVolume
-def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000) -> Tuple[bool, List[Item]]:
- """
- Find placement for a set of scene nodes, but don't actually move them just yet.
- :param nodes_to_arrange: The list of nodes that need to be moved.
- :param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
- :param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
- are placed.
- :param factor: The library that we use is int based. This factor defines how accurate we want it to be.
+class Nest2DArrange(Arranger):
+ def __init__(self,
+ nodes_to_arrange: List["SceneNode"],
+ build_volume: "BuildVolume",
+ fixed_nodes: Optional[List["SceneNode"]] = None,
+ *,
+ factor: int = 10000,
+ lock_rotation: bool = False):
+ """
+ :param nodes_to_arrange: The list of nodes that need to be moved.
+ :param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
+ :param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
+ are placed.
+ :param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
+ :param lock_rotation: If set to true the orientation of the object will remain the same
+ """
+ super().__init__()
+ self._nodes_to_arrange = nodes_to_arrange
+ self._build_volume = build_volume
+ self._fixed_nodes = fixed_nodes
+ self._factor = factor
+ self._lock_rotation = lock_rotation
- :return: tuple (found_solution_for_all, node_items)
- WHERE
- found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
- node_items: A list of the nodes return by libnest2d, which contain the new positions on the buildplate
- """
- spacing = int(1.5 * factor) # 1.5mm spacing.
+ def findNodePlacement(self) -> Tuple[bool, List[Item]]:
+ spacing = int(1.5 * self._factor) # 1.5mm spacing.
- machine_width = build_volume.getWidth()
- machine_depth = build_volume.getDepth()
- build_plate_bounding_box = Box(int(machine_width * factor), int(machine_depth * factor))
+ machine_width = self._build_volume.getWidth()
+ machine_depth = self._build_volume.getDepth()
+ build_plate_bounding_box = Box(int(machine_width * self._factor), int(machine_depth * self._factor))
- if fixed_nodes is None:
- fixed_nodes = []
+ if self._fixed_nodes is None:
+ self._fixed_nodes = []
- # Add all the items we want to arrange
- node_items = []
- for node in nodes_to_arrange:
- hull_polygon = node.callDecoration("getConvexHull")
- if not hull_polygon or hull_polygon.getPoints is None:
- Logger.log("w", "Object {} cannot be arranged because it has no convex hull.".format(node.getName()))
- continue
- converted_points = []
- for point in hull_polygon.getPoints():
- converted_points.append(Point(int(point[0] * factor), int(point[1] * factor)))
- item = Item(converted_points)
- node_items.append(item)
-
- # Use a tiny margin for the build_plate_polygon (the nesting doesn't like overlapping disallowed areas)
- half_machine_width = 0.5 * machine_width - 1
- half_machine_depth = 0.5 * machine_depth - 1
- build_plate_polygon = Polygon(numpy.array([
- [half_machine_width, -half_machine_depth],
- [-half_machine_width, -half_machine_depth],
- [-half_machine_width, half_machine_depth],
- [half_machine_width, half_machine_depth]
- ], numpy.float32))
-
- disallowed_areas = build_volume.getDisallowedAreas()
- num_disallowed_areas_added = 0
- for area in disallowed_areas:
- converted_points = []
-
- # Clip the disallowed areas so that they don't overlap the bounding box (The arranger chokes otherwise)
- clipped_area = area.intersectionConvexHulls(build_plate_polygon)
-
- if clipped_area.getPoints() is not None and len(clipped_area.getPoints()) > 2: # numpy array has to be explicitly checked against None
- for point in clipped_area.getPoints():
- converted_points.append(Point(int(point[0] * factor), int(point[1] * factor)))
-
- disallowed_area = Item(converted_points)
- disallowed_area.markAsDisallowedAreaInBin(0)
- node_items.append(disallowed_area)
- num_disallowed_areas_added += 1
-
- for node in fixed_nodes:
- converted_points = []
- hull_polygon = node.callDecoration("getConvexHull")
-
- if hull_polygon is not None and hull_polygon.getPoints() is not None and len(hull_polygon.getPoints()) > 2: # numpy array has to be explicitly checked against None
+ # Add all the items we want to arrange
+ node_items = []
+ for node in self._nodes_to_arrange:
+ hull_polygon = node.callDecoration("getConvexHull")
+ if not hull_polygon or hull_polygon.getPoints is None:
+ Logger.log("w", "Object {} cannot be arranged because it has no convex hull.".format(node.getName()))
+ continue
+ converted_points = []
for point in hull_polygon.getPoints():
- converted_points.append(Point(int(point[0] * factor), int(point[1] * factor)))
+ converted_points.append(Point(int(point[0] * self._factor), int(point[1] * self._factor)))
item = Item(converted_points)
- item.markAsFixedInBin(0)
node_items.append(item)
- num_disallowed_areas_added += 1
- config = NfpConfig()
- config.accuracy = 1.0
- config.alignment = NfpConfig.Alignment.DONT_ALIGN
+ # Use a tiny margin for the build_plate_polygon (the nesting doesn't like overlapping disallowed areas)
+ half_machine_width = 0.5 * machine_width - 1
+ half_machine_depth = 0.5 * machine_depth - 1
+ build_plate_polygon = Polygon(numpy.array([
+ [half_machine_width, -half_machine_depth],
+ [-half_machine_width, -half_machine_depth],
+ [-half_machine_width, half_machine_depth],
+ [half_machine_width, half_machine_depth]
+ ], numpy.float32))
- num_bins = nest(node_items, build_plate_bounding_box, spacing, config)
+ disallowed_areas = self._build_volume.getDisallowedAreas()
+ num_disallowed_areas_added = 0
+ for area in disallowed_areas:
+ converted_points = []
- # Strip the fixed items (previously placed) and the disallowed areas from the results again.
- node_items = list(filter(lambda item: not item.isFixed(), node_items))
+ # Clip the disallowed areas so that they don't overlap the bounding box (The arranger chokes otherwise)
+ clipped_area = area.intersectionConvexHulls(build_plate_polygon)
- found_solution_for_all = num_bins == 1
+ if clipped_area.getPoints() is not None and len(
+ clipped_area.getPoints()) > 2: # numpy array has to be explicitly checked against None
+ for point in clipped_area.getPoints():
+ converted_points.append(Point(int(point[0] * self._factor), int(point[1] * self._factor)))
- return found_solution_for_all, node_items
+ disallowed_area = Item(converted_points)
+ disallowed_area.markAsDisallowedAreaInBin(0)
+ node_items.append(disallowed_area)
+ num_disallowed_areas_added += 1
+ for node in self._fixed_nodes:
+ converted_points = []
+ hull_polygon = node.callDecoration("getConvexHull")
-def createGroupOperationForArrange(nodes_to_arrange: List["SceneNode"],
- build_volume: "BuildVolume",
- fixed_nodes: Optional[List["SceneNode"]] = None,
- factor = 10000,
- add_new_nodes_in_scene: bool = False) -> Tuple[GroupedOperation, int]:
- scene_root = Application.getInstance().getController().getScene().getRoot()
- found_solution_for_all, node_items = findNodePlacement(nodes_to_arrange, build_volume, fixed_nodes, factor)
+ if hull_polygon is not None and hull_polygon.getPoints() is not None and len(
+ hull_polygon.getPoints()) > 2: # numpy array has to be explicitly checked against None
+ for point in hull_polygon.getPoints():
+ converted_points.append(Point(int(point[0] * self._factor), int(point[1] * self._factor)))
+ item = Item(converted_points)
+ item.markAsFixedInBin(0)
+ node_items.append(item)
+ num_disallowed_areas_added += 1
- not_fit_count = 0
- grouped_operation = GroupedOperation()
- for node, node_item in zip(nodes_to_arrange, node_items):
- if add_new_nodes_in_scene:
- grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
+ config = NfpConfig()
+ config.accuracy = 1.0
+ config.alignment = NfpConfig.Alignment.DONT_ALIGN
+ if self._lock_rotation:
+ config.rotations = [0.0]
- if node_item.binId() == 0:
- # We found a spot for it
- rotation_matrix = Matrix()
- rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0))
- grouped_operation.addOperation(RotateOperation(node, Quaternion.fromMatrix(rotation_matrix)))
- grouped_operation.addOperation(TranslateOperation(node, Vector(node_item.translation().x() / factor, 0,
- node_item.translation().y() / factor)))
- else:
- # We didn't find a spot
- grouped_operation.addOperation(
- TranslateOperation(node, Vector(200, node.getWorldPosition().y, -not_fit_count * 20), set_position = True))
- not_fit_count += 1
+ num_bins = nest(node_items, build_plate_bounding_box, spacing, config)
- return grouped_operation, not_fit_count
+ # Strip the fixed items (previously placed) and the disallowed areas from the results again.
+ node_items = list(filter(lambda item: not item.isFixed(), node_items))
+ found_solution_for_all = num_bins == 1
-def arrange(nodes_to_arrange: List["SceneNode"],
- build_volume: "BuildVolume",
- fixed_nodes: Optional[List["SceneNode"]] = None,
- factor = 10000,
- add_new_nodes_in_scene: bool = False) -> bool:
- """
- Find placement for a set of scene nodes, and move them by using a single grouped operation.
- :param nodes_to_arrange: The list of nodes that need to be moved.
- :param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
- :param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
- are placed.
- :param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
- :param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
+ return found_solution_for_all, node_items
- :return: found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
- """
+ def createGroupOperationForArrange(self, *, add_new_nodes_in_scene: bool = False) -> Tuple[GroupedOperation, int]:
+ scene_root = Application.getInstance().getController().getScene().getRoot()
+ found_solution_for_all, node_items = self.findNodePlacement()
- grouped_operation, not_fit_count = createGroupOperationForArrange(nodes_to_arrange, build_volume, fixed_nodes, factor, add_new_nodes_in_scene)
- grouped_operation.push()
- return not_fit_count == 0
+ not_fit_count = 0
+ grouped_operation = GroupedOperation()
+ for node, node_item in zip(self._nodes_to_arrange, node_items):
+ if add_new_nodes_in_scene:
+ grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
+
+ if node_item.binId() == 0:
+ # We found a spot for it
+ rotation_matrix = Matrix()
+ rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0))
+ grouped_operation.addOperation(RotateOperation(node, Quaternion.fromMatrix(rotation_matrix)))
+ grouped_operation.addOperation(
+ TranslateOperation(node, Vector(node_item.translation().x() / self._factor, 0,
+ node_item.translation().y() / self._factor)))
+ else:
+ # We didn't find a spot
+ grouped_operation.addOperation(
+ TranslateOperation(node, Vector(200, node.getWorldPosition().y, -not_fit_count * 20), set_position = True))
+ not_fit_count += 1
+
+ return grouped_operation, not_fit_count
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 0d6ecf5810..045156dcce 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -203,6 +203,9 @@ class BuildVolume(SceneNode):
if shape:
self._shape = shape
+ def getShape(self) -> str:
+ return self._shape
+
def getDiagonalSize(self) -> float:
"""Get the length of the 3D diagonal through the build volume.
diff --git a/cura/CuraActions.py b/cura/CuraActions.py
index 6c2d3f4cb8..9a61a1c4f0 100644
--- a/cura/CuraActions.py
+++ b/cura/CuraActions.py
@@ -22,7 +22,10 @@ from cura.Operations.SetParentOperation import SetParentOperation
from cura.MultiplyObjectsJob import MultiplyObjectsJob
from cura.Settings.SetObjectExtruderOperation import SetObjectExtruderOperation
from cura.Settings.ExtruderManager import ExtruderManager
-from cura.Arranging.Nest2DArrange import createGroupOperationForArrange
+
+from cura.Arranging.GridArrange import GridArrange
+from cura.Arranging.Nest2DArrange import Nest2DArrange
+
from cura.Operations.SetBuildPlateNumberOperation import SetBuildPlateNumberOperation
@@ -82,16 +85,25 @@ class CuraActions(QObject):
center_operation = TranslateOperation(current_node, Vector(0, center_y, 0), set_position = True)
operation.addOperation(center_operation)
operation.push()
-
@pyqtSlot(int)
def multiplySelection(self, count: int) -> None:
"""Multiply all objects in the selection
+ :param count: The number of times to multiply the selection.
+ """
+ min_offset = cura.CuraApplication.CuraApplication.getInstance().getBuildVolume().getEdgeDisallowedSize() + 2 # Allow for some rounding errors
+ job = MultiplyObjectsJob(Selection.getAllSelectedObjects(), count, min_offset = max(min_offset, 8))
+ job.start()
+
+ @pyqtSlot(int)
+ def multiplySelectionToGrid(self, count: int) -> None:
+ """Multiply all objects in the selection
:param count: The number of times to multiply the selection.
"""
min_offset = cura.CuraApplication.CuraApplication.getInstance().getBuildVolume().getEdgeDisallowedSize() + 2 # Allow for some rounding errors
- job = MultiplyObjectsJob(Selection.getAllSelectedObjects(), count, min_offset = max(min_offset, 8))
+ job = MultiplyObjectsJob(Selection.getAllSelectedObjects(), count, min_offset=max(min_offset, 8),
+ grid_arrange=True)
job.start()
@pyqtSlot()
@@ -229,9 +241,9 @@ class CuraActions(QObject):
if node.callDecoration("isSliceable"):
fixed_nodes.append(node)
# Add the new nodes to the scene, and arrange them
- group_operation, not_fit_count = createGroupOperationForArrange(nodes, application.getBuildVolume(),
- fixed_nodes, factor=10000,
- add_new_nodes_in_scene=True)
+
+ arranger = GridArrange(nodes, application.getBuildVolume(), fixed_nodes)
+ group_operation, not_fit_count = arranger.createGroupOperationForArrange(add_new_nodes_in_scene = True)
group_operation.push()
# deselect currently selected nodes, and select the new nodes
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 889e442eaa..a2edde95a8 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -54,7 +54,6 @@ from cura import ApplicationMetadata
from cura.API import CuraAPI
from cura.API.Account import Account
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
-from cura.Arranging.Nest2DArrange import arrange
from cura.Machines.MachineErrorChecker import MachineErrorChecker
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
@@ -115,6 +114,7 @@ from . import CameraAnimation
from . import CuraActions
from . import PlatformPhysics
from . import PrintJobPreviewImageProvider
+from .Arranging.Nest2DArrange import Nest2DArrange
from .AutoSave import AutoSave
from .Machines.Models.CompatibleMachineModel import CompatibleMachineModel
from .Machines.Models.MachineListModel import MachineListModel
@@ -409,7 +409,9 @@ class CuraApplication(QtApplication):
SettingFunction.registerOperator("extruderValue", self._cura_formula_functions.getValueInExtruder)
SettingFunction.registerOperator("extruderValues", self._cura_formula_functions.getValuesInAllExtruders)
- SettingFunction.registerOperator("anyExtruderNrWithOrDefault", self._cura_formula_functions.getAnyExtruderPositionWithOrDefault)
+ SettingFunction.registerOperator("anyExtruderWithMaterial", self._cura_formula_functions.getExtruderPositionWithMaterial)
+ SettingFunction.registerOperator("anyExtruderNrWithOrDefault",
+ self._cura_formula_functions.getAnyExtruderPositionWithOrDefault)
SettingFunction.registerOperator("resolveOrValue", self._cura_formula_functions.getResolveOrValue)
SettingFunction.registerOperator("defaultExtruderPosition", self._cura_formula_functions.getDefaultExtruderPosition)
SettingFunction.registerOperator("valueFromContainer", self._cura_formula_functions.getValueFromContainerAtIndex)
@@ -495,6 +497,36 @@ class CuraApplication(QtApplication):
def startSplashWindowPhase(self) -> None:
"""Runs preparations that needs to be done before the starting process."""
+ self.setRequiredPlugins([
+ # Misc.:
+ "ConsoleLogger", # You want to be able to read the log if something goes wrong.
+ "CuraEngineBackend", # Cura is useless without this one since you can't slice.
+ "FileLogger", # You want to be able to read the log if something goes wrong.
+ "XmlMaterialProfile", # Cura crashes without this one.
+ "Marketplace",
+ # This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
+ "PrepareStage", # Cura is useless without this one since you can't load models.
+ "PreviewStage", # This shows the list of the plugin views that are installed in Cura.
+ "MonitorStage", # Major part of Cura's functionality.
+ "LocalFileOutputDevice", # Major part of Cura's functionality.
+ "LocalContainerProvider", # Cura is useless without any profiles or setting definitions.
+
+ # Views:
+ "SimpleView", # Dependency of SolidView.
+ "SolidView", # Displays models. Cura is useless without it.
+
+ # Readers & Writers:
+ "GCodeWriter", # Cura is useless if it can't write its output.
+ "STLReader", # Most common model format, so disabling this makes Cura 90% useless.
+ "3MFWriter", # Required for writing project files.
+
+ # Tools:
+ "CameraTool", # Needed to see the scene. Cura is useless without it.
+ "SelectionTool", # Dependency of the rest of the tools.
+ "TranslateTool", # You'll need this for almost every print.
+ ])
+ # Plugins need to be set here, since in the super the check is done if they are actually loaded.
+
super().startSplashWindowPhase()
if not self.getIsHeadLess():
@@ -503,33 +535,7 @@ class CuraApplication(QtApplication):
except FileNotFoundError:
Logger.log("w", "Unable to find the window icon.")
- self.setRequiredPlugins([
- # Misc.:
- "ConsoleLogger", #You want to be able to read the log if something goes wrong.
- "CuraEngineBackend", #Cura is useless without this one since you can't slice.
- "FileLogger", #You want to be able to read the log if something goes wrong.
- "XmlMaterialProfile", #Cura crashes without this one.
- "Marketplace", #This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
- "PrepareStage", #Cura is useless without this one since you can't load models.
- "PreviewStage", #This shows the list of the plugin views that are installed in Cura.
- "MonitorStage", #Major part of Cura's functionality.
- "LocalFileOutputDevice", #Major part of Cura's functionality.
- "LocalContainerProvider", #Cura is useless without any profiles or setting definitions.
- # Views:
- "SimpleView", #Dependency of SolidView.
- "SolidView", #Displays models. Cura is useless without it.
-
- # Readers & Writers:
- "GCodeWriter", #Cura is useless if it can't write its output.
- "STLReader", #Most common model format, so disabling this makes Cura 90% useless.
- "3MFWriter", #Required for writing project files.
-
- # Tools:
- "CameraTool", #Needed to see the scene. Cura is useless without it.
- "SelectionTool", #Dependency of the rest of the tools.
- "TranslateTool", #You'll need this for almost every print.
- ])
self._i18n_catalog = i18nCatalog("cura")
self._update_platform_activity_timer = QTimer()
@@ -1438,6 +1444,13 @@ class CuraApplication(QtApplication):
# Single build plate
@pyqtSlot()
def arrangeAll(self) -> None:
+ self._arrangeAll(grid_arrangement = False)
+
+ @pyqtSlot()
+ def arrangeAllInGrid(self) -> None:
+ self._arrangeAll(grid_arrangement = True)
+
+ def _arrangeAll(self, *, grid_arrangement: bool) -> None:
nodes_to_arrange = []
active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
locked_nodes = []
@@ -1467,17 +1480,17 @@ class CuraApplication(QtApplication):
locked_nodes.append(node)
else:
nodes_to_arrange.append(node)
- self.arrange(nodes_to_arrange, locked_nodes)
+ self.arrange(nodes_to_arrange, locked_nodes, grid_arrangement = grid_arrangement)
- def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None:
+ def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], *, grid_arrangement: bool = False) -> None:
"""Arrange a set of nodes given a set of fixed nodes
:param nodes: nodes that we have to place
:param fixed_nodes: nodes that are placed in the arranger before finding spots for nodes
+ :param grid_arrangement: If set to true if objects are to be placed in a grid
"""
-
min_offset = self.getBuildVolume().getEdgeDisallowedSize() + 2 # Allow for some rounding errors
- job = ArrangeObjectsJob(nodes, fixed_nodes, min_offset = max(min_offset, 8))
+ job = ArrangeObjectsJob(nodes, fixed_nodes, min_offset = max(min_offset, 8), grid_arrange = grid_arrangement)
job.start()
@pyqtSlot()
@@ -1964,7 +1977,8 @@ class CuraApplication(QtApplication):
if select_models_on_load:
Selection.add(node)
try:
- arrange(nodes_to_arrange, self.getBuildVolume(), fixed_nodes)
+ arranger = Nest2DArrange(nodes_to_arrange, self.getBuildVolume(), fixed_nodes)
+ arranger.arrange()
except:
Logger.logException("e", "Failed to arrange the models")
diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py
index 1446ae687e..889b6f5d1a 100644
--- a/cura/MultiplyObjectsJob.py
+++ b/cura/MultiplyObjectsJob.py
@@ -14,17 +14,19 @@ from UM.Operations.TranslateOperation import TranslateOperation
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog
-from cura.Arranging.Nest2DArrange import arrange, createGroupOperationForArrange
+from cura.Arranging.GridArrange import GridArrange
+from cura.Arranging.Nest2DArrange import Nest2DArrange
i18n_catalog = i18nCatalog("cura")
class MultiplyObjectsJob(Job):
- def __init__(self, objects, count, min_offset = 8):
+ def __init__(self, objects, count: int, min_offset: int = 8 ,* , grid_arrange: bool = False):
super().__init__()
self._objects = objects
- self._count = count
- self._min_offset = min_offset
+ self._count: int = count
+ self._min_offset: int = min_offset
+ self._grid_arrange: bool = grid_arrange
def run(self) -> None:
status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime = 0,
@@ -39,7 +41,7 @@ class MultiplyObjectsJob(Job):
root = scene.getRoot()
- processed_nodes = [] # type: List[SceneNode]
+ processed_nodes: List[SceneNode] = []
nodes = []
fixed_nodes = []
@@ -76,12 +78,12 @@ class MultiplyObjectsJob(Job):
found_solution_for_all = True
group_operation = GroupedOperation()
if nodes:
- group_operation, not_fit_count = createGroupOperationForArrange(nodes,
- Application.getInstance().getBuildVolume(),
- fixed_nodes,
- factor = 10000,
- add_new_nodes_in_scene = True)
- found_solution_for_all = not_fit_count == 0
+ if self._grid_arrange:
+ arranger = GridArrange(nodes, Application.getInstance().getBuildVolume(), fixed_nodes)
+ else:
+ arranger = Nest2DArrange(nodes, Application.getInstance().getBuildVolume(), fixed_nodes, factor=1000)
+
+ group_operation, not_fit_count = arranger.createGroupOperationForArrange(add_new_nodes_in_scene=True)
if nodes_to_add_without_arrange:
for nested_node in nodes_to_add_without_arrange:
diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py
index 06ec247ae4..0dbf3ba782 100644
--- a/cura/Scene/ConvexHullDecorator.py
+++ b/cura/Scene/ConvexHullDecorator.py
@@ -111,11 +111,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
# Parent can be None if node is just loaded.
if self._isSingularOneAtATimeNode():
- hull = self.getConvexHullHeadFull()
- if hull is None:
- return None
- hull = self._add2DAdhesionMargin(hull)
- return hull
+ return self.getConvexHullHeadFull()
return self._compute2DConvexHull()
@@ -323,6 +319,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def _compute2DConvexHeadFull(self) -> Optional[Polygon]:
convex_hull = self._compute2DConvexHull()
+ convex_hull = self._add2DAdhesionMargin(convex_hull)
if convex_hull:
return convex_hull.getMinkowskiHull(self._getHeadAndFans())
return None
diff --git a/cura/Settings/CuraFormulaFunctions.py b/cura/Settings/CuraFormulaFunctions.py
index fd6555e679..d7b6228e09 100644
--- a/cura/Settings/CuraFormulaFunctions.py
+++ b/cura/Settings/CuraFormulaFunctions.py
@@ -99,12 +99,21 @@ class CuraFormulaFunctions:
# Get the first extruder that adheres to a specific (boolean) property, like 'material_is_support_material'.
def getAnyExtruderPositionWithOrDefault(self, filter_key: str,
- context: Optional["PropertyEvaluationContext"] = None) -> str:
+ context: Optional["PropertyEvaluationContext"] = None) -> str:
for extruder in self._getActiveExtruders(context):
value = extruder.getRawProperty(filter_key, "value", context=context)
if value is None or not value:
continue
return str(extruder.position)
+
+ # Get the first extruder with material that adheres to a specific (boolean) property, like 'material_is_support_material'.
+ def getExtruderPositionWithMaterial(self, filter_key: str,
+ context: Optional["PropertyEvaluationContext"] = None) -> str:
+ for extruder in self._getActiveExtruders(context):
+ material_container = extruder.material
+ value = material_container.getProperty(filter_key, "value", context)
+ if value is not None:
+ return str(extruder.position)
return self.getDefaultExtruderPosition()
# Get the resolve value or value for a given key.
diff --git a/docs/profiles/getting_a_setting_value.md b/docs/profiles/getting_a_setting_value.md
index bd106eb2da..7cd912ac45 100644
--- a/docs/profiles/getting_a_setting_value.md
+++ b/docs/profiles/getting_a_setting_value.md
@@ -54,7 +54,10 @@ There are also a few extra things that can be used in these expressions:
* The function `extruderValue(extruder, key)` will evaluate a particular setting for a particular extruder.
* The function `resolveOrValue(key)` will perform the full setting evaluation as described in this document for the current context (so if this setting is being evaluated for the second extruder it would perform it as if coming from the second extruder).
* The function `defaultExtruderPosition()` will get the first extruder that is not disabled. For instance, if a printer has three extruders but the first is disabled, this would return `1` to indicate the second extruder (0-indexed).
-* The function `anyExtruderNrWithOrDefault(key)` will filter the list of extruders on the key, and then give the first index for which it is true, or if none of them are, the default one as specified by the 'default extruder position' function above.
+* The function `anyExtruderNrWithOrDefault(key)` will filter the list of extruders on the key, and then give the first
+ index for which it is true, or if none of them are, the default one as specified by the 'default extruder position'
+ function above.
+* The function `anyExtruderWithMaterial(key)` will filter the list of extruders on the key of material quality, and then give the first index for which it is true, or if none of them are, the default one as specified by the 'default extruder position' function above.
* The function `valueFromContainer(key, index)` will get a setting value from the global stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
* The function `extruderValueFromContainer(key, index)` will get a setting value from the current extruder stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
diff --git a/packaging/MacOS/build_macos.py b/packaging/MacOS/build_macos.py
index dcde629900..eae9afceff 100644
--- a/packaging/MacOS/build_macos.py
+++ b/packaging/MacOS/build_macos.py
@@ -21,6 +21,7 @@ def build_dmg(source_path: str, dist_path: str, filename: str, app_name: str) ->
"--icon", app_name, "169", "272",
"--eula", f"{source_path}/packaging/cura_license.txt",
"--background", f"{source_path}/packaging/MacOs/cura_background_dmg.png",
+ "--hdiutil-quiet",
f"{dist_path}/{filename}",
f"{dist_path}/{app_name}"]
@@ -138,18 +139,20 @@ def create_dmg(filename: str, dist_path: str, source_path: str, app_name: str) -
if __name__ == "__main__":
parser = argparse.ArgumentParser(description = "Create installer for Cura.")
- parser.add_argument("source_path", type = str, help = "Path to Pyinstaller source folder")
- parser.add_argument("dist_path", type = str, help = "Path to Pyinstaller dist folder")
- parser.add_argument("cura_conan_version", type = str, help="The version of cura")
- parser.add_argument("filename", type = str, help = "Filename of the pkg/dmg (e.g. 'UltiMaker-Cura-5.1.0-beta-Macos-X64.pkg' or 'UltiMaker-Cura-5.1.0-beta-Macos-X64.dmg')")
- parser.add_argument("app_name", type = str, help = "Filename of the .app that will be contained within the dmg/pkg")
+ parser.add_argument("--source_path", required = True, type = str, help = "Path to Pyinstaller source folder")
+ parser.add_argument("--dist_path", required = True, type = str, help = "Path to Pyinstaller dist folder")
+ parser.add_argument("--cura_conan_version", required = True, type = str, help = "The version of cura")
+ parser.add_argument("--filename", required = True, type = str, help = "Filename of the pkg/dmg (e.g. 'UltiMaker-Cura-5.5.0-Macos-X64' or 'UltiMaker-Cura-5.5.0-beta.1-Macos-ARM64')")
+ parser.add_argument("--build_pkg", action="store_true", default = False, help = "build the pkg")
+ parser.add_argument("--build_dmg", action="store_true", default = True, help = "build the dmg")
+ parser.add_argument("--app_name", required = True, type = str, help = "Filename of the .app that will be contained within the dmg/pkg")
args = parser.parse_args()
cura_version = args.cura_conan_version.split("/")[-1]
app_name = f"{args.app_name}.app"
- if Path(args.filename).suffix == ".pkg":
- create_pkg_installer(args.filename, args.dist_path, cura_version, app_name)
- else:
- create_dmg(args.filename, args.dist_path, args.source_path, app_name)
+ if args.build_pkg:
+ create_pkg_installer(f"{args.filename}.pkg", args.dist_path, cura_version, app_name)
+ if args.build_dmg:
+ create_dmg(f"{args.filename}.dmg", args.dist_path, args.source_path, app_name)
diff --git a/packaging/MacOS/cura_background_dmg.png b/packaging/MacOS/cura_background_dmg.png
index 8f2fb50b05..a293d94bd2 100644
Binary files a/packaging/MacOS/cura_background_dmg.png and b/packaging/MacOS/cura_background_dmg.png differ
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
index fbb4214021..b3ef761af5 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
@@ -1,5 +1,5 @@
# Copyright (c) 2018 Jaime van Kessel, Ultimaker B.V.
-# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
import configparser # The script lists are stored in metadata as serialised config files.
import importlib.util
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
index a80f304aaa..0f379479ba 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
@@ -1,5 +1,5 @@
// Copyright (c) 2022 Jaime van Kessel, Ultimaker B.V.
-// The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+// The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 2.15
diff --git a/plugins/PostProcessingPlugin/Script.py b/plugins/PostProcessingPlugin/Script.py
index 1cc9b59c9c..be661e0889 100644
--- a/plugins/PostProcessingPlugin/Script.py
+++ b/plugins/PostProcessingPlugin/Script.py
@@ -1,6 +1,6 @@
# Copyright (c) 2015 Jaime van Kessel
# Copyright (c) 2018 Ultimaker B.V.
-# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
from typing import Optional, Any, Dict, TYPE_CHECKING, List
from UM.Signal import Signal, signalemitter
diff --git a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
index 91b36389f3..2930623a93 100644
--- a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
+++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
@@ -1,7 +1,7 @@
# ChangeAtZ script - Change printing parameters at a given height
# This script is the successor of the TweakAtZ plugin for legacy Cura.
# It contains code from the TweakAtZ plugin V1.0-V4.x and from the ExampleScript by Jaime van Kessel, Ultimaker B.V.
-# It runs with the PostProcessingPlugin which is released under the terms of the AGPLv3 or higher.
+# It runs with the PostProcessingPlugin which is released under the terms of the LGPLv3 or higher.
# This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
# Authors of the ChangeAtZ plugin / script:
diff --git a/plugins/PostProcessingPlugin/scripts/ColorMix.py b/plugins/PostProcessingPlugin/scripts/ColorMix.py
index dacb40e905..534c0208cf 100644
--- a/plugins/PostProcessingPlugin/scripts/ColorMix.py
+++ b/plugins/PostProcessingPlugin/scripts/ColorMix.py
@@ -1,6 +1,6 @@
# ColorMix script - 2-1 extruder color mix and blending
# This script is specific for the Geeetech A10M dual extruder but should work with other Marlin printers.
-# It runs with the PostProcessingPlugin which is released under the terms of the AGPLv3 or higher.
+# It runs with the PostProcessingPlugin which is released under the terms of the LGPLv3 or higher.
# This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
#Authors of the 2-1 ColorMix plug-in / script:
diff --git a/plugins/PostProcessingPlugin/scripts/FilamentChange.py b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
index d3c1e60192..93941c0992 100644
--- a/plugins/PostProcessingPlugin/scripts/FilamentChange.py
+++ b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
@@ -1,5 +1,5 @@
# Copyright (c) 2023 Ultimaker B.V.
-# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
# Modification 06.09.2020
# add checkbox, now you can choose and use configuration from the firmware itself.
diff --git a/plugins/PostProcessingPlugin/scripts/RetractContinue.py b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
index b5ea4d4eda..eaa15e0942 100644
--- a/plugins/PostProcessingPlugin/scripts/RetractContinue.py
+++ b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
@@ -1,5 +1,5 @@
# Copyright (c) 2023 UltiMaker B.V.
-# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
from ..Script import Script
diff --git a/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py b/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
index 40a56ace57..7a12c229cc 100644
--- a/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
+++ b/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
@@ -1,5 +1,5 @@
# Copyright (c) 2017 Ghostkeeper
-# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
import re #To perform the search and replace.
diff --git a/plugins/PostProcessingPlugin/scripts/Stretch.py b/plugins/PostProcessingPlugin/scripts/Stretch.py
index 8d35f68822..ab964d160a 100644
--- a/plugins/PostProcessingPlugin/scripts/Stretch.py
+++ b/plugins/PostProcessingPlugin/scripts/Stretch.py
@@ -1,4 +1,4 @@
-# This PostProcessingPlugin script is released under the terms of the AGPLv3 or higher.
+# This PostProcessingPlugin script is released under the terms of the LGPLv3 or higher.
"""
Copyright (c) 2017 Christophe Baribaud 2017
Python implementation of https://github.com/electrocbd/post_stretch
diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py
index e93473c25f..8c0c50d0b4 100644
--- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py
+++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py
@@ -1,6 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+import os
import os.path
from UM.Application import Application
@@ -143,38 +144,44 @@ class RemovableDriveOutputDevice(OutputDevice):
def _onFinished(self, job):
if self._stream:
- # Explicitly closing the stream flushes the write-buffer
+ error = job.getError()
try:
+ # Explicitly closing the stream flushes the write-buffer
self._stream.close()
- self._stream = None
- except:
- Logger.logException("w", "An exception occurred while trying to write to removable drive.")
- message = Message(catalog.i18nc("@info:status", "Could not save to removable drive {0}: {1}").format(self.getName(),str(job.getError())),
- title = catalog.i18nc("@info:title", "Error"),
- message_type = Message.MessageType.ERROR)
+ except Exception as e:
+ if not error:
+ # Only log new error if there was no previous one
+ error = e
+
+ self._stream = None
+ self._writing = False
+ self.writeFinished.emit(self)
+
+ if not error:
+ message = Message(
+ catalog.i18nc("@info:status", "Saved to Removable Drive {0} as {1}").format(self.getName(),
+ os.path.basename(
+ job.getFileName())),
+ title=catalog.i18nc("@info:title", "File Saved"),
+ message_type=Message.MessageType.POSITIVE)
+ message.addAction("eject", catalog.i18nc("@action:button", "Eject"), "eject",
+ catalog.i18nc("@action", "Eject removable device {0}").format(self.getName()))
+ message.actionTriggered.connect(self._onActionTriggered)
+ message.show()
+ self.writeSuccess.emit(self)
+ else:
+ try:
+ os.remove(job.getFileName())
+ except Exception as e:
+ Logger.logException("e", "Exception when trying to remove incomplete exported file %s",
+ str(job.getFileName()))
+ message = Message(catalog.i18nc("@info:status",
+ "Could not save to removable drive {0}: {1}").format(self.getName(),
+ str(job.getError())),
+ title=catalog.i18nc("@info:title", "Error"),
+ message_type=Message.MessageType.ERROR)
message.show()
self.writeError.emit(self)
- return
-
- self._writing = False
- self.writeFinished.emit(self)
- if job.getResult():
- message = Message(catalog.i18nc("@info:status", "Saved to Removable Drive {0} as {1}").format(self.getName(), os.path.basename(job.getFileName())),
- title = catalog.i18nc("@info:title", "File Saved"),
- message_type = Message.MessageType.POSITIVE)
- message.addAction("eject", catalog.i18nc("@action:button", "Eject"), "eject", catalog.i18nc("@action", "Eject removable device {0}").format(self.getName()))
- message.actionTriggered.connect(self._onActionTriggered)
- message.show()
- self.writeSuccess.emit(self)
- else:
- message = Message(catalog.i18nc("@info:status",
- "Could not save to removable drive {0}: {1}").format(self.getName(),
- str(job.getError())),
- title = catalog.i18nc("@info:title", "Error"),
- message_type = Message.MessageType.ERROR)
- message.show()
- self.writeError.emit(self)
- job.getStream().close()
def _onActionTriggered(self, message, action):
if action == "eject":
diff --git a/plugins/UM3NetworkPrinting/src/Messages/NewPrinterDetectedMessage.py b/plugins/UM3NetworkPrinting/src/Messages/NewPrinterDetectedMessage.py
index d85ade9dce..76254547da 100644
--- a/plugins/UM3NetworkPrinting/src/Messages/NewPrinterDetectedMessage.py
+++ b/plugins/UM3NetworkPrinting/src/Messages/NewPrinterDetectedMessage.py
@@ -37,24 +37,13 @@ class NewPrinterDetectedMessage(Message):
def finalize(self, new_devices_added, new_output_devices):
self.setProgress(None)
- num_devices_added = len(new_devices_added)
- max_disp_devices = 3
-
- if num_devices_added > max_disp_devices:
- num_hidden = num_devices_added - max_disp_devices
- device_name_list = ["
{} ({}) ".format(device.name, device.printerTypeName) for device in
- new_output_devices[0: max_disp_devices]]
- device_name_list.append(
- "" + self.i18n_catalog.i18ncp("info:{0} gets replaced by a number of printers", "... and {0} other",
- "... and {0} others", num_hidden) + " ")
- device_names = "".join(device_name_list)
- else:
- device_names = "".join(
- ["{} ({}) ".format(device.name, device.printerTypeName) for device in new_devices_added])
if new_devices_added:
- message_text = self.i18n_catalog.i18nc("info:status",
- "Printers added from Digital Factory:") + f""
+ device_names = ""
+ for device in new_devices_added:
+ device_names = device_names + "{} ({}) ".format(device.name, device.printerTypeName)
+ message_title = self.i18n_catalog.i18nc("info:status", "Printers added from Digital Factory:")
+ message_text = f"{message_title}"
self.setText(message_text)
else:
self.hide()
diff --git a/resources/definitions/SV02.def.json b/resources/definitions/SV02.def.json
index 95b165075b..728a6c6242 100644
--- a/resources/definitions/SV02.def.json
+++ b/resources/definitions/SV02.def.json
@@ -59,7 +59,7 @@
"machine_width": { "default_value": 280 },
"material_diameter": { "default_value": 1.75 },
"material_initial_print_temperature": { "value": "material_print_temperature" },
- "prime_tower_min_volume": { "value": "((reveOrValue('layer_height'))/2" },
+ "prime_tower_min_volume": { "value": "((resolveOrValue('layer_height'))/2" },
"prime_tower_position_x": { "value": "240" },
"prime_tower_position_y": { "value": "190" },
"prime_tower_size": { "value": "30" },
diff --git a/resources/definitions/elegoo_base.def.json b/resources/definitions/elegoo_base.def.json
index b0a0717c59..c54a388806 100644
--- a/resources/definitions/elegoo_base.def.json
+++ b/resources/definitions/elegoo_base.def.json
@@ -69,7 +69,7 @@
"material_print_temperature_layer_0": { "value": "210 if material_print_temperature < 210 else material_print_temperature" },
"min_infill_area": { "value": "5" },
"minimum_interface_area": { "default_value": 10 },
- "minimum_support_area": { "default_value": 3 },
+ "minimum_support_area": { "value": "3 if support_structure == 'normal' else 0" },
"optimize_wall_printing_order": { "default_value": true },
"prime_tower_brim_enable": { "default_value": true },
"prime_tower_min_volume": { "value": "(layer_height) * (prime_tower_size / 2)**2 * 3 * 0.5 " },
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index fca9e69310..590b8d3f29 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -1664,17 +1664,27 @@
"small_skin_width":
{
"label": "Small Top/Bottom Width",
- "description": "Small top/bottom regions are filled with walls instead of the default top/bottom pattern. This helps to avoids jerky motions.",
- "value": "0",
- "default_value": 0,
+ "description": "Small top/bottom regions are filled with walls instead of the default top/bottom pattern. This helps to avoids jerky motions. Off for the topmost (air-exposed) layer by default (see 'Small Top/Bottom On Surface').",
+ "value": "skin_line_width * 2",
+ "default_value": 1,
"minimum_value": "0",
- "maximum_value_warning": "skin_line_width * 10",
+ "maximum_value_warning": "skin_line_width * 3",
"type": "float",
- "enabled": false,
+ "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true,
- "unit": "mm",
- "comment": "Disabled for 5.4.x, as we're worried about micro-segments in the infill. Also disabled in the engine, so forcing this > 0 will not do anything at the moment."
+ "unit": "mm"
+ },
+ "small_skin_on_surface":
+ {
+ "label": "Small Top/Bottom On Surface",
+ "description": "Enable small (up to 'Small Top/Bottom Width') regions on the topmost skinned layer (exposed to air) to be filled with walls instead of the default pattern.",
+ "value": "False",
+ "default_value": false,
+ "type": "bool",
+ "enabled": "small_skin_width > 0 and top_layers > 0",
+ "limit_to_extruder": "top_bottom_extruder_nr",
+ "settable_per_mesh": true
},
"skin_no_small_gaps_heuristic":
{
@@ -4490,7 +4500,7 @@
"type": "extruder",
"default_value": "0",
"enabled": "(support_enable or support_meshes_present) and extruders_enabled_count > 1",
- "value": "int(defaultExtruderPosition())",
+ "value": "int(anyExtruderWithMaterial('material_is_support_material'))",
"settable_per_mesh": false,
"settable_per_extruder": false,
"children":
@@ -4570,6 +4580,7 @@
},
"enabled": "support_enable",
"default_value": "normal",
+ "resolve": "extruderValue(support_extruder_nr, 'support_structure')",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -5504,7 +5515,9 @@
"unit": "mm",
"type": "float",
"default_value": 0.0,
- "maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
+ "maximum_value": "extruderValue(support_extruder_nr, 'support_offset') if support_structure == 'normal' else None",
+ "minimum_value_warning": "-1 * machine_nozzle_size",
+ "maximum_value_warning": "10 * machine_nozzle_size",
"limit_to_extruder": "support_interface_extruder_nr",
"enabled": "support_interface_enable and (support_enable or support_meshes_present)",
"settable_per_mesh": false,
@@ -5519,7 +5532,9 @@
"type": "float",
"default_value": 0.0,
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_offset')",
- "maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
+ "maximum_value": "extruderValue(support_extruder_nr, 'support_offset') if support_structure == 'normal' else None",
+ "minimum_value_warning": "-1 * machine_nozzle_size",
+ "maximum_value_warning": "10 * machine_nozzle_size",
"limit_to_extruder": "support_roof_extruder_nr",
"enabled": "support_roof_enable and (support_enable or support_meshes_present)",
"settable_per_mesh": false,
@@ -5533,7 +5548,9 @@
"type": "float",
"default_value": 0.0,
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_offset')",
- "maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
+ "maximum_value": "extruderValue(support_extruder_nr, 'support_offset') if support_structure == 'normal' else None",
+ "minimum_value_warning": "-1 * machine_nozzle_size",
+ "maximum_value_warning": "10 * machine_nozzle_size",
"limit_to_extruder": "support_bottom_extruder_nr",
"enabled": "support_bottom_enable and (support_enable or support_meshes_present)",
"settable_per_mesh": false,
@@ -6805,6 +6822,48 @@
"minimum_value_warning": "500",
"maximum_value_warning": "100000",
"settable_per_mesh": true
+ },
+ "meshfix_fluid_motion_enabled":
+ {
+ "label": "Enable Fluid Motion",
+ "description": "When enabled tool paths are corrected for printers with smooth motion planners. Small movements that deviate from the general tool path direction are smoothed to improve fluid motions.",
+ "type": "bool",
+ "default_value": true
+ },
+ "meshfix_fluid_motion_shift_distance":
+ {
+ "label": "Fluid Motion Shift Distance",
+ "description": "Distance points are shifted to smooth the path",
+ "enabled": "meshfix_fluid_motion_enabled",
+ "type": "float",
+ "unit": "mm",
+ "default_value": 0.1,
+ "minimum_value": "0.01",
+ "maximum_value": "1"
+ },
+ "meshfix_fluid_motion_small_distance":
+ {
+ "label": "Fluid Motion Small Distance",
+ "description": "Distance points are shifted to smooth the path",
+ "enabled": "meshfix_fluid_motion_enabled",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 0.01,
+ "minimum_value": "0.01",
+ "maximum_value": "0.1"
+ },
+ "meshfix_fluid_motion_angle":
+ {
+ "label": "Fluid Motion Angle",
+ "description": "If a toolpath-segment deviates more than this angle from the general motion it is smoothed.",
+ "enabled": "meshfix_fluid_motion_enabled",
+ "type": "float",
+ "unit": "\u00b0",
+ "default_value": 15,
+ "maximum_value": "90",
+ "minimum_value": "0",
+ "minimum_value_warning": "1",
+ "maximum_value_warning": "35"
}
}
},
diff --git a/resources/definitions/kingroon_kp3s_pro.def.json b/resources/definitions/kingroon_kp3s_pro.def.json
index 79a4916680..bda5ac03b2 100644
--- a/resources/definitions/kingroon_kp3s_pro.def.json
+++ b/resources/definitions/kingroon_kp3s_pro.def.json
@@ -5,13 +5,14 @@
"metadata":
{
"visible": true,
+ "author": "willuhmjs",
"platform": "kingroon_kp3s.stl",
- "quality_definition": "kingroon_base",
- "author": "willuhmjs"
+ "quality_definition": "kingroon_base"
},
"overrides":
{
"machine_acceleration": { "value": 1000 },
+ "machine_depth": { "default_value": 200 },
"machine_height": { "default_value": 200 },
"machine_max_acceleration_e": { "value": 1000 },
"machine_max_acceleration_x": { "value": 1000 },
@@ -23,7 +24,7 @@
"machine_max_feedrate_z": { "value": 4 },
"machine_max_jerk_xy": { "value": 15 },
"machine_max_jerk_z": { "value": 0.4 },
- "machine_name": { "default_value": "Kingroon KP3S" },
+ "machine_name": { "default_value": "Kingroon KP3S Pro" },
"machine_steps_per_mm_e": { "value": 764 },
"machine_steps_per_mm_x": { "value": 160 },
"machine_steps_per_mm_y": { "value": 160 },
@@ -34,4 +35,4 @@
"retraction_speed": { "value": 40 },
"speed_z_hop": { "value": 4 }
}
-}
+}
\ No newline at end of file
diff --git a/resources/definitions/matterhackers_pulsexe_e444m.def.json b/resources/definitions/matterhackers_pulsexe_e444m.def.json
new file mode 100644
index 0000000000..fc5d4f6dda
--- /dev/null
+++ b/resources/definitions/matterhackers_pulsexe_e444m.def.json
@@ -0,0 +1,60 @@
+{
+ "version": 2,
+ "name": "Pulse XE E-444M",
+ "inherits": "fdmprinter",
+ "metadata":
+ {
+ "visible": true,
+ "author": "Zwitch Guitars",
+ "manufacturer": "MatterHackers",
+ "file_formats": "text/x-gcode",
+ "first_start_actions": [ "MachineSettingsAction" ],
+ "has_machine_quality": false,
+ "has_materials": true,
+ "has_variants": false,
+ "machine_extruder_trains": { "0": "matterhackers_extruder" },
+ "preferred_material": "generic_pla",
+ "preferred_quality_type": "normal"
+ },
+ "overrides":
+ {
+ "adhesion_type": { "value": "skirt" },
+ "cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
+ "cool_min_layer_time": { "value": 10 },
+ "gantry_height": { "value": 23 },
+ "machine_acceleration": { "value": 1300 },
+ "machine_depth": { "default_value": 220 },
+ "machine_end_gcode": { "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y{machine_depth}; home X axis and push Y forward\nG28 Z0\nM84 ; disable motors" },
+ "machine_gcode_flavor": { "default_value": "Marlin" },
+ "machine_head_with_fans_polygon":
+ {
+ "default_value": [
+ [-28, 45],
+ [-28, -18],
+ [40, 45],
+ [40, -18]
+ ]
+ },
+ "machine_heated_bed": { "default_value": true },
+ "machine_height": { "default_value": 215 },
+ "machine_max_feedrate_e": { "value": 75 },
+ "machine_max_feedrate_x": { "value": 300 },
+ "machine_max_feedrate_y": { "value": 300 },
+ "machine_max_feedrate_z": { "value": 30 },
+ "machine_name": { "default_value": "Pulse XE E-444M" },
+ "machine_start_gcode": { "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nG28 ; home axes\nM104 S{material_print_temperature_layer_0} ; set extruder temp\nM140 S{material_bed_temperature_layer_0} ; set bed temp\nM190 S{material_bed_temperature_layer_0} ; wait for bed temp\nM109 S{material_print_temperature_layer_0} ; wait for extruder temp\nG29 ; mesh bed leveling\n\nG92 E0\nG1 X5 Y5 Z0.8 F1800\nG1 X100 Z0.3 E25 F900\nG92 E0\nG1 E-2 F2400" },
+ "machine_steps_per_mm_e": { "value": 415 },
+ "machine_steps_per_mm_x": { "value": 80 },
+ "machine_steps_per_mm_y": { "value": 80 },
+ "machine_steps_per_mm_z": { "value": 400 },
+ "machine_width": { "default_value": 250 },
+ "material_diameter": { "value": 1.75 },
+ "optimize_wall_printing_order": { "value": true },
+ "speed_layer_0": { "value": 20.0 },
+ "speed_print": { "value": 50 },
+ "top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3" },
+ "travel_retract_before_outer_wall": { "value": true },
+ "wall_thickness": { "value": "line_width * 2" },
+ "z_seam_type": { "value": "back" }
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/tizyx_evy.def.json b/resources/definitions/tizyx_evy.def.json
index 41b2b982be..7ae10f5f1d 100644
--- a/resources/definitions/tizyx_evy.def.json
+++ b/resources/definitions/tizyx_evy.def.json
@@ -57,7 +57,7 @@
[25, 49],
[25, -49],
[-25, -49],
- [25, 49]
+ [-25, 49]
]
},
"machine_heated_bed": { "default_value": true },
diff --git a/resources/definitions/tizyx_evy_dual.def.json b/resources/definitions/tizyx_evy_dual.def.json
index 22046a16ff..7ef3aff2ab 100644
--- a/resources/definitions/tizyx_evy_dual.def.json
+++ b/resources/definitions/tizyx_evy_dual.def.json
@@ -54,7 +54,7 @@
[25, 49],
[25, -49],
[-25, -49],
- [25, 49]
+ [-25, 49]
]
},
"machine_heated_bed": { "default_value": true },
diff --git a/resources/definitions/tizyx_k25.def.json b/resources/definitions/tizyx_k25.def.json
index 60005e8712..fbae8a657d 100644
--- a/resources/definitions/tizyx_k25.def.json
+++ b/resources/definitions/tizyx_k25.def.json
@@ -51,7 +51,7 @@
[25, 49],
[25, -49],
[-25, -49],
- [25, 49]
+ [-25, 49]
]
},
"machine_heated_bed": { "default_value": true },
diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json
index 87168d20ae..1669dd5e00 100644
--- a/resources/definitions/ultimaker.def.json
+++ b/resources/definitions/ultimaker.def.json
@@ -111,7 +111,7 @@
"skin_angles": { "value": "[] if infill_pattern not in ['cross', 'cross_3d'] else [20, 110]" },
"skin_edge_support_thickness": { "value": "4 * layer_height if infill_sparse_density < 30 else 0" },
"skin_material_flow": { "value": "0.95 * material_flow" },
- "skin_material_flow_layer_0": { "value": "0.9 * material_flow_layer_0" },
+ "skin_material_flow_layer_0": { "value": "95" },
"skin_monotonic": { "value": "roofing_layer_count == 0" },
"skin_overlap": { "value": "20" },
"speed_equalize_flow_width_factor": { "value": "110.0" },
diff --git a/resources/definitions/ultimaker_s3.def.json b/resources/definitions/ultimaker_s3.def.json
index 10aaabd6a7..eeadc38a8b 100644
--- a/resources/definitions/ultimaker_s3.def.json
+++ b/resources/definitions/ultimaker_s3.def.json
@@ -41,7 +41,7 @@
0
],
"platform_texture": "UltimakerS3backplate.png",
- "preferred_quality_type": "fast",
+ "preferred_quality_type": "draft",
"preferred_variant_name": "AA 0.4",
"supported_actions": [ "DiscoverUM3Action" ],
"supports_material_export": true,
diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json
index 092a16fa6e..16887cfc78 100644
--- a/resources/definitions/ultimaker_s5.def.json
+++ b/resources/definitions/ultimaker_s5.def.json
@@ -38,7 +38,7 @@
-10
],
"platform_texture": "UltimakerS5backplate.png",
- "preferred_quality_type": "fast",
+ "preferred_quality_type": "draft",
"preferred_variant_buildplate_name": "Glass",
"preferred_variant_name": "AA 0.4",
"supported_actions": [ "DiscoverUM3Action" ],
diff --git a/resources/extruders/matterhackers_extruder.def.json b/resources/extruders/matterhackers_extruder.def.json
new file mode 100644
index 0000000000..f05e4b4e20
--- /dev/null
+++ b/resources/extruders/matterhackers_extruder.def.json
@@ -0,0 +1,16 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata":
+ {
+ "machine": "matterhackers_pulsexe_e444m",
+ "position": "0"
+ },
+ "overrides":
+ {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
\ No newline at end of file
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..fb88768bb6
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..e06ccbc3c6
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..9d2ad2a8ca
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..967051c6b6
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..c08c5e37c1
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..e5c66d6b88
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..259e0ef8cb
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..8cb3b60f94
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..0b2c1c3a96
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..9bf56f69a2
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..698fa97fc8
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..d8a435819c
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..e0df1f7d0f
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..63e20e56bd
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..031ab34fa2
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..50545d4be9
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..b65a22fbdc
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..a90a1b971d
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..1cd8170e8f
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..ecf32d17b8
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..47652f89e9
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm_quick.inst.cfg
new file mode 100644
index 0000000000..acbb98ad5e
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+is_experimental = True
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..e2997ae696
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..f5f5a33ca7
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..9ca6216a54
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..a57cbf0af0
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..48ce65c800
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..2c2efb74ac
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..ee1030ccbc
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..c0a6172ac3
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg
new file mode 100644
index 0000000000..a38c9d2e99
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+is_experimental = True
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..60413405bb
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..d2c679ba21
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..5ca0c38d68
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..5db19be11f
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..ae60552513
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..60da5eb917
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..5361dfeb62
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..03a875cef5
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..2e9f8bd87b
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..c4cad5993d
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s3
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..b6b75a5995
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s3
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..f406be1958
--- /dev/null
+++ b/resources/intent/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..3866a4593a
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..908186790e
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..e5eac8992c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..b5834b5757
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..63b0273ba5
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..c8ead2040c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..ec0a92efe7
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..63b4386e2f
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..b0057d80ed
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..00c264aa32
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..da575d938f
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..bd9326793d
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..ea10424026
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..0bb1797b46
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..446f68db01
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..88add2c54c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..0ab18817e0
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..f6b7800386
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..248fee213c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..8de69e1dc3
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..7ad908b8a9
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm_quick.inst.cfg
new file mode 100644
index 0000000000..e578761b73
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+is_experimental = True
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg
new file mode 100644
index 0000000000..b4516e44dd
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = high
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg
new file mode 100644
index 0000000000..dd54779d5d
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg
new file mode 100644
index 0000000000..df0a96e81c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg
new file mode 100644
index 0000000000..5c78ea044d
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_engineering.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 30
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg
new file mode 100644
index 0000000000..5f73432e1c
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm_visual.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+speed_infill = 50
+top_bottom_thickness = 1.05
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..aea6b01bff
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..75d0bf412a
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..d5acb79777
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg
new file mode 100644
index 0000000000..f6506f04d9
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+is_experimental = True
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = intent
+variant = AA 0.4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_print = 150
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =2 * line_width
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..8281aefcf0
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..3e1c36a10e
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..e454a17773
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..ed5a152040
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..57617613a1
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..dac4c2b723
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..9e15b423a2
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..c51d0badf1
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..79e0432210
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg
new file mode 100644
index 0000000000..bf180f24e3
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_engineering.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+definition = ultimaker_s5
+name = Accurate
+version = 4
+
+[metadata]
+intent_category = engineering
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+infill_sparse_density = 20
+jerk_print = 30
+speed_infill = =speed_print
+speed_print = 35
+speed_roofing = =speed_topbottom
+speed_topbottom = =speed_print
+speed_wall = =speed_print
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+top_bottom_thickness = =wall_thickness
+wall_thickness = =line_width * 3
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg
new file mode 100644
index 0000000000..339fcdabdf
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_quick.inst.cfg
@@ -0,0 +1,26 @@
+[general]
+definition = ultimaker_s5
+name = Quick
+version = 4
+
+[metadata]
+intent_category = quick
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = False
+acceleration_wall_0 = 2000
+gradual_infill_step_height = =4 * layer_height
+gradual_infill_steps = 3
+infill_sparse_density = 40
+jerk_print = 30
+jerk_wall_0 = 30
+speed_wall = =speed_print
+speed_wall_0 = 40
+top_bottom_thickness = = 4 * layer_height
+wall_thickness = =wall_line_width_0
+
diff --git a/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg
new file mode 100644
index 0000000000..c448ea51b4
--- /dev/null
+++ b/resources/intent/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm_visual.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Visual
+version = 4
+
+[metadata]
+intent_category = visual
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = intent
+variant = AA 0.8
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
+acceleration_print = 2500
+acceleration_wall_0 = 1000
+inset_direction = inside_out
+jerk_wall_0 = 20
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(35/50))
+speed_wall_0 = =math.ceil(speed_wall*(25/50))
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+
diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml
index 3b75c7699e..65888b3493 100644
--- a/resources/qml/Actions.qml
+++ b/resources/qml/Actions.qml
@@ -41,7 +41,7 @@ Item
property alias deleteAll: deleteAllAction
property alias reloadAll: reloadAllAction
property alias arrangeAll: arrangeAllAction
- property alias arrangeSelection: arrangeSelectionAction
+ property alias arrangeAllGrid: arrangeAllGridAction
property alias resetAllTranslation: resetAllTranslationAction
property alias resetAll: resetAllAction
@@ -60,6 +60,7 @@ Item
property alias showProfileFolder: showProfileFolderAction
property alias documentation: documentationAction
property alias showTroubleshooting: showTroubleShootingAction
+ property alias openSponsershipPage: openSponsershipPageAction
property alias reportBug: reportBugAction
property alias whatsNew: whatsNewAction
property alias about: aboutAction
@@ -90,6 +91,13 @@ Item
text: catalog.i18nc("@action:inmenu", "Show Online Troubleshooting")
}
+ Action
+ {
+ id: openSponsershipPageAction
+ onTriggered: Qt.openUrlExternally("https://ultimaker.com/software/ultimaker-cura/sponsor/")
+ text: catalog.i18nc("@action:inmenu", "Sponsor Cura")
+ }
+
Action
{
id: toggleFullScreenAction
@@ -454,9 +462,10 @@ Item
Action
{
- id: arrangeSelectionAction
- text: catalog.i18nc("@action:inmenu menubar:edit","Arrange Selection")
- onTriggered: Printer.arrangeSelection()
+ id: arrangeAllGridAction
+ text: catalog.i18nc("@action:inmenu menubar:edit","Arrange All Models in a grid")
+ onTriggered: Printer.arrangeAllInGrid()
+ shortcut: "Shift+Ctrl+R"
}
Action
diff --git a/resources/qml/ApplicationSwitcher/ApplicationSwitcherPopup.qml b/resources/qml/ApplicationSwitcher/ApplicationSwitcherPopup.qml
index f13ca28447..a42239056c 100644
--- a/resources/qml/ApplicationSwitcher/ApplicationSwitcherPopup.qml
+++ b/resources/qml/ApplicationSwitcher/ApplicationSwitcherPopup.qml
@@ -57,10 +57,10 @@ Popup
permissionsRequired: []
},
{
- displayName: "UltiMaker Academy", //Not translated, since it's a brand name.
- thumbnail: UM.Theme.getIcon("Knowledge"),
- description: catalog.i18nc("@tooltip:button", "Become a 3D printing expert with UltiMaker e-learning."),
- link: "https://academy.ultimaker.com/?utm_source=cura&utm_medium=software&utm_campaign=switcher-academy",
+ displayName: catalog.i18nc("@label:button", "Sponsor Cura"),
+ thumbnail: UM.Theme.getIcon("Heart"),
+ description: catalog.i18nc("@tooltip:button", "Show your support for Cura with a donation."),
+ link: "https://ultimaker.com/software/ultimaker-cura/sponsor/",
permissionsRequired: []
},
{
diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml
index d85703451f..2de2795a74 100644
--- a/resources/qml/Menus/ContextMenu.qml
+++ b/resources/qml/Menus/ContextMenu.qml
@@ -66,6 +66,7 @@ Cura.Menu
Cura.MenuSeparator {}
Cura.MenuItem { action: Cura.Actions.selectAll }
Cura.MenuItem { action: Cura.Actions.arrangeAll }
+ Cura.MenuItem { action: Cura.Actions.arrangeAllGrid }
Cura.MenuItem { action: Cura.Actions.deleteAll }
Cura.MenuItem { action: Cura.Actions.reloadAll }
Cura.MenuItem { action: Cura.Actions.resetAllTranslation }
@@ -108,9 +109,7 @@ Cura.Menu
height: UM.Theme.getSize("small_popup_dialog").height
minimumWidth: UM.Theme.getSize("small_popup_dialog").width
minimumHeight: UM.Theme.getSize("small_popup_dialog").height
-
- onAccepted: CuraActions.multiplySelection(copiesField.value)
-
+ onAccepted: gridPlacementSelected.checked? CuraActions.multiplySelectionToGrid(copiesField.value) : CuraActions.multiplySelection(copiesField.value)
buttonSpacing: UM.Theme.getSize("thin_margin").width
rightButtons:
@@ -127,28 +126,49 @@ Cura.Menu
}
]
- Row
+ Column
{
- spacing: UM.Theme.getSize("default_margin").width
+ spacing: UM.Theme.getSize("default_margin").height
- UM.Label
+ Row
{
- text: catalog.i18nc("@label", "Number of Copies")
- anchors.verticalCenter: copiesField.verticalCenter
- width: contentWidth
- wrapMode: Text.NoWrap
+ spacing: UM.Theme.getSize("default_margin").width
+
+ UM.Label
+ {
+ text: catalog.i18nc("@label", "Number of Copies")
+ anchors.verticalCenter: copiesField.verticalCenter
+ width: contentWidth
+ wrapMode: Text.NoWrap
+ }
+
+ Cura.SpinBox
+ {
+ id: copiesField
+ editable: true
+ focus: true
+ from: 1
+ to: 99
+ width: 2 * UM.Theme.getSize("button").width
+ value: 1
+ }
}
- Cura.SpinBox
+ UM.CheckBox
{
- id: copiesField
- editable: true
- focus: true
- from: 1
- to: 99
- width: 2 * UM.Theme.getSize("button").width
- value: 1
+ id: gridPlacementSelected
+ text: catalog.i18nc("@label", "Grid Placement")
+
+ UM.ToolTip
+ {
+ visible: parent.hovered
+ targetPoint: Qt.point(parent.x + Math.round(parent.width / 2), parent.y)
+ x: 0
+ y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
+ tooltipText: catalog.i18nc("@info", "Multiply selected item and place them in a grid of build plate.")
+ }
}
+
}
}
}
diff --git a/resources/qml/Menus/HelpMenu.qml b/resources/qml/Menus/HelpMenu.qml
index 4be25fdffe..6a57a99515 100644
--- a/resources/qml/Menus/HelpMenu.qml
+++ b/resources/qml/Menus/HelpMenu.qml
@@ -17,6 +17,7 @@ Cura.Menu
Cura.MenuItem { action: Cura.Actions.showTroubleshooting}
Cura.MenuItem { action: Cura.Actions.documentation }
Cura.MenuItem { action: Cura.Actions.reportBug }
+ Cura.MenuItem { action: Cura.Actions.openSponsershipPage }
Cura.MenuSeparator { }
Cura.MenuItem { action: Cura.Actions.whatsNew }
Cura.MenuItem { action: Cura.Actions.about }
diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml
index 7d8f6b886d..3f0db28058 100644
--- a/resources/qml/Widgets/ScrollableTextArea.qml
+++ b/resources/qml/Widgets/ScrollableTextArea.qml
@@ -4,41 +4,11 @@
import QtQuick 2.10
import QtQuick.Controls 2.3
-import UM 1.5 as UM
+import UM 1.7 as UM
import Cura 1.1 as Cura
-//
-// Cura-style TextArea with scrolls
-//
-Flickable
+// Wrapper to UM.ScrollableTextArea which was originally placed here
+UM.ScrollableTextArea
{
- id: scrollableTextAreaBase
- property bool do_borders: true
- property var back_color: UM.Theme.getColor("main_background")
- property alias textArea: flickableTextArea
-
- ScrollBar.vertical: UM.ScrollBar {}
-
- TextArea.flickable: TextArea
- {
- id: flickableTextArea
-
- background: Rectangle //Providing the background color and border.
- {
- anchors.fill: parent
- anchors.margins: -border.width
-
- color: scrollableTextAreaBase.back_color
- border.color: UM.Theme.getColor("thick_lining")
- border.width: scrollableTextAreaBase.do_borders ? UM.Theme.getSize("default_lining").width : 0
- }
-
- font: UM.Theme.getFont("default")
- color: UM.Theme.getColor("text")
- textFormat: TextEdit.PlainText
- renderType: Text.NativeRendering
- wrapMode: Text.Wrap
- selectByMouse: true
- }
-}
\ No newline at end of file
+}
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.25_um-abs_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-abs_0.1mm.inst.cfg
new file mode 100644
index 0000000000..761ee98519
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-abs_0.1mm.inst.cfg
@@ -0,0 +1,20 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.25_um-petg_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-petg_0.1mm.inst.cfg
new file mode 100644
index 0000000000..1a8de2bc0f
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-petg_0.1mm.inst.cfg
@@ -0,0 +1,23 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+material_print_temperature = =default_material_print_temperature - 5
+speed_infill = =math.ceil(speed_print * 40 / 55)
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.8
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.25_um-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..4d8c8c7d60
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-pla_0.1mm.inst.cfg
@@ -0,0 +1,32 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+brim_width = 8
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = 190
+retraction_hop = 0.2
+speed_print = 30
+speed_wall = =math.ceil(speed_print * 25 / 30)
+speed_wall_0 = =math.ceil(speed_print * 20 / 30)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.72
+travel_avoid_distance = 0.4
+wall_0_inset = 0.015
+wall_0_wipe_dist = 0.25
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.25_um-tough-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-tough-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..13a5ab0a9c
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.25_um-tough-pla_0.1mm.inst.cfg
@@ -0,0 +1,31 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+brim_width = 8
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = =default_material_print_temperature - 15
+speed_print = 30
+speed_topbottom = =math.ceil(speed_print * 20 / 30)
+speed_wall = =math.ceil(speed_print * 25 / 30)
+speed_wall_0 = =math.ceil(speed_print * 20 / 30)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.72
+wall_0_inset = 0.015
+wall_0_wipe_dist = 0.25
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..e908d2de88
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_abs_0.3mm.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = generic_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+prime_tower_enable = False
+raft_airgap = 0.15
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..95aa7481ec
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_petg_0.3mm.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = generic_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm.inst.cfg
new file mode 100644
index 0000000000..19b593834d
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.8
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+material_print_temperature = =default_material_print_temperature + 5
+prime_tower_enable = False
+raft_airgap = 0.15
+speed_infill = =math.ceil(speed_print * 40 / 50)
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 30 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm.inst.cfg
new file mode 100644
index 0000000000..c973d197c7
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.15mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s3
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 15
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm.inst.cfg
new file mode 100644
index 0000000000..200524266b
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.1mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = False
+raft_airgap = 0.15
+speed_infill = =math.ceil(speed_print * 40 / 55)
+speed_print = 55
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm.inst.cfg
new file mode 100644
index 0000000000..e43c821b68
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..2e6a43fa19
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-abs_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 22
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.06mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.06mm.inst.cfg
new file mode 100644
index 0000000000..1b7919bd02
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.06mm.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature - 10
+speed_infill = =math.ceil(speed_print * 40 / 50)
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 30 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm.inst.cfg
new file mode 100644
index 0000000000..fba7878625
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.15mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s3
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm.inst.cfg
new file mode 100644
index 0000000000..afa05aa2cf
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.1mm.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature - 5
+speed_infill = =math.ceil(speed_print * 45 / 55)
+speed_print = 55
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm.inst.cfg
new file mode 100644
index 0000000000..9f31fe8ca9
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..aff44b0ffd
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-petg_0.3mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm.inst.cfg
new file mode 100644
index 0000000000..2939389a3c
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 5
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_prime_speed = =retraction_speed
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 35 / 50)
+speed_wall = =math.ceil(speed_print * 35 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..9edcd27ee9
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..2b430c1afb
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.1mm.inst.cfg
@@ -0,0 +1,25 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_prime_speed = =retraction_speed
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..e24a076814
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..3bbc619504
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-pla_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm.inst.cfg
new file mode 100644
index 0000000000..02a5085655
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 15
+prime_tower_enable = False
+retraction_prime_speed = =retraction_speed
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1.2
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..5686689704
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.15mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..11ef55bdaa
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.1mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 15
+prime_tower_enable = False
+retraction_prime_speed = =retraction_speed
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1.2
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..1a7577b4cc
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..23db0d8882
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.4_um-tough-pla_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm.inst.cfg
new file mode 100644
index 0000000000..58ad241ba6
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..02b6fa9e85
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 22
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 75
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/75))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.4mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.4mm.inst.cfg
new file mode 100644
index 0000000000..18bff1a39a
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-abs_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 25
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/50))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm.inst.cfg
new file mode 100644
index 0000000000..c29079c72d
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.2mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..6c631dc44e
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.3mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 75
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/75))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.4mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.4mm.inst.cfg
new file mode 100644
index 0000000000..d7487d9f2b
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-petg_0.4mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s3
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/50))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..5ad8dddc00
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..274ed54554
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 10
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 65
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/65))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.4mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.4mm.inst.cfg
new file mode 100644
index 0000000000..492cf7580b
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-pla_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 15
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 45
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/45))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..89165618b0
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..7483c994b5
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 10
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 65
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/65))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.4mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.4mm.inst.cfg
new file mode 100644
index 0000000000..99695ec519
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_aa0.8_um-tough-pla_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s3
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 15
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 45
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/45))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..300e2ebaed
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Normal - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = CC 0.4
+weight = -1
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..84040ede4e
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_cc0.4_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = CC 0.4
+weight = -2
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..e7b72d6cd0
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Normal - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = CC 0.6
+weight = -1
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..38c857de5e
--- /dev/null
+++ b/resources/quality/ultimaker_s3/um_s3_cc0.6_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s3
+name = Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = CC 0.6
+weight = -2
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_um-abs_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-abs_0.1mm.inst.cfg
new file mode 100644
index 0000000000..e4b42e7587
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-abs_0.1mm.inst.cfg
@@ -0,0 +1,20 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_um-petg_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-petg_0.1mm.inst.cfg
new file mode 100644
index 0000000000..42f2bf5d16
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-petg_0.1mm.inst.cfg
@@ -0,0 +1,23 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+material_print_temperature = =default_material_print_temperature - 5
+speed_infill = =math.ceil(speed_print * 40 / 55)
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.8
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_um-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..e282ec5eab
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-pla_0.1mm.inst.cfg
@@ -0,0 +1,32 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+brim_width = 8
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = 190
+retraction_hop = 0.2
+speed_print = 30
+speed_wall = =math.ceil(speed_print * 25 / 30)
+speed_wall_0 = =math.ceil(speed_print * 20 / 30)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.72
+travel_avoid_distance = 0.4
+wall_0_inset = 0.015
+wall_0_wipe_dist = 0.25
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_um-tough-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-tough-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..7eb277b007
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_um-tough-pla_0.1mm.inst.cfg
@@ -0,0 +1,31 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.25
+weight = 0
+
+[values]
+brim_width = 8
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = =default_material_print_temperature - 15
+speed_print = 30
+speed_topbottom = =math.ceil(speed_print * 20 / 30)
+speed_wall = =math.ceil(speed_print * 25 / 30)
+speed_wall_0 = =math.ceil(speed_print * 20 / 30)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 0.72
+wall_0_inset = 0.015
+wall_0_wipe_dist = 0.25
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..6063b995cd
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_abs_0.3mm.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = generic_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+prime_tower_enable = False
+raft_airgap = 0.15
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..1b502797ab
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_petg_0.3mm.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = generic_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm.inst.cfg
new file mode 100644
index 0000000000..eeabba9298
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.8
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+material_print_temperature = =default_material_print_temperature + 5
+prime_tower_enable = False
+raft_airgap = 0.15
+speed_infill = =math.ceil(speed_print * 40 / 50)
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 30 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm.inst.cfg
new file mode 100644
index 0000000000..016273511a
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.15mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s5
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 15
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm.inst.cfg
new file mode 100644
index 0000000000..510e761bbe
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.1mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 20
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = False
+raft_airgap = 0.15
+speed_infill = =math.ceil(speed_print * 40 / 55)
+speed_print = 55
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm.inst.cfg
new file mode 100644
index 0000000000..ce83812064
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..6a62cff48e
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-abs_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 22
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.06mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.06mm.inst.cfg
new file mode 100644
index 0000000000..9545d34977
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.06mm.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature - 10
+speed_infill = =math.ceil(speed_print * 40 / 50)
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 30 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm.inst.cfg
new file mode 100644
index 0000000000..ad8de06a25
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.15mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s5
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm.inst.cfg
new file mode 100644
index 0000000000..4a20bd76b3
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.1mm.inst.cfg
@@ -0,0 +1,27 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature - 5
+speed_infill = =math.ceil(speed_print * 45 / 55)
+speed_print = 55
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm.inst.cfg
new file mode 100644
index 0000000000..712b01db7c
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..d6da9b758f
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-petg_0.3mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm.inst.cfg
new file mode 100644
index 0000000000..c2bb123d04
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 5
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_prime_speed = =retraction_speed
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 35 / 50)
+speed_wall = =math.ceil(speed_print * 35 / 50)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..97bbfc43f7
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..1e2820f565
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.1mm.inst.cfg
@@ -0,0 +1,25 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_prime_speed = =retraction_speed
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..123ec0c576
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..c72c3ad17e
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-pla_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 12
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm.inst.cfg
new file mode 100644
index 0000000000..d195d3c40f
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.06mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = high
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 1
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 15
+prime_tower_enable = False
+retraction_prime_speed = =retraction_speed
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1.2
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..c284eb48e9
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.15mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Normal
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -1
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm.inst.cfg
new file mode 100644
index 0000000000..38b2142353
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.1mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Fine
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = normal
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = 0
+
+[values]
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature - 15
+prime_tower_enable = False
+retraction_prime_speed = =retraction_speed
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = 1.2
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..b54ca471b0
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.2mm.inst.cfg
@@ -0,0 +1,76 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+material_print_temperature = =default_material_print_temperature + 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..25f0a22fbe
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_um-tough-pla_0.3mm.inst.cfg
@@ -0,0 +1,78 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.4
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_max_flowrate = 14
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = False
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_bottom_distance = =support_z_distance
+support_interface_enable = True
+support_structure = tree
+support_top_distance = =support_z_distance
+support_z_distance = =math.ceil(0.3/layer_height)*layer_height
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm.inst.cfg
new file mode 100644
index 0000000000..6df6b8c747
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 20
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.3mm.inst.cfg
new file mode 100644
index 0000000000..c0f7c1d90e
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 22
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 75
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/75))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.4mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.4mm.inst.cfg
new file mode 100644
index 0000000000..a82db91177
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-abs_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_abs
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,8
+material_flow = 93
+material_max_flowrate = 22
+material_print_temperature = =default_material_print_temperature + 25
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.15
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/50))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm.inst.cfg
new file mode 100644
index 0000000000..78584e7c44
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.2mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.3mm.inst.cfg
new file mode 100644
index 0000000000..d6c503a8a7
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.3mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 75
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/75))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.4mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.4mm.inst.cfg
new file mode 100644
index 0000000000..6f1c83fe74
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-petg_0.4mm.inst.cfg
@@ -0,0 +1,74 @@
+[general]
+definition = ultimaker_s5
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_petg
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 4
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,4
+machine_nozzle_heat_up_speed = 1,7
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 23
+material_print_temperature = =default_material_print_temperature - 5
+optimize_wall_printing_order = False
+prime_tower_enable = True
+retraction_amount = 8
+retraction_prime_speed = 15
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 50
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/50))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1.2 , layer_height * 6)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..9bb022693c
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..46ebe6c961
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 10
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 65
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/65))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.4mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.4mm.inst.cfg
new file mode 100644
index 0000000000..32d74d9418
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-pla_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_pla
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 15
+material_print_temperature = =default_material_print_temperature + 15
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 45
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/45))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..b87fa10da1
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.2mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -2
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 10
+meshfix_maximum_resolution = 0.7
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 100
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/100))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.3mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.3mm.inst.cfg
new file mode 100644
index 0000000000..12e49dc993
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.3mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Extra Fast
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = verydraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -3
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 10
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 65
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/65))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.4mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.4mm.inst.cfg
new file mode 100644
index 0000000000..0e041dfe8d
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_um-tough-pla_0.4mm.inst.cfg
@@ -0,0 +1,75 @@
+[general]
+definition = ultimaker_s5
+name = Sprint
+version = 4
+
+[metadata]
+material = ultimaker_tough_pla
+quality_type = superdraft
+setting_version = 22
+type = quality
+variant = AA 0.8
+weight = -4
+
+[values]
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_discretisation_step_size = 0.2
+_plugin__curaenginegradualflow__0_1_0__gradual_flow_enabled = True
+_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 2
+acceleration_infill = =acceleration_print
+acceleration_ironing = 1000
+acceleration_layer_0 = =acceleration_wall_0
+acceleration_print = 3500
+acceleration_roofing = =acceleration_wall_0
+acceleration_topbottom = =acceleration_wall
+acceleration_wall = =acceleration_infill
+acceleration_wall_0 = 1500
+acceleration_wall_x = =acceleration_wall
+bridge_skin_speed = =bridge_wall_speed
+bridge_sparse_infill_max_density = 50
+bridge_wall_speed = 30
+cool_min_layer_time = 6
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'grid'
+infill_sparse_density = 15
+jerk_infill = =jerk_print
+jerk_layer_0 = =jerk_wall_0
+jerk_print = =max(30, speed_print/2)
+jerk_roofing = =jerk_wall_0
+jerk_topbottom = =jerk_wall
+jerk_wall = =jerk_infill
+jerk_wall_0 = =max(30, speed_wall_0/2)
+machine_nozzle_cool_down_speed = 1,3
+machine_nozzle_heat_up_speed = 1,9
+material_extrusion_cool_down_speed = 0,7
+material_flow = 93
+material_max_flowrate = 17
+material_print_temperature = =default_material_print_temperature + 15
+optimize_wall_printing_order = False
+prime_tower_enable = True
+raft_airgap = 0.25
+retraction_amount = 4
+retraction_prime_speed = =retraction_speed
+retraction_speed = 45
+skin_no_small_gaps_heuristic = True
+small_skin_on_surface = False
+small_skin_width = 4
+speed_infill = =speed_print
+speed_ironing = 20
+speed_layer_0 = =speed_roofing
+speed_prime_tower = =speed_wall_0
+speed_print = 45
+speed_roofing = =math.ceil(speed_wall*(45/100))
+speed_support_interface = =speed_wall_0
+speed_topbottom = =speed_print
+speed_wall = =speed_infill
+speed_wall_0 = =math.ceil(speed_wall*(35/45))
+speed_wall_x = =speed_wall
+support_angle = 70
+support_interface_enable = False
+support_structure = tree
+top_bottom_thickness = =max(1 , layer_height * 5)
+wall_0_wipe_dist = 0.8
+wall_line_width_0 = =line_width * (1 + magic_spiralize * 0.25)
+z_seam_relative = True
+z_seam_type = back
+zig_zaggify_infill = True
+
diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..1204be4c15
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Normal - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = CC 0.4
+weight = -1
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..6a7d52af4b
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_cc0.4_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = CC 0.4
+weight = -2
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.15mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.15mm.inst.cfg
new file mode 100644
index 0000000000..5bf5d910e8
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.15mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Normal - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = fast
+setting_version = 22
+type = quality
+variant = CC 0.6
+weight = -1
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.2mm.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.2mm.inst.cfg
new file mode 100644
index 0000000000..21407b6e66
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_um-pla_0.2mm.inst.cfg
@@ -0,0 +1,29 @@
+[general]
+definition = ultimaker_s5
+name = Fast - Experimental
+version = 4
+
+[metadata]
+is_experimental = True
+material = ultimaker_pla
+quality_type = draft
+setting_version = 22
+type = quality
+variant = CC 0.6
+weight = -2
+
+[values]
+gradual_infill_step_height = =3 * layer_height
+infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
+machine_nozzle_cool_down_speed = 0.75
+machine_nozzle_heat_up_speed = 1.6
+material_print_temperature = =default_material_print_temperature + 10
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+speed_wall_x = =speed_wall
+support_angle = 70
+top_bottom_thickness = =layer_height * 4
+
diff --git a/resources/setting_visibility/advanced.cfg b/resources/setting_visibility/advanced.cfg
index a744c8eae8..c3451d2c98 100644
--- a/resources/setting_visibility/advanced.cfg
+++ b/resources/setting_visibility/advanced.cfg
@@ -34,6 +34,8 @@ bottom_thickness
bottom_layers
ironing_enabled
skin_monotonic
+small_skin_width
+small_skin_on_surface
[infill]
infill_extruder_nr
diff --git a/resources/setting_visibility/expert.cfg b/resources/setting_visibility/expert.cfg
index 6517728968..5388681e8f 100644
--- a/resources/setting_visibility/expert.cfg
+++ b/resources/setting_visibility/expert.cfg
@@ -60,6 +60,7 @@ skin_monotonic
connect_skin_polygons
skin_angles
small_skin_width
+small_skin_on_surface
skin_no_small_gaps_heuristic
skin_outline_count
ironing_enabled
@@ -365,6 +366,10 @@ multiple_mesh_overlap
carve_multiple_volumes
alternate_carve_order
remove_empty_first_layers
+meshfix_fluid_motion_enabled
+meshfix_fluid_motion_shift_distance
+meshfix_fluid_motion_small_distance
+meshfix_fluid_motion_angle
[blackmagic]
print_sequence
diff --git a/resources/themes/cura-light/icons/default/Heart.svg b/resources/themes/cura-light/icons/default/Heart.svg
new file mode 100644
index 0000000000..793dcbd6b5
--- /dev/null
+++ b/resources/themes/cura-light/icons/default/Heart.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.2.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.2.inst.cfg
new file mode 100644
index 0000000000..4d0858a573
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.2.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.2mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.2
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.3.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.3.inst.cfg
new file mode 100644
index 0000000000..e127a63c76
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.3.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.3mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.3
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.4.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.4.inst.cfg
new file mode 100644
index 0000000000..3422da8b90
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.4.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.4mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.4
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.5.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.5.inst.cfg
new file mode 100644
index 0000000000..744e7e441d
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.5.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.5mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.5
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.6.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.6.inst.cfg
new file mode 100644
index 0000000000..289eb3bd96
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.6.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.6mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.6
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_0.8.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_0.8.inst.cfg
new file mode 100644
index 0000000000..68aa6dc7da
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_0.8.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 0.8mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 0.8
+
diff --git a/resources/variants/kingroon/kingroon_kp3s_pro_1.0.inst.cfg b/resources/variants/kingroon/kingroon_kp3s_pro_1.0.inst.cfg
new file mode 100644
index 0000000000..5e332ea26b
--- /dev/null
+++ b/resources/variants/kingroon/kingroon_kp3s_pro_1.0.inst.cfg
@@ -0,0 +1,13 @@
+[general]
+definition = kingroon_kp3s_pro
+name = 1.0mm Nozzle
+version = 4
+
+[metadata]
+hardware_type = nozzle
+setting_version = 22
+type = variant
+
+[values]
+machine_nozzle_size = 1.0
+