diff --git a/.doxygen b/.doxygen
index fb8ae5f045..d557f6ba85 100644
--- a/.doxygen
+++ b/.doxygen
@@ -48,7 +48,7 @@ PROJECT_NAME = OrcaSlicer
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.6.3
+PROJECT_NUMBER = latest
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -68,7 +68,7 @@ PROJECT_LOGO = ./resources/images/OrcaSlicer_32px.png
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
-OUTPUT_DIRECTORY = ../
+OUTPUT_DIRECTORY = .
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
# sub-directories (in 2 levels) under the output directory of each output format
@@ -1059,7 +1059,11 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
-EXCLUDE_PATTERNS =
+EXCLUDE_PATTERNS = */deps/*
+EXCLUDE_PATTERNS = */build/*
+EXCLUDE_PATTERNS = */deps_src/*
+
+
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1286,7 +1290,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_OUTPUT = OrcaSlicer_Dev_Document
+HTML_OUTPUT = internal_docs
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
@@ -1565,7 +1569,7 @@ TOC_EXPAND = NO
# protocol see https://www.sitemaps.org
# This tag requires that the tag GENERATE_HTML is set to YES.
-SITEMAP_URL =
+SITEMAP_URL = internals.orcaslicer.com
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml
index 1e944a7667..41d489d4d8 100644
--- a/.github/workflows/build_all.yml
+++ b/.github/workflows/build_all.yml
@@ -48,17 +48,16 @@ concurrency:
jobs:
- build_linux: # Separate so unit tests can wait on just Linux builds to complete.
+ build_linux:
name: Build Linux
strategy:
fail-fast: false
# Don't run scheduled builds on forks:
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
- uses: ./.github/workflows/build_deps.yml
+ uses: ./.github/workflows/build_check_cache.yml
with:
os: ubuntu-24.04
build-deps-only: ${{ inputs.build-deps-only || false }}
- force-build: ${{ github.event_name == 'schedule' }}
secrets: inherit
build_all:
name: Build Non-Linux
@@ -71,7 +70,7 @@ jobs:
arch: arm64
# Don't run scheduled builds on forks:
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
- uses: ./.github/workflows/build_deps.yml
+ uses: ./.github/workflows/build_check_cache.yml
with:
os: ${{ matrix.os }}
arch: ${{ matrix.arch }}
@@ -94,7 +93,7 @@ jobs:
- name: Apt-Install Dependencies
uses: ./.github/actions/apt-install-deps
- name: Restore Test Artifact
- uses: actions/download-artifact@v6
+ uses: actions/download-artifact@v7
with:
name: ${{ github.sha }}-tests
- uses: lukka/get-cmake@latest
@@ -106,14 +105,14 @@ jobs:
tar -xvf build_tests.tar
scripts/run_unit_tests.sh
- name: Upload Test Logs
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
if: ${{ failure() }}
with:
name: unit-test-logs
path: build/tests/**/*.log
- name: Publish Test Results
if: always()
- uses: EnricoMi/publish-unit-test-result-action/linux@v2
+ uses: EnricoMi/publish-unit-test-result-action@v2
with:
files: "ctest_results.xml"
flatpak:
@@ -170,7 +169,7 @@ jobs:
arch: ${{ matrix.variant.arch }}
upload-artifact: false
- name: Upload artifacts Flatpak
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak
path: '/__w/OrcaSlicer/OrcaSlicer/OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak'
diff --git a/.github/workflows/build_check_cache.yml b/.github/workflows/build_check_cache.yml
new file mode 100644
index 0000000000..fee5a6e955
--- /dev/null
+++ b/.github/workflows/build_check_cache.yml
@@ -0,0 +1,62 @@
+name: Check Cache
+
+on:
+ workflow_call:
+ inputs:
+ os:
+ required: true
+ type: string
+ arch:
+ required: false
+ type: string
+ build-deps-only:
+ required: false
+ type: boolean
+ force-build:
+ required: false
+ type: boolean
+
+jobs:
+ check_cache: # determines if there is a cache and outputs variables used in caching process
+ name: Check Cache
+ runs-on: ${{ inputs.os }}
+ outputs:
+ cache-key: ${{ steps.set_outputs.outputs.cache-key }}
+ cache-path: ${{ steps.set_outputs.outputs.cache-path }}
+ valid-cache: ${{ steps.cache_deps.outputs.cache-hit }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ lfs: 'true'
+
+ - name: set outputs
+ id: set_outputs
+ env:
+ dep-folder-name: ${{ inputs.os != 'macos-14' && '/OrcaSlicer_dep' || '' }}
+ output-cmd: ${{ inputs.os == 'windows-latest' && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}}
+ run: |
+ echo cache-key=${{ inputs.os }}-cache-orcaslicer_deps-build-${{ hashFiles('deps/**') }} >> ${{ env.output-cmd }}
+ echo cache-path=${{ github.workspace }}/deps/build${{ env.dep-folder-name }} >> ${{ env.output-cmd }}
+
+ - name: load cache
+ id: cache_deps
+ uses: actions/cache@v5
+ with:
+ path: ${{ steps.set_outputs.outputs.cache-path }}
+ key: ${{ steps.set_outputs.outputs.cache-key }}
+ lookup-only: true
+
+ build_deps: # call next step
+ name: Build Deps
+ needs: [check_cache]
+ uses: ./.github/workflows/build_deps.yml
+ with:
+ cache-key: ${{ needs.check_cache.outputs.cache-key }}
+ cache-path: ${{ needs.check_cache.outputs.cache-path }}
+ valid-cache: ${{ needs.check_cache.outputs.valid-cache == 'true' }}
+ os: ${{ inputs.os }}
+ arch: ${{ inputs.arch }}
+ build-deps-only: ${{ inputs.build-deps-only }}
+ force-build: ${{ inputs.force-build }}
+ secrets: inherit
diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml
index 045f9f7f2a..6cec66f24b 100644
--- a/.github/workflows/build_deps.yml
+++ b/.github/workflows/build_deps.yml
@@ -1,6 +1,15 @@
on:
workflow_call:
inputs:
+ cache-key:
+ required: true
+ type: string
+ cache-path:
+ required: true
+ type: string
+ valid-cache:
+ required: true
+ type: boolean
os:
required: true
type: string
@@ -17,62 +26,55 @@ on:
jobs:
build_deps:
name: Build Deps
+ if: ${{ !cancelled() && (inputs.build-deps-only || inputs.force-build || inputs.valid-cache != true) }}
runs-on: ${{ inputs.os }}
- outputs:
- artifact-name: ${{ env.ARTIFACT_NAME }}
- artifact-path: ${{ env.DEPS_PATH }}
env:
- DO_BUILD: ${{ inputs.build-deps-only || inputs.force-build }}
- DEPS_PATH: ${{ github.workspace }}/deps/build${{ inputs.os != 'macos-14' && '/OrcaSlicer_dep' || '' }}
- ARTIFACT_NAME: OrcaSlicer_dep_${{ inputs.os }}_${{ inputs.arch }}
+ date:
steps:
+
+ # Setup the environment
- name: Checkout
uses: actions/checkout@v6
with:
lfs: 'true'
- # Cached deps are just the final outputs, no intermediate files.
- # So building XOR cache loading.
- # We use `lookup-only` to skip pulling cache.
- name: load cached deps
- uses: actions/cache/restore@v4
- id: cache-load
+ uses: actions/cache@v5
with:
- path: ${{ env.DEPS_PATH }}
- key: ${{ inputs.os }}-${{ inputs.arch }}-cache-orcaslicer_deps-build-${{ hashFiles('deps/**') }}
- lookup-only: ${{ env.DO_BUILD == 'true' }} # Doing this instead of `if` preserves the outputs of this step
+ path: ${{ inputs.cache-path }}
+ key: ${{ inputs.cache-key }}
- uses: lukka/get-cmake@latest
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') }}
with:
cmakeVersion: "~3.28.0" # use most recent 3.28.x version
- name: setup dev on Windows
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os == 'windows-latest' }}
+ if: inputs.os == 'windows-latest'
uses: microsoft/setup-msbuild@v2
- name: Get the date on Ubuntu and macOS
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os != 'windows-latest' }}
+ if: inputs.os != 'windows-latest'
run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_ENV
shell: bash
- name: Get the date on Windows
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os == 'windows-latest' }}
+ if: inputs.os == 'windows-latest'
run: echo "date=$(Get-Date -Format 'yyyyMMdd')" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
shell: pwsh
+
+ # Build Dependencies
- name: Build on Windows
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os == 'windows-latest' }}
+ if: inputs.os == 'windows-latest'
working-directory: ${{ github.workspace }}
run: |
choco install strawberryperl
.\build_release_vs.bat deps
+ .\build_release_vs.bat pack
+ cd ${{ github.workspace }}/deps/build
- # Windows and Linux don't need to delete any directories, because they only package up deps/build/OrcaSlicer_dep.
- # But Mac has multiple and we're preserving their directory structure relationship.
- # So the garbage siblings of OrcaSlicer_dep can be deleted to save artifact and cache space.
- name: Build on Mac ${{ inputs.arch }}
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os == 'macos-14' }}
+ if: inputs.os == 'macos-14'
working-directory: ${{ github.workspace }}
run: |
brew install automake texinfo libtool
@@ -85,40 +87,53 @@ jobs:
done
brew install zstd
+
- name: Apt-Install Dependencies
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && inputs.os == 'ubuntu-24.04' }}
+ if: inputs.os == 'ubuntu-24.04'
uses: ./.github/actions/apt-install-deps
- name: Build on Ubuntu
- if: ${{ !cancelled() && (env.DO_BUILD == 'true' || steps.cache-load.outputs.cache-hit != 'true') && (inputs.os == 'ubuntu-20.04' || inputs.os == 'ubuntu-24.04') }}
+ if: inputs.os == 'ubuntu-20.04' || inputs.os == 'ubuntu-24.04'
working-directory: ${{ github.workspace }}
run: |
+ mkdir -p ${{ github.workspace }}/deps/build/destdir
./build_linux.sh -dr
+ cd deps/build
+ tar -czvf OrcaSlicer_dep_ubuntu_$(date +"%Y%m%d").tar.gz destdir
- - name: Upload OrcaSlicer_dep director(ies) for use later
- if: ${{ !cancelled() && ! env.ACT}}
- uses: actions/upload-artifact@v5
- with:
- name: ${{ env.ARTIFACT_NAME }}
- path: ${{ env.DEPS_PATH }}
- retention-days: 10 # It's not too big, but we don't need it for a very long time.
- if-no-files-found: error
- - name: Save cache from main branch
- if: ${{ !cancelled() && github.ref == 'refs/heads/main' && steps.cache-load.outputs.cache-hit != 'true' }}
- uses: actions/cache/save@v4
+ # Upload Artifacts
+ # - name: Upload Mac ${{ inputs.arch }} artifacts
+ # if: inputs.os == 'macos-14'
+ # uses: actions/upload-artifact@v6
+ # with:
+ # name: OrcaSlicer_dep_mac_${{ env.date }}
+ # path: ${{ github.workspace }}/deps/build/OrcaSlicer_dep*.tar.gz
+
+ - name: Upload Windows artifacts
+ if: inputs.os == 'windows-latest'
+ uses: actions/upload-artifact@v6
with:
- path: ${{ env.DEPS_PATH }}
- key: ${{ steps.cache-load.outputs.cache-primary-key }}
+ name: OrcaSlicer_dep_win64_${{ env.date }}
+ path: ${{ github.workspace }}/deps/build/OrcaSlicer_dep*.zip
+
+ - name: Upload Ubuntu artifacts
+ if: ${{ ! env.ACT && inputs.os == 'ubuntu-20.04' || inputs.os == 'ubuntu-24.04' }}
+ env:
+ ubuntu-ver: ${{ (inputs.os == 'ubuntu-20.04' && '2004') || (inputs.os == 'ubuntu-24.04' && '2404') || '' }}
+ uses: actions/upload-artifact@v6
+ with:
+ name: OrcaSlicer_dep_ubuntu_${{ env.ubuntu-ver }}_${{ env.date }}
+ path: ${{ github.workspace }}/deps/build/OrcaSlicer_dep_ubuntu_*.tar.gz
build_orca:
name: Build OrcaSlicer
needs: [build_deps]
- if: ${{ !cancelled() && (!inputs.build-deps-only || inputs.force-build) }}
+ if: ${{ !cancelled() && !inputs.build-deps-only && (inputs.force-build || (inputs.valid-cache == true && needs.build_deps.result == 'skipped') || (inputs.valid-cache != true && success())) }}
uses: ./.github/workflows/build_orca.yml
with:
- artifact-name: ${{ needs.build_deps.outputs.artifact-name }}
- artifact-path: ${{ needs.build_deps.outputs.artifact-path }}
+ cache-key: ${{ inputs.cache-key }}
+ cache-path: ${{ inputs.cache-path }}
os: ${{ inputs.os }}
arch: ${{ inputs.arch }}
secrets: inherit
diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml
index 986ac4059c..131766e49e 100644
--- a/.github/workflows/build_orca.yml
+++ b/.github/workflows/build_orca.yml
@@ -1,10 +1,10 @@
on:
workflow_call:
inputs:
- artifact-name:
+ cache-key:
required: true
type: string
- artifact-path:
+ cache-path:
required: true
type: string
os:
@@ -30,11 +30,12 @@ jobs:
with:
lfs: 'true'
- - name: Download deps artifacts
- uses: actions/download-artifact@v4
+ - name: load cached deps
+ uses: actions/cache@v5
with:
- name: ${{ inputs.artifact-name }}
- path: ${{ inputs.artifact-path }}
+ path: ${{ inputs.cache-path }}
+ key: ${{ inputs.cache-key }}
+ fail-on-cache-miss: true
- uses: lukka/get-cmake@latest
with:
@@ -180,14 +181,14 @@ jobs:
- name: Upload artifacts mac
if: inputs.os == 'macos-14'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_Mac_universal_${{ env.ver }}
path: ${{ github.workspace }}/OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
- name: Upload OrcaSlicer_profile_validator DMG mac
if: inputs.os == 'macos-14'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_profile_validator_Mac_universal_DMG_${{ env.ver }}
path: ${{ github.workspace }}/OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
@@ -254,28 +255,28 @@ jobs:
- name: Upload artifacts Win zip
if: inputs.os == 'windows-latest'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_Windows_${{ env.ver }}_portable
path: ${{ github.workspace }}/build/OrcaSlicer
- name: Upload artifacts Win installer
if: inputs.os == 'windows-latest'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_Windows_${{ env.ver }}
path: ${{ github.workspace }}/build/OrcaSlicer*.exe
- name: Upload artifacts Win PDB
if: inputs.os == 'windows-latest'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: PDB
path: ${{ github.workspace }}/build/src/Release/Debug_PDB_${{ env.ver }}_for_developers_only.7z
- name: Upload OrcaSlicer_profile_validator Win
if: inputs.os == 'windows-latest'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_profile_validator_Windows_${{ env.ver }}
path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe
@@ -335,7 +336,7 @@ jobs:
# and doesn't preserve file permissions
- name: Upload Test Artifact
if: inputs.os == 'ubuntu-24.04'
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: ${{ github.sha }}-tests
overwrite: true
@@ -357,7 +358,7 @@ jobs:
env:
ubuntu-ver: ${{ (inputs.os == 'ubuntu-20.04' && '2004') || (inputs.os == 'ubuntu-24.04' && '2404') || '' }}
ubuntu-ver-str: ${{ (inputs.os == 'ubuntu-24.04' && '_Ubuntu2404') || '' }}
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_Linux_ubuntu_${{ env.ubuntu-ver }}_${{ env.ver }}
path: './build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_${{ env.ver }}.AppImage'
@@ -366,7 +367,7 @@ jobs:
if: ${{ ! env.ACT && inputs.os == 'ubuntu-20.04' || inputs.os == 'ubuntu-24.04' }}
env:
ubuntu-ver: ${{ (inputs.os == 'ubuntu-20.04' && '2004') || (inputs.os == 'ubuntu-24.04' && '2404') || '' }}
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: OrcaSlicer_profile_validator_Linux_ubuntu_${{ env.ubuntu-ver }}_${{ env.ver }}
path: './build/src/Release/OrcaSlicer_profile_validator'
diff --git a/.github/workflows/doxygen-docs.yml b/.github/workflows/doxygen-docs.yml
new file mode 100644
index 0000000000..f30c3e0d0e
--- /dev/null
+++ b/.github/workflows/doxygen-docs.yml
@@ -0,0 +1,78 @@
+name: Generate Doxygen Documentation
+
+on:
+ schedule:
+ - cron: '0 0 * * 1' # Every Monday at midnight UTC
+ workflow_dispatch: # Manual trigger
+
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build-and-deploy:
+ name: Build and Deploy Docs
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ # Only run on main branch of the main repository
+ if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main'
+ permissions:
+ contents: read
+ steps:
+ - uses: thejerrybao/setup-swap-space@v1
+ with:
+ swap-space-path: /swapfile
+ swap-size-gb: 8
+ remove-existing-swap-files: true
+
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Install Doxygen and Graphviz
+ run: |
+ set -euo pipefail
+ sudo apt-get update
+ sudo apt-get install -y doxygen graphviz
+
+ - name: Generate documentation
+ run: |
+ set -euo pipefail
+ # Override DOT_NUM_THREADS to avoid parallel dot race condition bug
+ sed -i 's/^DOT_NUM_THREADS.*/DOT_NUM_THREADS = 1/' .doxygen
+ doxygen .doxygen
+ # Verify documentation was generated
+ if [ ! -f "internal_docs/index.html" ]; then
+ echo "Error: Documentation generation failed - index.html not found"
+ exit 1
+ fi
+ - name: Install Rclone
+ run: |
+ set -euo pipefail
+ sudo -v
+ curl -fsSL https://rclone.org/install.sh | sudo bash
+
+ - name: optimize
+ run: |
+ set -euo pipefail
+ rm -f internal_docs/Nodes.xml internal_docs/Tokens.xml
+ find internal_docs -name "*.map" -type f -delete || true
+ find internal_docs -name "*.md5" -type f -delete || true
+
+ - name: upload
+ # We configure rclone dynamically using environment variables
+ run: |
+ set -euo pipefail
+ # Remove existing config if it exists to avoid conflicts
+ rclone config delete cloudflare 2>/dev/null || true
+ rclone config create cloudflare s3 \
+ provider Cloudflare \
+ access_key_id ${{ secrets.R2_ACCESS_KEY_ID }} \
+ secret_access_key ${{ secrets.R2_SECRET_ACCESS_KEY }} \
+ endpoint ${{ secrets.R2_ENDPOINT }}
+
+ rclone sync internal_docs/ cloudflare:orcaslicer-internals \
+ --progress \
+ --transfers 512 \
+ --checkers 512
+
+ echo "Documentation upload completed successfully"
\ No newline at end of file
diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml
index 336636bbcc..d5fe5a35d2 100644
--- a/.github/workflows/shellcheck.yml
+++ b/.github/workflows/shellcheck.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Cache shellcheck download
id: cache-shellcheck-v0_11
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ~/shellcheck
key: ${{ runner.os }}-shellcheck-v0_11
diff --git a/.gitignore b/.gitignore
index 09abcc8dee..5b369a47fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ deps_src/build/
test.js
/.cache/
.clangd
+internal_docs/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 162763621c..041c7b17cf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "4.0")
+ set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "" FORCE)
+endif()
+
cmake_minimum_required(VERSION 3.13)
# Verify that your CMake version is exactly 3.5 series or higher on windows
@@ -571,6 +575,7 @@ endif()
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()
+set(Boost_NO_SYSTEM_PATHS TRUE)
find_package(Boost 1.83.0 REQUIRED COMPONENTS system filesystem thread log log_setup locale regex chrono atomic date_time iostreams program_options nowide)
add_library(boost_libs INTERFACE)
@@ -688,6 +693,10 @@ find_package(PNG REQUIRED)
set(OpenGL_GL_PREFERENCE "LEGACY")
find_package(OpenGL REQUIRED)
+if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set(OPENGL_LIBRARIES "-framework OpenGL" CACHE STRING "OpenGL framework" FORCE)
+endif()
+
set(GLEW_ROOT "${CMAKE_PREFIX_PATH}")
message("GLEW_ROOT: ${GLEW_ROOT}")
# Find glew or use bundled version
diff --git a/README.md b/README.md
index 59fb76034b..afd418ea0a 100644
--- a/README.md
+++ b/README.md
@@ -44,19 +44,19 @@ If you come across any of these in search results, please report them as
# Main features
-- **[Advanced Calibration Tools](https://github.com/OrcaSlicer/OrcaSlicer/wiki/Calibration)**
+- **[Advanced Calibration Tools](https://www.orcaslicer.com/wiki/Calibration)**
Comprehensive suite: temperature towers, flow rate, retraction & more for optimal performance.
-- **[Precise Wall](https://github.com/OrcaSlicer/OrcaSlicer/wiki/quality_settings_precision#precise-wall) and [Seam Control](https://github.com/OrcaSlicer/OrcaSlicer/wiki/quality_settings_seam)**
+- **[Precise Wall](https://www.orcaslicer.com/wiki/quality_settings_precision#precise-wall) and [Seam Control](https://www.orcaslicer.com/wiki/quality_settings_seam)**
Adjust outer wall spacing and apply scarf seams to enhance print accuracy.
-- **[Sandwich Mode](https://github.com/OrcaSlicer/OrcaSlicer/wiki/quality_settings_wall_and_surfaces#innerouterinner) and [Polyholes](https://github.com/OrcaSlicer/OrcaSlicer/wiki/quality_settings_precision#polyholes) Support**
- Use varied infill [patterns](https://github.com/OrcaSlicer/OrcaSlicer/wiki/strength_settings_patterns) and accurate hole shapes for improved clarity.
-- **[Overhang](https://github.com/OrcaSlicer/OrcaSlicer/wiki/quality_settings_overhangs) and [Support Optimization](https://github.com/OrcaSlicer/OrcaSlicer/wiki#support-settings)**
+- **[Sandwich Mode](https://www.orcaslicer.com/wiki/quality_settings_wall_and_surfaces#innerouterinner) and [Polyholes](https://www.orcaslicer.com/wiki/quality_settings_precision#polyholes) Support**
+ Use varied infill [patterns](https://www.orcaslicer.com/wiki/strength_settings_patterns) and accurate hole shapes for improved clarity.
+- **[Overhang](https://www.orcaslicer.com/wiki/quality_settings_overhangs) and [Support Optimization](https://www.orcaslicer.com/wiki#support-settings)**
Modify geometry for printable overhangs with precise support placement.
-- **[Granular Controls and Customization](https://github.com/OrcaSlicer/OrcaSlicer/wiki#process-settings)**
+- **[Granular Controls and Customization](https://www.orcaslicer.com/wiki#process-settings)**
Fine-tune print speed, layer height, pressure, and temperature with precision.
- **Network Printer Support**
Seamless integration with Klipper, PrusaLink, and OctoPrint for remote control.
-- **[Mouse Ear Brims](https://github.com/OrcaSlicer/OrcaSlicer/wiki/others_settings_brim) & [Adaptive Bed Mesh](https://github.com/OrcaSlicer/OrcaSlicer/wiki/printer_basic_information_adaptive_bed_mesh)**
+- **[Mouse Ear Brims](https://www.orcaslicer.com/wiki/others_settings_brim) & [Adaptive Bed Mesh](https://www.orcaslicer.com/wiki/printer_basic_information_adaptive_bed_mesh)**
Automatic brims and adaptive mesh calibration ensure consistent adhesion.
- **User-Friendly Interface**
Intuitive drag-and-drop design with pre-made profiles for popular printers.
@@ -68,10 +68,10 @@ If you come across any of these in search results, please report them as
# Wiki
-The [wiki](https://github.com/OrcaSlicer/OrcaSlicer/wiki) aims to provide a detailed explanation of the slicer settings, including how to maximize their use and how to calibrate and set up your printer.
+The [wiki](https://www.orcaslicer.com/wiki) aims to provide a detailed explanation of the slicer settings, including how to maximize their use and how to calibrate and set up your printer.
-- **[Access the wiki here](https://github.com/OrcaSlicer/OrcaSlicer/wiki)**
-- **[Contribute to the wiki](https://github.com/OrcaSlicer/OrcaSlicer/wiki/How-to-wiki)**
+- **[Access the wiki here](https://www.orcaslicer.com/wiki)**
+- **[Contribute to the wiki](https://www.orcaslicer.com/wiki/How-to-wiki)**
# Download
@@ -144,7 +144,7 @@ winget install --id=SoftFever.OrcaSlicer -e
# How to Compile
-All updated build instructions for Windows, macOS, and Linux are now available on the official [OrcaSlicer Wiki - How to build](https://github.com/OrcaSlicer/OrcaSlicer/wiki/How-to-build) page.
+All updated build instructions for Windows, macOS, and Linux are now available on the official [OrcaSlicer Wiki - How to build](https://www.orcaslicer.com/wiki/How-to-build) page.
Please refer to the wiki to ensure you're following the latest and most accurate steps for your platform.
diff --git a/build_linux.sh b/build_linux.sh
index 3159557146..9a9a9160ba 100755
--- a/build_linux.sh
+++ b/build_linux.sh
@@ -21,7 +21,7 @@ function usage() {
echo " -p: boost ccache hit rate by disabling precompiled headers (default: ON)"
echo " -r: skip RAM and disk checks (low RAM compiling)"
echo " -s: build the Orca Slicer (optional)"
- echo " -t: build tests (optional)"
+ echo " -t: build tests (optional), requires -s flag"
echo " -u: install system dependencies (asks for sudo password; build prerequisite)"
echo " -l: use Clang instead of GCC (default: GCC)"
echo " -L: use ld.lld as linker (if available)"
diff --git a/build_release_macos.sh b/build_release_macos.sh
index e42490f1bd..1999c62b92 100755
--- a/build_release_macos.sh
+++ b/build_release_macos.sh
@@ -3,7 +3,7 @@
set -e
set -o pipefail
-while getopts ":dpa:snt:xbc:1h" opt; do
+while getopts ":dpa:snt:xbc:1Th" opt; do
case "${opt}" in
d )
export BUILD_TARGET="deps"
@@ -37,6 +37,9 @@ while getopts ":dpa:snt:xbc:1h" opt; do
1 )
export CMAKE_BUILD_PARALLEL_LEVEL=1
;;
+ T )
+ export BUILD_TESTS="1"
+ ;;
h ) echo "Usage: ./build_release_macos.sh [-d]"
echo " -d: Build deps only"
echo " -a: Set ARCHITECTURE (arm64 or x86_64 or universal)"
@@ -47,6 +50,7 @@ while getopts ":dpa:snt:xbc:1h" opt; do
echo " -b: Build without reconfiguring CMake"
echo " -c: Set CMake build configuration, default is Release"
echo " -1: Use single job for building"
+ echo " -T: Build and run tests"
exit 0
;;
* )
@@ -85,6 +89,15 @@ if [ -z "$OSX_DEPLOYMENT_TARGET" ]; then
export OSX_DEPLOYMENT_TARGET="11.3"
fi
+CMAKE_VERSION=$(cmake --version | head -1 | sed 's/[^0-9]*\([0-9]*\).*/\1/')
+if [ "$CMAKE_VERSION" -ge 4 ] 2>/dev/null; then
+ export CMAKE_POLICY_VERSION_MINIMUM=3.5
+ export CMAKE_POLICY_COMPAT="-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
+ echo "Detected CMake 4.x, adding compatibility flag (env + cmake arg)"
+else
+ export CMAKE_POLICY_COMPAT=""
+fi
+
echo "Build params:"
echo " - ARCH: $ARCH"
echo " - BUILD_CONFIG: $BUILD_CONFIG"
@@ -133,7 +146,8 @@ function build_deps() {
-G "${DEPS_CMAKE_GENERATOR}" \
-DCMAKE_BUILD_TYPE="$BUILD_CONFIG" \
-DCMAKE_OSX_ARCHITECTURES:STRING="${_ARCH}" \
- -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}"
+ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
+ ${CMAKE_POLICY_COMPAT}
fi
cmake --build . --config "$BUILD_CONFIG" --target deps
)
@@ -170,13 +184,24 @@ function build_slicer() {
-G "${SLICER_CMAKE_GENERATOR}" \
-DORCA_TOOLS=ON \
${ORCA_UPDATER_SIG_KEY:+-DORCA_UPDATER_SIG_KEY="$ORCA_UPDATER_SIG_KEY"} \
+ ${BUILD_TESTS:+-DBUILD_TESTS=ON} \
-DCMAKE_BUILD_TYPE="$BUILD_CONFIG" \
-DCMAKE_OSX_ARCHITECTURES="${_ARCH}" \
- -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}"
+ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
+ ${CMAKE_POLICY_COMPAT}
fi
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
)
+ if [ "1." == "$BUILD_TESTS". ]; then
+ echo "Running tests for $_ARCH..."
+ (
+ set -x
+ cd "$PROJECT_BUILD_DIR"
+ ctest --build-config "$BUILD_CONFIG" --output-on-failure
+ )
+ fi
+
echo "Verify localization with gettext..."
(
cd "$PROJECT_DIR"
diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake
index 56661ffd33..5dd7b24df1 100644
--- a/cmake/modules/FindGLEW.cmake
+++ b/cmake/modules/FindGLEW.cmake
@@ -223,8 +223,13 @@ if(NOT TARGET GLEW::glew AND NOT GLEW_USE_STATIC_LIBS)
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
if(APPLE)
- set_target_properties(GLEW::glew
- PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set_target_properties(GLEW::glew
+ PROPERTIES INTERFACE_LINK_LIBRARIES "-framework OpenGL")
+ else()
+ set_target_properties(GLEW::glew
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
endif()
if(GLEW_SHARED_LIBRARY_RELEASE)
@@ -258,8 +263,13 @@ elseif(NOT TARGET GLEW::glew_s AND GLEW_USE_STATIC_LIBS)
set_target_properties(GLEW::glew_s PROPERTIES INTERFACE_COMPILE_DEFINITIONS GLEW_STATIC)
if(APPLE)
- set_target_properties(GLEW::glew_s
- PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set_target_properties(GLEW::glew_s
+ PROPERTIES INTERFACE_LINK_LIBRARIES "-framework OpenGL")
+ else()
+ set_target_properties(GLEW::glew_s
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
endif()
if(GLEW_STATIC_LIBRARY_RELEASE)
@@ -292,8 +302,13 @@ if(NOT TARGET GLEW::GLEW)
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
if(APPLE)
- set_target_properties(GLEW::GLEW
- PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set_target_properties(GLEW::GLEW
+ PROPERTIES INTERFACE_LINK_LIBRARIES "-framework OpenGL")
+ else()
+ set_target_properties(GLEW::GLEW
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
endif()
if(TARGET GLEW::glew)
diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt
index 13f3945d0c..92e36d0cad 100644
--- a/deps/CMakeLists.txt
+++ b/deps/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "4.0")
+ set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "" FORCE)
+endif()
+
#
# This CMake project downloads, configures and builds OrcaSlicer dependencies on Unix and Windows.
#
@@ -177,6 +181,7 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
${_gen}
CMAKE_ARGS
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DCMAKE_INSTALL_PREFIX:STRING=${DESTDIR}
-DCMAKE_MODULE_PATH:STRING=${PROJECT_SOURCE_DIR}/../cmake/modules
-DCMAKE_PREFIX_PATH:STRING=${DESTDIR}
@@ -221,6 +226,7 @@ else()
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
${_gen}
CMAKE_ARGS
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DCMAKE_INSTALL_PREFIX:STRING=${DESTDIR}
-DCMAKE_PREFIX_PATH:STRING=${DESTDIR}
-DBUILD_SHARED_LIBS:BOOL=OFF
diff --git a/deps/Qhull/Qhull.cmake b/deps/Qhull/Qhull.cmake
index 9376700428..97667021c0 100644
--- a/deps/Qhull/Qhull.cmake
+++ b/deps/Qhull/Qhull.cmake
@@ -1,11 +1,11 @@
include(GNUInstallDirs)
orcaslicer_add_cmake_project(Qhull
- URL "https://github.com/qhull/qhull/archive/v8.0.1.zip"
- URL_HASH SHA256=5287f5edd6a0372588f5d6640799086a4033d89d19711023ef8229dd9301d69b
+ URL "https://github.com/qhull/qhull/archive/v8.0.2.zip"
+ URL_HASH SHA256=a378e9a39e718e289102c20d45632f873bfdc58a7a5f924246ea4b176e185f1e
CMAKE_ARGS
-DINCLUDE_INSTALL_DIR=${CMAKE_INSTALL_INCLUDEDIR}
)
if (MSVC)
add_debug_dep(dep_Qhull)
-endif ()
\ No newline at end of file
+endif ()
diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake
index e45979fb42..3a52d14198 100644
--- a/deps/wxWidgets/wxWidgets.cmake
+++ b/deps/wxWidgets/wxWidgets.cmake
@@ -24,6 +24,14 @@ else ()
set(_wx_edge "-DwxUSE_WEBVIEW_EDGE=OFF")
endif ()
+set(_wx_opengl_override "")
+if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set(_wx_opengl_override
+ -DOPENGL_gl_LIBRARY="-framework OpenGL"
+ -DOPENGL_glu_LIBRARY="-framework OpenGL"
+ )
+endif()
+
orcaslicer_add_cmake_project(
wxWidgets
GIT_REPOSITORY "https://github.com/SoftFever/Orca-deps-wxWidgets"
@@ -31,6 +39,7 @@ orcaslicer_add_cmake_project(
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG}
${_wx_flatpak_patch}
CMAKE_ARGS
+ ${_wx_opengl_override}
-DwxBUILD_PRECOMP=ON
${_wx_toolkit}
"-DCMAKE_DEBUG_POSTFIX:STRING=${_wx_debug_postfix}"
diff --git a/deps_src/CMakeLists.txt b/deps_src/CMakeLists.txt
index 11457c0d18..390cffad30 100644
--- a/deps_src/CMakeLists.txt
+++ b/deps_src/CMakeLists.txt
@@ -10,7 +10,6 @@ add_subdirectory(earcut)
add_subdirectory(fast_float)
add_subdirectory(nanosvg)
add_subdirectory(nlohmann)
-add_subdirectory(spline) # Header-only spline library
add_subdirectory(stb_dxt) # Header-only STB DXT compression library
# Static libraries
diff --git a/deps_src/README_CMAKE_INTERFACES.md b/deps_src/README_CMAKE_INTERFACES.md
index 78a806fc0b..6ab88c63af 100644
--- a/deps_src/README_CMAKE_INTERFACES.md
+++ b/deps_src/README_CMAKE_INTERFACES.md
@@ -24,18 +24,7 @@ target_link_libraries(your_target PRIVATE semver::semver)
target_link_libraries(your_target PRIVATE hints)
```
-### 3. **spline** (Interface Library)
-- **Type**: Interface library (header-only)
-- **Target**: `spline` or `spline::spline`
-- **Headers**: `spline.h`
-- **Usage**:
-```cmake
-target_link_libraries(your_target PRIVATE spline)
-# or
-target_link_libraries(your_target PRIVATE spline::spline)
-```
-
-### 4. **stb_dxt** (Interface Library)
+### 3. **stb_dxt** (Interface Library)
- **Type**: Interface library (header-only)
- **Target**: `stb_dxt` or `stb_dxt::stb_dxt`
- **Headers**: `stb_dxt.h`
@@ -53,10 +42,9 @@ target_link_libraries(your_target PRIVATE stb_dxt::stb_dxt)
1. **In your CMakeLists.txt**, simply link the library:
```cmake
add_executable(my_app main.cpp)
-target_link_libraries(my_app
- PRIVATE
+target_link_libraries(my_app
+ PRIVATE
semver::semver # For version parsing
- spline::spline # For spline interpolation
stb_dxt::stb_dxt # For DXT texture compression
hints # For hints functionality
)
@@ -67,9 +55,6 @@ target_link_libraries(my_app
// For semver
#include
-// For spline
-#include
-
// For stb_dxt
#include
@@ -100,7 +85,6 @@ target_link_libraries(mycomponent
PUBLIC
semver::semver # Version handling is part of public API
PRIVATE
- spline::spline # Used internally for interpolation
stb_dxt::stb_dxt # Used internally for texture compression
)
diff --git a/deps_src/spline/CMakeLists.txt b/deps_src/spline/CMakeLists.txt
deleted file mode 100644
index ee6d5c9cb3..0000000000
--- a/deps_src/spline/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-cmake_minimum_required(VERSION 3.13)
-project(spline)
-
-# Create interface library for spline (header-only library)
-add_library(spline INTERFACE)
-
-# Set include directories for the interface library
-target_include_directories(spline SYSTEM
- INTERFACE
- $
- $
-)
-
-# Add compile features
-target_compile_features(spline INTERFACE cxx_std_11)
-
-# Create an alias for consistent naming
-add_library(spline::spline ALIAS spline)
-
-# Install headers if needed
-install(FILES
- spline.h
- DESTINATION include/spline
-)
-
-# Install the interface library
-install(TARGETS spline
- EXPORT splineTargets
- INCLUDES DESTINATION include
-)
-
-# Export the targets
-install(EXPORT splineTargets
- FILE splineTargets.cmake
- NAMESPACE spline::
- DESTINATION lib/cmake/spline
-)
diff --git a/deps_src/spline/spline.h b/deps_src/spline/spline.h
deleted file mode 100644
index 4b1ddd6134..0000000000
--- a/deps_src/spline/spline.h
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- * spline.h
- *
- * simple cubic spline interpolation library without external
- * dependencies
- *
- * ---------------------------------------------------------------------
- * Copyright (C) 2011, 2014, 2016, 2021 Tino Kluge (ttk448 at gmail.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- * ---------------------------------------------------------------------
- *
- */
-
-
-#ifndef TK_SPLINE_H
-#define TK_SPLINE_H
-
-#include
-#include
-#include
-#include
-#include
-#ifdef HAVE_SSTREAM
-#include
-#include
-#endif // HAVE_SSTREAM
-
-// not ideal but disable unused-function warnings
-// (we get them because we have implementations in the header file,
-// and this is because we want to be able to quickly separate them
-// into a cpp file if necessary)
-#if !defined(_MSC_VER)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
-namespace tk
-{
-
-// spline interpolation
-class spline
-{
-public:
- // spline types
- enum spline_type {
- linear = 10, // linear interpolation
- cspline = 30, // cubic splines (classical C^2)
- cspline_hermite = 31 // cubic hermite splines (local, only C^1)
- };
-
- // boundary condition type for the spline end-points
- enum bd_type {
- first_deriv = 1,
- second_deriv = 2,
- not_a_knot = 3
- };
-
-protected:
- std::vector m_x,m_y; // x,y coordinates of points
- // interpolation parameters
- // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3
- // where a_i = y_i, or else it won't go through grid points
- std::vector m_b,m_c,m_d; // spline coefficients
- double m_c0; // for left extrapolation
- spline_type m_type;
- bd_type m_left, m_right;
- double m_left_value, m_right_value;
- bool m_made_monotonic;
- void set_coeffs_from_b(); // calculate c_i, d_i from b_i
- size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x
-
-public:
- // default constructor: set boundary condition to be zero curvature
- // at both ends, i.e. natural splines
- spline(): m_type(cspline),
- m_left(second_deriv), m_right(second_deriv),
- m_left_value(0.0), m_right_value(0.0), m_made_monotonic(false)
- {
- ;
- }
- spline(const std::vector& X, const std::vector& Y,
- spline_type type = cspline,
- bool make_monotonic = false,
- bd_type left = second_deriv, double left_value = 0.0,
- bd_type right = second_deriv, double right_value = 0.0
- ):
- m_type(type),
- m_left(left), m_right(right),
- m_left_value(left_value), m_right_value(right_value),
- m_made_monotonic(false) // false correct here: make_monotonic() sets it
- {
- this->set_points(X,Y,m_type);
- if(make_monotonic) {
- this->make_monotonic();
- }
- }
-
-
- // modify boundary conditions: if called it must be before set_points()
- void set_boundary(bd_type left, double left_value,
- bd_type right, double right_value);
-
- // set all data points (cubic_spline=false means linear interpolation)
- void set_points(const std::vector& x,
- const std::vector& y,
- spline_type type=cspline);
-
- // adjust coefficients so that the spline becomes piecewise monotonic
- // where possible
- // this is done by adjusting slopes at grid points by a non-negative
- // factor and this will break C^2
- // this can also break boundary conditions if adjustments need to
- // be made at the boundary points
- // returns false if no adjustments have been made, true otherwise
- bool make_monotonic();
-
- // evaluates the spline at point x
- double operator() (double x) const;
- double deriv(int order, double x) const;
-
- // solves for all x so that: spline(x) = y
- std::vector solve(double y, bool ignore_extrapolation=true) const;
-
- // returns the input data points
- std::vector get_x() const { return m_x; }
- std::vector get_y() const { return m_y; }
- double get_x_min() const { assert(!m_x.empty()); return m_x.front(); }
- double get_x_max() const { assert(!m_x.empty()); return m_x.back(); }
-
-#ifdef HAVE_SSTREAM
- // spline info string, i.e. spline type, boundary conditions etc.
- std::string info() const;
-#endif // HAVE_SSTREAM
-
-};
-
-
-
-namespace internal
-{
-
-// band matrix solver
-class band_matrix
-{
-private:
- std::vector< std::vector > m_upper; // upper band
- std::vector< std::vector > m_lower; // lower band
-public:
- band_matrix() {}; // constructor
- band_matrix(int dim, int n_u, int n_l); // constructor
- ~band_matrix() {}; // destructor
- void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l
- int dim() const; // matrix dimension
- int num_upper() const
- {
- return (int)m_upper.size()-1;
- }
- int num_lower() const
- {
- return (int)m_lower.size()-1;
- }
- // access operator
- double & operator () (int i, int j); // write
- double operator () (int i, int j) const; // read
- // we can store an additional diagonal (in m_lower)
- double& saved_diag(int i);
- double saved_diag(int i) const;
- void lu_decompose();
- std::vector r_solve(const std::vector& b) const;
- std::vector l_solve(const std::vector& b) const;
- std::vector lu_solve(const std::vector& b,
- bool is_lu_decomposed=false);
-
-};
-
-double get_eps();
-
-std::vector solve_cubic(double a, double b, double c, double d,
- int newton_iter=0);
-
-} // namespace internal
-
-
-
-
-// ---------------------------------------------------------------------
-// implementation part, which could be separated into a cpp file
-// ---------------------------------------------------------------------
-
-// spline implementation
-// -----------------------
-
-void spline::set_boundary(spline::bd_type left, double left_value,
- spline::bd_type right, double right_value)
-{
- assert(m_x.size()==0); // set_points() must not have happened yet
- m_left=left;
- m_right=right;
- m_left_value=left_value;
- m_right_value=right_value;
-}
-
-
-void spline::set_coeffs_from_b()
-{
- assert(m_x.size()==m_y.size());
- assert(m_x.size()==m_b.size());
- assert(m_x.size()>2);
- size_t n=m_b.size();
- if(m_c.size()!=n)
- m_c.resize(n);
- if(m_d.size()!=n)
- m_d.resize(n);
-
- for(size_t i=0; i& x,
- const std::vector& y,
- spline_type type)
-{
- assert(x.size()==y.size());
- assert(x.size()>=3);
- // not-a-knot with 3 points has many solutions
- if(m_left==not_a_knot || m_right==not_a_knot)
- assert(x.size()>=4);
- m_type=type;
- m_made_monotonic=false;
- m_x=x;
- m_y=y;
- int n = (int) x.size();
- // check strict monotonicity of input vector x
- for(int i=0; i rhs(n);
- for(int i=1; i2);
- bool modified = false;
- const int n=(int)m_x.size();
- // make sure: input data monotonic increasing --> b_i>=0
- // input data monotonic decreasing --> b_i<=0
- for(int i=0; i=m_y[i]) && (m_y[i]>=m_y[ip1]) && m_b[i]>0.0) ) {
- modified=true;
- m_b[i]=0.0;
- }
- }
- // if input data is monotonic (b[i], b[i+1], avg have all the same sign)
- // ensure a sufficient criteria for monotonicity is satisfied:
- // sqrt(b[i]^2+b[i+1]^2) <= 3 |avg|, with avg=(y[i+1]-y[i])/h,
- for(int i=0; i=0.0 && m_b[i+1]>=0.0 && avg>0.0) ||
- (m_b[i]<=0.0 && m_b[i+1]<=0.0 && avg<0.0) ) {
- // input data is monotonic
- double r = sqrt(m_b[i]*m_b[i]+m_b[i+1]*m_b[i+1])/std::fabs(avg);
- if(r>3.0) {
- // sufficient criteria for monotonicity: r<=3
- // adjust b[i] and b[i+1]
- modified=true;
- m_b[i] *= (3.0/r);
- m_b[i+1] *= (3.0/r);
- }
- }
- }
-
- if(modified==true) {
- set_coeffs_from_b();
- m_made_monotonic=true;
- }
-
- return modified;
-}
-
-// return the closest idx so that m_x[idx] <= x (return 0 if x::const_iterator it;
- it=std::upper_bound(m_x.begin(),m_x.end(),x); // *it > x
- size_t idx = std::max( int(it-m_x.begin())-1, 0); // m_x[idx] <= x
- return idx;
-}
-
-double spline::operator() (double x) const
-{
- // polynomial evaluation using Horner's scheme
- // TODO: consider more numerically accurate algorithms, e.g.:
- // - Clenshaw
- // - Even-Odd method by A.C.R. Newbery
- // - Compensated Horner Scheme
- size_t n=m_x.size();
- size_t idx=find_closest(x);
-
- double h=x-m_x[idx];
- double interpol;
- if(xm_x[n-1]) {
- // extrapolation to the right
- interpol=(m_c[n-1]*h + m_b[n-1])*h + m_y[n-1];
- } else {
- // interpolation
- interpol=((m_d[idx]*h + m_c[idx])*h + m_b[idx])*h + m_y[idx];
- }
- return interpol;
-}
-
-double spline::deriv(int order, double x) const
-{
- assert(order>0);
- size_t n=m_x.size();
- size_t idx = find_closest(x);
-
- double h=x-m_x[idx];
- double interpol;
- if(xm_x[n-1]) {
- // extrapolation to the right
- switch(order) {
- case 1:
- interpol=2.0*m_c[n-1]*h + m_b[n-1];
- break;
- case 2:
- interpol=2.0*m_c[n-1];
- break;
- default:
- interpol=0.0;
- break;
- }
- } else {
- // interpolation
- switch(order) {
- case 1:
- interpol=(3.0*m_d[idx]*h + 2.0*m_c[idx])*h + m_b[idx];
- break;
- case 2:
- interpol=6.0*m_d[idx]*h + 2.0*m_c[idx];
- break;
- case 3:
- interpol=6.0*m_d[idx];
- break;
- default:
- interpol=0.0;
- break;
- }
- }
- return interpol;
-}
-
-std::vector spline::solve(double y, bool ignore_extrapolation) const
-{
- std::vector x; // roots for the entire spline
- std::vector root; // roots for each piecewise cubic
- const size_t n=m_x.size();
-
- // left extrapolation
- if(ignore_extrapolation==false) {
- root = internal::solve_cubic(m_y[0]-y,m_b[0],m_c0,0.0,1);
- for(size_t j=0; j0) ? (m_x[i]-m_x[i-1]) : 0.0;
- double eps = internal::get_eps()*512.0*std::min(h,1.0);
- if( (-eps<=root[j]) && (root[j]0 && x.back()+eps > new_root) {
- x.back()=new_root; // avoid spurious duplicate roots
- } else {
- x.push_back(new_root);
- }
- }
- }
- }
-
- // right extrapolation
- if(ignore_extrapolation==false) {
- root = internal::solve_cubic(m_y[n-1]-y,m_b[n-1],m_c[n-1],0.0,1);
- for(size_t j=0; j0);
- assert(n_u>=0);
- assert(n_l>=0);
- m_upper.resize(n_u+1);
- m_lower.resize(n_l+1);
- for(size_t i=0; i0) {
- return (int)m_upper[0].size();
- } else {
- return 0;
- }
-}
-
-
-// defines the new operator (), so that we can access the elements
-// by A(i,j), index going from i=0,...,dim()-1
-double & band_matrix::operator () (int i, int j)
-{
- int k=j-i; // what band is the entry
- assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part
- if(k>=0) return m_upper[k][i];
- else return m_lower[-k][i];
-}
-double band_matrix::operator () (int i, int j) const
-{
- int k=j-i; // what band is the entry
- assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part
- if(k>=0) return m_upper[k][i];
- else return m_lower[-k][i];
-}
-// second diag (used in LU decomposition), saved in m_lower
-double band_matrix::saved_diag(int i) const
-{
- assert( (i>=0) && (i=0) && (idim(); i++) {
- assert(this->operator()(i,i)!=0.0);
- this->saved_diag(i)=1.0/this->operator()(i,i);
- j_min=std::max(0,i-this->num_lower());
- j_max=std::min(this->dim()-1,i+this->num_upper());
- for(int j=j_min; j<=j_max; j++) {
- this->operator()(i,j) *= this->saved_diag(i);
- }
- this->operator()(i,i)=1.0; // prevents rounding errors
- }
-
- // Gauss LR-Decomposition
- for(int k=0; kdim(); k++) {
- i_max=std::min(this->dim()-1,k+this->num_lower()); // num_lower not a mistake!
- for(int i=k+1; i<=i_max; i++) {
- assert(this->operator()(k,k)!=0.0);
- x=-this->operator()(i,k)/this->operator()(k,k);
- this->operator()(i,k)=-x; // assembly part of L
- j_max=std::min(this->dim()-1,k+this->num_upper());
- for(int j=k+1; j<=j_max; j++) {
- // assembly part of R
- this->operator()(i,j)=this->operator()(i,j)+x*this->operator()(k,j);
- }
- }
- }
-}
-// solves Ly=b
-std::vector band_matrix::l_solve(const std::vector& b) const
-{
- assert( this->dim()==(int)b.size() );
- std::vector x(this->dim());
- int j_start;
- double sum;
- for(int i=0; idim(); i++) {
- sum=0;
- j_start=std::max(0,i-this->num_lower());
- for(int j=j_start; joperator()(i,j)*x[j];
- x[i]=(b[i]*this->saved_diag(i)) - sum;
- }
- return x;
-}
-// solves Rx=y
-std::vector band_matrix::r_solve(const std::vector& b) const
-{
- assert( this->dim()==(int)b.size() );
- std::vector x(this->dim());
- int j_stop;
- double sum;
- for(int i=this->dim()-1; i>=0; i--) {
- sum=0;
- j_stop=std::min(this->dim()-1,i+this->num_upper());
- for(int j=i+1; j<=j_stop; j++) sum += this->operator()(i,j)*x[j];
- x[i]=( b[i] - sum ) / this->operator()(i,i);
- }
- return x;
-}
-
-std::vector band_matrix::lu_solve(const std::vector& b,
- bool is_lu_decomposed)
-{
- assert( this->dim()==(int)b.size() );
- std::vector x,y;
- if(is_lu_decomposed==false) {
- this->lu_decompose();
- }
- y=this->l_solve(b);
- x=this->r_solve(y);
- return x;
-}
-
-// machine precision of a double, i.e. the successor of 1 is 1+eps
-double get_eps()
-{
- //return std::numeric_limits::epsilon(); // __DBL_EPSILON__
- return 2.2204460492503131e-16; // 2^-52
-}
-
-// solutions for a + b*x = 0
-std::vector solve_linear(double a, double b)
-{
- std::vector x; // roots
- if(b==0.0) {
- if(a==0.0) {
- // 0*x = 0
- x.resize(1);
- x[0] = 0.0; // any x solves it but we need to pick one
- return x;
- } else {
- // 0*x + ... = 0, no solution
- return x;
- }
- } else {
- x.resize(1);
- x[0] = -a/b;
- return x;
- }
-}
-
-// solutions for a + b*x + c*x^2 = 0
-std::vector solve_quadratic(double a, double b, double c,
- int newton_iter=0)
-{
- if(c==0.0) {
- return solve_linear(a,b);
- }
- // rescale so that we solve x^2 + 2p x + q = (x+p)^2 + q - p^2 = 0
- double p=0.5*b/c;
- double q=a/c;
- double discr = p*p-q;
- const double eps=0.5*internal::get_eps();
- double discr_err = (6.0*(p*p)+3.0*fabs(q)+fabs(discr))*eps;
-
- std::vector x; // roots
- if(fabs(discr)<=discr_err) {
- // discriminant is zero --> one root
- x.resize(1);
- x[0] = -p;
- } else if(discr<0) {
- // no root
- } else {
- // two roots
- x.resize(2);
- x[0] = -p - sqrt(discr);
- x[1] = -p + sqrt(discr);
- }
-
- // improve solution via newton steps
- for(size_t i=0; i1e-8) {
- x[i] -= f/f1;
- }
- }
- }
-
- return x;
-}
-
-// solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0
-// this is a naive implementation of the analytic solution without
-// optimisation for speed or numerical accuracy
-// newton_iter: number of newton iterations to improve analytical solution
-// see also
-// gsl: gsl_poly_solve_cubic() in solve_cubic.c
-// octave: roots.m - via eigenvalues of the Frobenius companion matrix
-std::vector solve_cubic(double a, double b, double c, double d,
- int newton_iter)
-{
- if(d==0.0) {
- return solve_quadratic(a,b,c,newton_iter);
- }
-
- // convert to normalised form: a + bx + cx^2 + x^3 = 0
- if(d!=1.0) {
- a/=d;
- b/=d;
- c/=d;
- }
-
- // convert to depressed cubic: z^3 - 3pz - 2q = 0
- // via substitution: z = x + c/3
- std::vector z; // roots of the depressed cubic
- double p = -(1.0/3.0)*b + (1.0/9.0)*(c*c);
- double r = 2.0*(c*c)-9.0*b;
- double q = -0.5*a - (1.0/54.0)*(c*r);
- double discr=p*p*p-q*q; // discriminant
- // calculating numerical round-off errors with assumptions:
- // - each operation is precise but each intermediate result x
- // when stored has max error of x*eps
- // - only multiplication with a power of 2 introduces no new error
- // - a,b,c,d and some fractions (e.g. 1/3) have rounding errors eps
- // - p_err << |p|, q_err << |q|, ... (this is violated in rare cases)
- // would be more elegant to use boost::numeric::interval
- const double eps = internal::get_eps();
- double p_err = eps*((3.0/3.0)*fabs(b)+(4.0/9.0)*(c*c)+fabs(p));
- double r_err = eps*(6.0*(c*c)+18.0*fabs(b)+fabs(r));
- double q_err = 0.5*fabs(a)*eps + (1.0/54.0)*fabs(c)*(r_err+fabs(r)*3.0*eps)
- + fabs(q)*eps;
- double discr_err = (p*p) * (3.0*p_err + fabs(p)*2.0*eps)
- + fabs(q) * (2.0*q_err + fabs(q)*eps) + fabs(discr)*eps;
-
- // depending on the discriminant we get different solutions
- if(fabs(discr)<=discr_err) {
- // discriminant zero: one or two real roots
- if(fabs(p)<=p_err) {
- // p and q are zero: single root
- z.resize(1);
- z[0] = 0.0; // triple root
- } else {
- z.resize(2);
- z[0] = 2.0*q/p; // single root
- z[1] = -0.5*z[0]; // double root
- }
- } else if(discr>0) {
- // three real roots: via trigonometric solution
- z.resize(3);
- double ac = (1.0/3.0) * acos( q/(p*sqrt(p)) );
- double sq = 2.0*sqrt(p);
- z[0] = sq * cos(ac);
- z[1] = sq * cos(ac-2.0*M_PI/3.0);
- z[2] = sq * cos(ac-4.0*M_PI/3.0);
- } else if (discr<0.0) {
- // single real root: via Cardano's fromula
- z.resize(1);
- double sgnq = (q >= 0 ? 1 : -1);
- double basis = fabs(q) + sqrt(-discr);
- double C = sgnq * pow(basis, 1.0/3.0); // c++11 has std::cbrt()
- z[0] = C + p/C;
- }
- for(size_t i=0; i1e-8) {
- z[i] -= f/f1;
- }
- }
- }
- // ensure if a=0 we get exactly x=0 as root
- // TODO: remove this fudge
- if(a==0.0) {
- assert(z.size()>0); // cubic should always have at least one root
- double xmin=fabs(z[0]);
- size_t imin=0;
- for(size_t i=1; ifabs(z[i])) {
- xmin=fabs(z[i]);
- imin=i;
- }
- }
- z[imin]=0.0; // replace the smallest absolute value with 0
- }
- std::sort(z.begin(), z.end());
- return z;
-}
-
-
-} // namespace internal
-
-
-} // namespace tk
-
-
-#if !defined(_MSC_VER)
-#pragma GCC diagnostic pop
-#endif
-
-#endif /* TK_SPLINE_H */
diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot
index accaf4ea66..4901a6b7a5 100644
--- a/localization/i18n/OrcaSlicer.pot
+++ b/localization/i18n/OrcaSlicer.pot
@@ -11108,6 +11108,19 @@ msgid ""
"easily."
msgstr ""
+msgid "Brim follows compensated outline"
+msgstr ""
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+
msgid "Brim ears"
msgstr ""
diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po
index cfb35a2480..d29d05b06b 100644
--- a/localization/i18n/ca/OrcaSlicer_ca.po
+++ b/localization/i18n/ca/OrcaSlicer_ca.po
@@ -12177,6 +12177,26 @@ msgstr ""
"Un espai entre la línia de la Vora d'Adherència més interna i l'objecte pot "
"fer que la Vora d'Adherència s'elimini més fàcilment"
+msgid "Brim follows compensated outline"
+msgstr "Vora d'Adherència segueix un esquema compensat"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Quan està activat, vora d'adherència s'alinea amb la geometria del perímetre de la primera capa "
+"després d'aplicar la compensació del peu d'elefant.\n"
+"Aquesta opció està pensada per als casos en què la compensació del peu d'elefant "
+"altera significativament la petjada de la primera capa.\n"
+"\n"
+"Si la vostra configuració actual ja funciona bé, activar-la pot ser innecessari i "
+"pot fer que el vora d'adherència es fusioni amb les capes superiors."
+
msgid "Brim ears"
msgstr "Orelles de la Vora d'Adherència"
diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po
index 9cc4976536..933c3b3504 100644
--- a/localization/i18n/cs/OrcaSlicer_cs.po
+++ b/localization/i18n/cs/OrcaSlicer_cs.po
@@ -11730,6 +11730,26 @@ msgid ""
msgstr ""
"Mezera mezi nejvnitřnějším límcem a předmětem může usnadnit odstranění límce"
+msgid "Brim follows compensated outline"
+msgstr "Límec sleduje kompenzovaný obrys"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Když je povoleno, límec je zarovnán s obvodovou geometrií první vrstvy "
+"po použití kompenzace sloní nohy.\n"
+"Tato možnost je určena pro případy, kdy je kompenzace sloní nohy "
+"výrazně mění stopu první vrstvy.\n"
+"\n"
+"Pokud vaše aktuální nastavení již funguje dobře, jeho povolení může být zbytečné a "
+"může způsobit spojení límec s horními vrstvami."
+
msgid "Brim ears"
msgstr "Uši límce"
diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po
index f0a0be35b4..15b84734a4 100644
--- a/localization/i18n/de/OrcaSlicer_de.po
+++ b/localization/i18n/de/OrcaSlicer_de.po
@@ -12766,6 +12766,26 @@ msgstr ""
"Eine Lücke zwischen der innersten Randlinie und dem Objekt kann das Abnehmen "
"des Randes erleichtern"
+msgid "Brim follows compensated outline"
+msgstr "Umrandung folgt einem kompensierten Umriss"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Wenn diese Option aktiviert ist, wird umrandung an der Umfangsgeometrie der ersten Ebene ausgerichtet "
+"nach Anwendung der Elefantenfußkompensation.\n"
+"Diese Option ist für Fälle gedacht, in denen eine Elefantenfuß-Entschädigung vorliegt "
+"verändert den Footprint der ersten Schicht erheblich.\n"
+"\n"
+"Wenn Ihr aktuelles Setup bereits gut funktioniert, kann es unnötig sein, es zu aktivieren "
+"kann dazu führen, dass der umrandung mit den oberen Schichten verschmilzt."
+
msgid "Brim ears"
msgstr "Brim Ohren"
diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po
index 647f62ee13..02b4dd6c18 100644
--- a/localization/i18n/en/OrcaSlicer_en.po
+++ b/localization/i18n/en/OrcaSlicer_en.po
@@ -11327,6 +11327,26 @@ msgstr ""
"This creates a gap between the innermost brim line and the object and can "
"make the brim easier to remove."
+msgid "Brim follows compensated outline"
+msgstr "Brim follows compensated outline"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+
msgid "Brim ears"
msgstr ""
diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po
index 85079d85fe..19c81d480d 100644
--- a/localization/i18n/es/OrcaSlicer_es.po
+++ b/localization/i18n/es/OrcaSlicer_es.po
@@ -12147,6 +12147,26 @@ msgstr ""
"Un hueco entre la línea más interna del borde de adherencia y el objeto "
"puede hacer que el borde de adherencia se retire más fácilmente"
+msgid "Brim follows compensated outline"
+msgstr "Borde de adherencia sigue el esquema compensado"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Cuando está habilitado, el borde de adherencia está alineado con la geometría del perímetro de la primera capa "
+"después de aplicar la compensación de pata de elefante.\n"
+"Esta opción está destinada a casos en los que la Compensación por pata de elefante "
+"altera significativamente la huella de la primera capa.\n"
+"\n"
+"Si su configuración actual ya funciona bien, habilitarla puede ser innecesario y "
+"puede hacer que el borde de adherencia se fusione con las capas superiores."
+
msgid "Brim ears"
msgstr "Orejas de borde"
diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po
index 1dd903bc10..5a80f34757 100644
--- a/localization/i18n/fr/OrcaSlicer_fr.po
+++ b/localization/i18n/fr/OrcaSlicer_fr.po
@@ -12298,6 +12298,26 @@ msgstr ""
"Un espace entre la ligne de bord la plus interne et l'objet peut faciliter "
"le retrait du bord"
+msgid "Brim follows compensated outline"
+msgstr "Bordure suit le contour compensé"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Lorsqu'il est activé, le bordure est aligné avec la géométrie du périmètre de la première couche "
+"après l'application de la compensation du pied d'éléphant.\n"
+"Cette option est destinée aux cas où la compensation du pied d'éléphant "
+"modifie considérablement l’empreinte de la première couche.\n"
+"\n"
+"Si votre configuration actuelle fonctionne déjà bien, son activation peut être inutile et "
+"peut provoquer la fusion du bordure avec les couches supérieures."
+
msgid "Brim ears"
msgstr "Bordures à oreilles"
diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po
index ddd70907ba..ba898f64ac 100644
--- a/localization/i18n/hu/OrcaSlicer_hu.po
+++ b/localization/i18n/hu/OrcaSlicer_hu.po
@@ -11603,6 +11603,26 @@ msgstr ""
"A legbelső peremvonal és a tárgy közötti rés, ami megkönnyítheti a perem "
"eltávolítását"
+msgid "Brim follows compensated outline"
+msgstr "A Perem a kompenzált körvonalat követi"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Ha engedélyezve van, a perem igazodik az első réteg kerületi geometriájához "
+"az elefánttalp-kompenzáció alkalmazása után.\n"
+"Ez az opció arra az esetre szolgál, amikor az elefánttalp-kompenzáció "
+"jelentősen megváltoztatja az első réteg alapterületét.\n"
+"\n"
+"Ha a jelenlegi beállítás már jól működik, előfordulhat, hogy az engedélyezése felesleges és "
+"a perem összeolvadását okozhatja a felső rétegekkel."
+
msgid "Brim ears"
msgstr "Karimás fülek"
diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po
index 43ee2d09c0..222467d02a 100644
--- a/localization/i18n/it/OrcaSlicer_it.po
+++ b/localization/i18n/it/OrcaSlicer_it.po
@@ -12234,6 +12234,26 @@ msgstr ""
"Crea uno spazio tra la linea più interna della tesa e l'oggetto per rendere "
"più facile la rimozione della tesa."
+msgid "Brim follows compensated outline"
+msgstr "Tesa segue il contorno compensato"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Quando abilitato, tesa è allineato con la geometria perimetrale del primo strato "
+"dopo l'applicazione della compensazione del piede di elefante.\n"
+"Questa opzione è prevista per i casi in cui è prevista la compensazione del piede di elefante "
+"altera significativamente l'impronta del primo strato.\n"
+"\n"
+"Se la tua configurazione attuale funziona già bene, abilitarla potrebbe non essere necessaria e "
+"può causare la fusione del tesa con gli strati superiori."
+
msgid "Brim ears"
msgstr "Tesa ad orecchio"
diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po
index 120ccae558..3258a45800 100644
--- a/localization/i18n/ja/OrcaSlicer_ja.po
+++ b/localization/i18n/ja/OrcaSlicer_ja.po
@@ -11394,6 +11394,26 @@ msgstr ""
"ブリムを取り外しやすくする為、一番内側のブリムラインをモデルと少し距離を設け"
"ます。"
+msgid "Brim follows compensated outline"
+msgstr "ブリム は補正されたアウトラインに従います"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"有効にすると、ブリム は最初の層の周囲ジオメトリと位置合わせされます。 "
+"エレファント・フット・コンペンセーション適用後。\n"
+"このオプションは、象の足の補正が必要な場合を対象としています。 "
+"最初の層のフットプリントを大幅に変更します。\n"
+"\n"
+"現在の設定がすでにうまく機能している場合は、それを有効にする必要はないかもしれません。 "
+"ブリム が上位層と融合する可能性があります。"
+
msgid "Brim ears"
msgstr ""
diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po
index fbc550e415..cf3d9dea71 100644
--- a/localization/i18n/ko/OrcaSlicer_ko.po
+++ b/localization/i18n/ko/OrcaSlicer_ko.po
@@ -11817,6 +11817,26 @@ msgstr ""
"가장 안쪽 브림 라인과 객체 사이에 간격을 주어 쉽게 브림을 제거 할 수 있게 합"
"니다"
+msgid "Brim follows compensated outline"
+msgstr "브림는 보상된 아웃라인을 따릅니다."
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"활성화되면 브림은 첫 번째 레이어 주변 형상과 정렬됩니다 "
+"코끼리 발 보정이 적용된 후.\n"
+"이 옵션은 코끼리 발 보상이 적용되는 경우를 위한 것입니다 "
+"첫 번째 레이어 공간을 크게 변경합니다.\n"
+"\n"
+"현재 설정이 이미 잘 작동하는 경우 활성화할 필요가 없으며 "
+"브림이 상위 레이어와 융합될 수 있습니다."
+
msgid "Brim ears"
msgstr "브림 귀"
diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po
index 052250e63f..ec9f6ce417 100644
--- a/localization/i18n/lt/OrcaSlicer_lt.po
+++ b/localization/i18n/lt/OrcaSlicer_lt.po
@@ -12183,6 +12183,26 @@ msgstr ""
"Sukuriamas tarpas tarp vidinės krašto linijos ir objekto, todėl galima "
"lengviau jį atskirti."
+msgid "Brim follows compensated outline"
+msgstr "Kraštas atitinka kompensuotą kontūrą"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Kai įjungta, kraštas yra sulygiuotas su pirmojo sluoksnio perimetro geometrija "
+"pritaikius dramblio pėdos kompensaciją.\n"
+"Ši parinktis skirta tais atvejais, kai kompensuojama dramblio pėda "
+"žymiai pakeičia pirmojo sluoksnio pėdsaką.\n"
+"\n"
+"Jei dabartinė sąranka jau veikia gerai, jos įjungti gali nebūti ir "
+"gali sukelti kraštas susiliejimą su viršutiniais sluoksniais."
+
msgid "Brim ears"
msgstr "Krašto \"ausys\""
diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po
index 2f1c24f60d..923ea51aec 100644
--- a/localization/i18n/nl/OrcaSlicer_nl.po
+++ b/localization/i18n/nl/OrcaSlicer_nl.po
@@ -11751,6 +11751,26 @@ msgstr ""
"Dit creëert ruimte tussen de binnenste brimlijn en het object en zorgt "
"ervoor dat het object eenvoudiger van het printbed kan worden verwijderd."
+msgid "Brim follows compensated outline"
+msgstr "Rand volgt de gecompenseerde omtrek"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Indien ingeschakeld, wordt de rand uitgelijnd met de omtrekgeometrie van de eerste laag "
+"nadat olifantenvoetcompensatie is toegepast.\n"
+"Deze optie is bedoeld voor gevallen waarin sprake is van olifantenvoetcompensatie "
+"verandert de voetafdruk van de eerste laag aanzienlijk.\n"
+"\n"
+"Als uw huidige configuratie al goed werkt, kan het inschakelen hiervan niet nodig zijn "
+"kan ervoor zorgen dat de rand samensmelt met de bovenste lagen."
+
msgid "Brim ears"
msgstr "Rand oren"
diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po
index 81afc09e9b..5c2896d962 100644
--- a/localization/i18n/pl/OrcaSlicer_pl.po
+++ b/localization/i18n/pl/OrcaSlicer_pl.po
@@ -12130,6 +12130,26 @@ msgstr ""
"Szczelina między najbardziej wewnętrzną linią brimu a obiektem może ułatwić "
"usunięcie brimu"
+msgid "Brim follows compensated outline"
+msgstr "Brim podąża za skompensowanym konturem"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Po włączeniu brim jest wyrównany z geometrią obwodu pierwszej warstwy "
+"po zastosowaniu Kompensacji Stopy Słonia.\n"
+"Ta opcja jest przeznaczona dla przypadków, w których występuje kompensacja stopy słonia "
+"znacząco zmienia ślad pierwszej warstwy.\n"
+"\n"
+"Jeśli Twoja bieżąca konfiguracja już działa dobrze, włączenie jej może być niepotrzebne i "
+"może spowodować stopienie brim z górnymi warstwami."
+
msgid "Brim ears"
msgstr "Uszy brim"
diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po
index 73fcdb50ea..cffab32de6 100644
--- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po
+++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po
@@ -12555,6 +12555,26 @@ msgstr ""
"Um espaço entre a linha mais interna da borda e o objeto pode facilitar a "
"remoção da borda."
+msgid "Brim follows compensated outline"
+msgstr "Borda segue contorno compensado"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Quando ativado, o borda fica alinhado com a geometria do perímetro da primeira camada "
+"após a aplicação da Compensação da Pé de Elefante.\n"
+"Esta opção destina-se aos casos em que a Compensação da Pé de Elefante "
+"altera significativamente a pegada da primeira camada.\n"
+"\n"
+"Se a sua configuração atual já funciona bem, ativá-la pode ser desnecessário e "
+"pode fazer com que o borda se funda com as camadas superiores."
+
msgid "Brim ears"
msgstr "Orelhas da borda"
diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po
index d9ff700c16..4364ce8306 100644
--- a/localization/i18n/ru/OrcaSlicer_ru.po
+++ b/localization/i18n/ru/OrcaSlicer_ru.po
@@ -12291,6 +12291,26 @@ msgid ""
"easily."
msgstr "Смещение каймы от печатаемой модели, может облегчить её удаление."
+msgid "Brim follows compensated outline"
+msgstr "Кайма соответствует компенсированному контуру"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Если этот параметр включен, кайма выравнивается по геометрии периметра первого слоя "
+"после применения компенсации «слоновьей стопы».\n"
+"Эта опция предназначена для случаев, когда «Компенсация слоновой стопы» "
+"существенно изменяет след первого слоя.\n"
+"\n"
+"Если ваша текущая настройка уже работает хорошо, ее включение может быть ненужным и "
+"может привести к слиянию кайма с верхними слоями."
+
msgid "Brim ears"
msgstr "Ушки каймы"
diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po
index 04c2d4d565..ab1944d79e 100644
--- a/localization/i18n/sv/OrcaSlicer_sv.po
+++ b/localization/i18n/sv/OrcaSlicer_sv.po
@@ -11574,6 +11574,26 @@ msgstr ""
"Mellanrum mellan innersta brim linjen och objektet kan underlätta vid "
"borttagande av brim"
+msgid "Brim follows compensated outline"
+msgstr "Brim följer kompenserad disposition"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"När den är aktiverad, är brim justerad med det första lagrets omkretsgeometri "
+"efter att elefantfotskompensation tillämpas.\n"
+"Detta alternativ är avsett för fall där elefantfotskompensation "
+"förändrar det första skiktets fotavtryck avsevärt.\n"
+"\n"
+"Om din nuvarande inställning redan fungerar bra kan det vara onödigt att aktivera det och "
+"kan få brim att smälta samman med de övre lagren."
+
msgid "Brim ears"
msgstr "Brätte öron"
diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po
index a817dd919e..b10eacfc6e 100644
--- a/localization/i18n/tr/OrcaSlicer_tr.po
+++ b/localization/i18n/tr/OrcaSlicer_tr.po
@@ -12097,6 +12097,26 @@ msgstr ""
"En içteki kenar çizgisi ile nesne arasındaki boşluk, kenarlığın daha kolay "
"çıkarılmasını sağlayabilir."
+msgid "Brim follows compensated outline"
+msgstr "Kenar telafi edilen taslağı takip ediyor"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Etkinleştirildiğinde, kenar birinci katmanın çevre geometrisiyle hizalanır "
+"Fil Ayağı Telafisi uygulandıktan sonra.\n"
+"Bu seçenek Fil Ayağı Telafisinin geçerli olmadığı durumlar için tasarlanmıştır "
+"ilk katmanın ayak izini önemli ölçüde değiştirir.\n"
+"\n"
+"Mevcut kurulumunuz zaten iyi çalışıyorsa, bunu etkinleştirmek gereksiz olabilir ve "
+"kenar'in üst katmanlarla kaynaşmasına neden olabilir."
+
msgid "Brim ears"
msgstr "Kenar kulakları"
diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po
index 05482e66d1..296efbe5bd 100644
--- a/localization/i18n/uk/OrcaSlicer_uk.po
+++ b/localization/i18n/uk/OrcaSlicer_uk.po
@@ -12138,6 +12138,26 @@ msgstr ""
"Зазор між першою внутрішньою лінією кайми та об'єктом може сприяти легшому "
"відокремленню кайми"
+msgid "Brim follows compensated outline"
+msgstr "Кайма має компенсований контур"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Якщо ввімкнено, кайма вирівнюється з геометрією периметра першого рівня "
+"після застосування Elephant Foot Compensation.\n"
+"Ця опція призначена для випадків компенсації слонячої стопи "
+"значно змінює поверхню першого шару.\n"
+"\n"
+"Якщо ваші поточні налаштування вже працюють добре, увімкнення їх може бути непотрібним "
+"може призвести до злиття кайма з верхніми шарами."
+
msgid "Brim ears"
msgstr "Вушка кайми"
diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/OrcaSlicer_vi.po
index f14576ceed..5017bc246f 100644
--- a/localization/i18n/vi/OrcaSlicer_vi.po
+++ b/localization/i18n/vi/OrcaSlicer_vi.po
@@ -11926,6 +11926,26 @@ msgstr ""
"Khoảng cách giữa đường brim trong cùng và đối tượng có thể làm cho brim dễ "
"dàng tháo hơn."
+msgid "Brim follows compensated outline"
+msgstr "Brim tuân theo phác thảo được bù đắp"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"Khi được bật, brim sẽ được căn chỉnh theo hình học chu vi lớp đầu tiên "
+"sau khi áp dụng Bồi thường bàn chân voi.\n"
+"Tùy chọn này dành cho các trường hợp Bồi thường chân voi "
+"làm thay đổi đáng kể dấu chân lớp đầu tiên.\n"
+"\n"
+"Nếu thiết lập hiện tại của bạn đã hoạt động tốt, việc bật nó có thể không cần thiết và "
+"có thể khiến brim kết hợp với các lớp trên."
+
msgid "Brim ears"
msgstr "Tai brim"
diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po
index 952bd49555..8cad4e58a5 100644
--- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po
+++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po
@@ -2490,7 +2490,7 @@ msgid "Plate"
msgstr "盘"
msgid "Brim"
-msgstr "Brim"
+msgstr "边缘"
msgid "Object/Part Setting"
msgstr "对象/零件设置"
@@ -11493,6 +11493,26 @@ msgid ""
"easily."
msgstr "在brim和模型之间设置间隙,能够让brim更容易剥离"
+msgid "Brim follows compensated outline"
+msgstr "边缘 遵循补偿轮廓"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"启用后,边缘 与第一层周边几何体对齐 "
+"应用象脚补偿后。\n"
+"此选项适用于象脚补偿的情况 "
+"显着改变第一层足迹。\n"
+"\n"
+"如果您当前的设置已经运行良好,则可能没有必要启用它,并且 "
+"可以导致 边缘 与上层融合。"
+
msgid "Brim ears"
msgstr "圆盘"
diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po
index 01c3669856..51d89cca21 100644
--- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po
+++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po
@@ -2493,7 +2493,7 @@ msgid "Plate"
msgstr "列印板"
msgid "Brim"
-msgstr "Brim"
+msgstr "邊緣"
msgid "Object/Part Setting"
msgstr "物件/零件 設定"
@@ -11560,6 +11560,26 @@ msgid ""
"easily."
msgstr "在 Brim 和模型之間設定間隙,能夠讓 Brim 更容易拆除"
+msgid "Brim follows compensated outline"
+msgstr "邊緣 遵循補償輪廓"
+
+msgid ""
+"When enabled, the brim is aligned with the first-layer perimeter geometry "
+"after Elephant Foot Compensation is applied.\n"
+"This option is intended for cases where Elephant Foot Compensation "
+"significantly alters the first-layer footprint.\n"
+"\n"
+"If your current setup already works well, enabling it may be unnecessary and "
+"can cause the brim to fuse with upper layers."
+msgstr ""
+"啟用後,邊緣 與第一層周邊幾何體對齊 "
+"應用像腳補償後。\n"
+"此選項適用於像腳補償的情況 "
+"顯著改變第一層足跡。\n"
+"\n"
+"如果您當前的設置已經運行良好,則可能沒有必要啟用它,並且 "
+"可以導致 邊緣 與上層融合。"
+
msgid "Brim ears"
msgstr "耳狀 Brim"
diff --git a/resources/images/axis_toggle.svg b/resources/images/axis_toggle.svg
deleted file mode 100644
index 679c34e5ca..0000000000
--- a/resources/images/axis_toggle.svg
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
diff --git a/resources/images/axis_toggle_dark.svg b/resources/images/axis_toggle_dark.svg
deleted file mode 100644
index 08c52a8398..0000000000
--- a/resources/images/axis_toggle_dark.svg
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
diff --git a/resources/images/axis_toggle_hover.svg b/resources/images/axis_toggle_hover.svg
deleted file mode 100644
index 1d462ffb1d..0000000000
--- a/resources/images/axis_toggle_hover.svg
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
diff --git a/resources/images/axis_toggle_hover_dark.svg b/resources/images/axis_toggle_hover_dark.svg
deleted file mode 100644
index 14f9bd2767..0000000000
--- a/resources/images/axis_toggle_hover_dark.svg
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
diff --git a/resources/images/canvas_menu.svg b/resources/images/canvas_menu.svg
new file mode 100644
index 0000000000..b94a4952f0
--- /dev/null
+++ b/resources/images/canvas_menu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_menu_dark.svg b/resources/images/canvas_menu_dark.svg
new file mode 100644
index 0000000000..6578d79a9c
--- /dev/null
+++ b/resources/images/canvas_menu_dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_menu_dark_hover.svg b/resources/images/canvas_menu_dark_hover.svg
new file mode 100644
index 0000000000..e71a5c9787
--- /dev/null
+++ b/resources/images/canvas_menu_dark_hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_menu_hover.svg b/resources/images/canvas_menu_hover.svg
new file mode 100644
index 0000000000..83fbddee17
--- /dev/null
+++ b/resources/images/canvas_menu_hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_zoom.svg b/resources/images/canvas_zoom.svg
new file mode 100644
index 0000000000..5448cd7cee
--- /dev/null
+++ b/resources/images/canvas_zoom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_zoom_dark.svg b/resources/images/canvas_zoom_dark.svg
new file mode 100644
index 0000000000..9e598f8cba
--- /dev/null
+++ b/resources/images/canvas_zoom_dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_zoom_dark_hover.svg b/resources/images/canvas_zoom_dark_hover.svg
new file mode 100644
index 0000000000..6d7e4e5fcb
--- /dev/null
+++ b/resources/images/canvas_zoom_dark_hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/images/canvas_zoom_hover.svg b/resources/images/canvas_zoom_hover.svg
new file mode 100644
index 0000000000..53f272d28d
--- /dev/null
+++ b/resources/images/canvas_zoom_hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json
index 9425300cb4..fdc096c888 100644
--- a/resources/profiles/BBL.json
+++ b/resources/profiles/BBL.json
@@ -1405,6 +1405,10 @@
"name": "Generic PLA-CF @base",
"sub_path": "filament/Generic PLA-CF @base.json"
},
+ {
+ "name": "Numakers PLA+ @base",
+ "sub_path": "filament/Numakers/Numakers PLA+ @base.json"
+ },
{
"name": "Overture Matte PLA @base",
"sub_path": "filament/Overture/Overture Matte PLA @base.json"
@@ -1458,12 +1462,12 @@
"sub_path": "filament/Polymaker/Panchroma PLA Neon @base.json"
},
{
- "name": "Panchroma PLA Silk @base",
- "sub_path": "filament/Polymaker/Panchroma PLA Silk @base.json"
+ "name": "Panchroma PLA Satin @base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @base.json"
},
{
- "name": "Panchroma PLA Stain @base",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @base.json"
+ "name": "Panchroma PLA Silk @base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Silk @base.json"
},
{
"name": "Panchroma PLA Starlight @base",
@@ -5101,6 +5105,42 @@
"name": "Generic PLA-CF @BBL P2S",
"sub_path": "filament/Generic PLA-CF @BBL P2S.json"
},
+ {
+ "name": "Numakers PLA+ @BBL A1",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL A1 0.2 nozzle",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1 0.2 nozzle.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL A1M",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1M.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL A1M 0.2 nozzle",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1M 0.2 nozzle.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL P1P",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL P1P.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL P1P 0.2 nozzle",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL P1P 0.2 nozzle.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL X1",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL X1C",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1C.json"
+ },
+ {
+ "name": "Numakers PLA+ @BBL X1C 0.2 nozzle",
+ "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1C 0.2 nozzle.json"
+ },
{
"name": "Overture Matte PLA @BBL A1",
"sub_path": "filament/Overture/Overture Matte PLA @BBL A1.json"
@@ -5641,6 +5681,46 @@
"name": "Panchroma PLA Neon @BBL X1C 0.2 nozzle",
"sub_path": "filament/Polymaker/Panchroma PLA Neon @BBL X1C 0.2 nozzle.json"
},
+ {
+ "name": "Panchroma PLA Satin @BBL A1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL A1.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL A1 0.2 nozzle",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL A1 0.2 nozzle.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL A1M",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL A1M.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL A1M 0.2 nozzle",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL A1M 0.2 nozzle.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL P1P",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL P1P.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL P1P 0.2 nozzle",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL P1P 0.2 nozzle.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL X1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL X1.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL X1 0.2 nozzle",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL X1 0.2 nozzle.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL X1C",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL X1C.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @BBL X1C 0.2 nozzle",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @BBL X1C 0.2 nozzle.json"
+ },
{
"name": "Panchroma PLA Silk @BBL A1",
"sub_path": "filament/Polymaker/Panchroma PLA Silk @BBL A1.json"
@@ -5677,46 +5757,6 @@
"name": "Panchroma PLA Silk @BBL X1C",
"sub_path": "filament/Polymaker/Panchroma PLA Silk @BBL X1C.json"
},
- {
- "name": "Panchroma PLA Stain @BBL A1",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL A1.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL A1 0.2 nozzle",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL A1 0.2 nozzle.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL A1M",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL A1M.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL A1M 0.2 nozzle",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL A1M 0.2 nozzle.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL P1P",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL P1P.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL P1P 0.2 nozzle",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL P1P 0.2 nozzle.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL X1",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL X1.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL X1 0.2 nozzle",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL X1 0.2 nozzle.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL X1C",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL X1C.json"
- },
- {
- "name": "Panchroma PLA Stain @BBL X1C 0.2 nozzle",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @BBL X1C 0.2 nozzle.json"
- },
{
"name": "Panchroma PLA Starlight @BBL A1",
"sub_path": "filament/Polymaker/Panchroma PLA Starlight @BBL A1.json"
@@ -7661,46 +7701,6 @@
"name": "Overture TPU @BBL X1C 0.2 nozzle",
"sub_path": "filament/Overture/Overture TPU @BBL X1C 0.2 nozzle.json"
},
- {
- "name": "Numakers PLA+ @base",
- "sub_path": "filament/Numakers/Numakers PLA+ @base.json"
- },
- {
- "name": "Numakers PLA+ @BBL A1",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1.json"
- },
- {
- "name": "Numakers PLA+ @BBL A1 0.2 nozzle",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1 0.2 nozzle.json"
- },
- {
- "name": "Numakers PLA+ @BBL A1M",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1M.json"
- },
- {
- "name": "Numakers PLA+ @BBL A1M 0.2 nozzle",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL A1M 0.2 nozzle.json"
- },
- {
- "name": "Numakers PLA+ @BBL P1P",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL P1P.json"
- },
- {
- "name": "Numakers PLA+ @BBL P1P 0.2 nozzle",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL P1P 0.2 nozzle.json"
- },
- {
- "name": "Numakers PLA+ @BBL X1",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1.json"
- },
- {
- "name": "Numakers PLA+ @BBL X1C",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1C.json"
- },
- {
- "name": "Numakers PLA+ @BBL X1C 0.2 nozzle",
- "sub_path": "filament/Numakers/Numakers PLA+ @BBL X1C 0.2 nozzle.json"
- },
{
"name": "fdm_filament_dual_common",
"sub_path": "filament/fdm_filament_dual_common.json"
diff --git a/resources/profiles/BBL/Bambu Lab P2S_cover.png b/resources/profiles/BBL/Bambu Lab P2S_cover.png
index febba125ee..30982b863a 100644
Binary files a/resources/profiles/BBL/Bambu Lab P2S_cover.png and b/resources/profiles/BBL/Bambu Lab P2S_cover.png differ
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1 0.2 nozzle.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1 0.2 nozzle.json
similarity index 74%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1 0.2 nozzle.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1 0.2 nozzle.json
index 1db86a72e8..886b3217cc 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1 0.2 nozzle.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1 0.2 nozzle.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL A1 0.2 nozzle",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL A1 0.2 nozzle",
+ "renamed_from": "Panchroma PLA Stain @BBL A1 0.2 nozzle",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_01",
"instantiation": "true",
@@ -26,4 +27,4 @@
"slow_down_layer_time": [
"5"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1.json
similarity index 79%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1.json
index 6f573a8f19..93520a1eda 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL A1",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL A1",
+ "renamed_from": "Panchroma PLA Stain @BBL A1",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_00",
"instantiation": "true",
@@ -28,4 +29,4 @@
"slow_down_layer_time": [
"5"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M 0.2 nozzle.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M 0.2 nozzle.json
similarity index 74%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M 0.2 nozzle.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M 0.2 nozzle.json
index 7510aa9ebf..b6689b1ee8 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M 0.2 nozzle.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M 0.2 nozzle.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL A1M 0.2 nozzle",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL A1M 0.2 nozzle",
+ "renamed_from": "Panchroma PLA Stain @BBL A1M 0.2 nozzle",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_03",
"instantiation": "true",
@@ -26,4 +27,4 @@
"slow_down_layer_time": [
"5"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M.json
similarity index 79%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M.json
index 620a76ffe4..800a4bb8bc 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL A1M.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL A1M.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL A1M",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL A1M",
+ "renamed_from": "Panchroma PLA Stain @BBL A1M",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_02",
"instantiation": "true",
@@ -28,4 +29,4 @@
"slow_down_layer_time": [
"5"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P 0.2 nozzle.json
similarity index 74%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P 0.2 nozzle.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P 0.2 nozzle.json
index 00cf4852a1..e6b2d27440 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P 0.2 nozzle.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P 0.2 nozzle.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL P1P 0.2 nozzle",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL P1P 0.2 nozzle",
+ "renamed_from": "Panchroma PLA Stain @BBL P1P 0.2 nozzle",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_05",
"instantiation": "true",
@@ -26,4 +27,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P.json
similarity index 79%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P.json
index 88678c3159..7e9c805c63 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL P1P.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL P1P.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL P1P",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL P1P",
+ "renamed_from": "Panchroma PLA Stain @BBL P1P",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_04",
"instantiation": "true",
@@ -28,4 +29,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1 0.2 nozzle.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1 0.2 nozzle.json
similarity index 74%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1 0.2 nozzle.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1 0.2 nozzle.json
index 435a9c991a..3a07dcb602 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1 0.2 nozzle.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1 0.2 nozzle.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL X1 0.2 nozzle",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL X1 0.2 nozzle",
+ "renamed_from": "Panchroma PLA Stain @BBL X1 0.2 nozzle",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_07",
"instantiation": "true",
@@ -26,4 +27,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1.json
similarity index 79%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1.json
index e5d9bfdf3a..be4651c5f4 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL X1",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL X1",
+ "renamed_from": "Panchroma PLA Stain @BBL X1",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_06",
"instantiation": "true",
@@ -28,4 +29,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C 0.2 nozzle.json
similarity index 77%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C 0.2 nozzle.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C 0.2 nozzle.json
index d4f02ff39a..0254f8e61e 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C 0.2 nozzle.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C 0.2 nozzle.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL X1C 0.2 nozzle",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL X1C 0.2 nozzle",
+ "renamed_from": "Panchroma PLA Stain @BBL X1C 0.2 nozzle",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_09",
"instantiation": "true",
@@ -28,4 +29,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C.json
similarity index 84%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C.json
index 1d50deee52..0449da66b0 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @BBL X1C.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @BBL X1C.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @BBL X1C",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @BBL X1C",
+ "renamed_from": "Panchroma PLA Stain @BBL X1C",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "GFSPM005_08",
"instantiation": "true",
@@ -34,4 +35,4 @@
"slow_down_layer_time": [
"15"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @base.json b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @base.json
similarity index 88%
rename from resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @base.json
rename to resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @base.json
index b2cb2b8cf3..26d3344d4b 100644
--- a/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Stain @base.json
+++ b/resources/profiles/BBL/filament/Polymaker/Panchroma PLA Satin @base.json
@@ -1,6 +1,7 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @base",
+ "renamed_from": "Panchroma PLA Stain @base",
"inherits": "fdm_filament_pla",
"from": "system",
"filament_id": "GFPM005",
@@ -38,4 +39,4 @@
"temperature_vitrification": [
"59"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/BBL/machine/fdm_machine_common.json b/resources/profiles/BBL/machine/fdm_machine_common.json
index 0073ac6a8a..566d3960ed 100644
--- a/resources/profiles/BBL/machine/fdm_machine_common.json
+++ b/resources/profiles/BBL/machine/fdm_machine_common.json
@@ -136,7 +136,7 @@
"60"
],
"scan_first_layer": "0",
- "enable_power_loss_recovery": "1",
+ "enable_power_loss_recovery": "printer_configuration",
"silent_mode": "0",
"single_extruder_multi_material": "1",
"support_air_filtration": "0",
diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json
index b7c03f3f96..b7605cb457 100644
--- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json
+++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json
@@ -11,6 +11,9 @@
"nozzle_diameter": [
"0.4"
],
+ "nozzle_volume": [
+ "156"
+ ],
"retract_before_wipe": [
"0%"
],
@@ -132,7 +135,7 @@
"0"
],
"parking_pos_retraction": [
- "25"
+ "0"
],
"retract_when_changing_layer": [
"0"
@@ -141,7 +144,10 @@
"0"
],
"high_current_on_filament_swap": [
- "1"
+ "0"
+ ],
+ "enable_filament_ramming": [
+ "0"
],
"z_hop_types": "Spiral Lift"
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json
index 7dabbd7f08..391b37301d 100644
--- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json
+++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json
@@ -11,6 +11,9 @@
"nozzle_diameter": [
"0.4"
],
+ "nozzle_volume": [
+ "156"
+ ],
"retract_before_wipe": [
"0%"
],
@@ -132,7 +135,7 @@
"0"
],
"parking_pos_retraction": [
- "25"
+ "0"
],
"retract_when_changing_layer": [
"0"
@@ -141,7 +144,10 @@
"0"
],
"high_current_on_filament_swap": [
- "1"
+ "0"
+ ],
+ "enable_filament_ramming": [
+ "0"
],
"z_hop_types": "Spiral Lift"
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json
index 518acb39cd..b33d7e5a5c 100644
--- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json
+++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json
@@ -11,6 +11,9 @@
"nozzle_diameter": [
"0.4"
],
+ "nozzle_volume": [
+ "156"
+ ],
"retract_before_wipe": [
"0%"
],
@@ -132,7 +135,7 @@
"0"
],
"parking_pos_retraction": [
- "25"
+ "0"
],
"retract_when_changing_layer": [
"0"
@@ -141,7 +144,10 @@
"0"
],
"high_current_on_filament_swap": [
- "1"
+ "0"
+ ],
+ "enable_filament_ramming": [
+ "0"
],
"z_hop_types": "Spiral Lift"
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json
index 8a49ec2f87..3ee7b4e79b 100644
--- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json
+++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json
@@ -10,6 +10,9 @@
"printer_variant": "0.4",
"nozzle_diameter": [
"0.4"
+ ],
+ "nozzle_volume": [
+ "156"
],
"retract_before_wipe": [
"0%"
@@ -132,7 +135,7 @@
"0"
],
"parking_pos_retraction": [
- "25"
+ "0"
],
"retract_when_changing_layer": [
"0"
@@ -141,7 +144,10 @@
"0"
],
"high_current_on_filament_swap": [
- "1"
+ "0"
+ ],
+ "enable_filament_ramming": [
+ "0"
],
"z_hop_types": "Spiral Lift"
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/Geeetech/Geeetech A10 M_cover.png b/resources/profiles/Geeetech/Geeetech A10 M_cover.png
index 537e84e105..c33288671f 100644
Binary files a/resources/profiles/Geeetech/Geeetech A10 M_cover.png and b/resources/profiles/Geeetech/Geeetech A10 M_cover.png differ
diff --git a/resources/profiles/Ginger Additive/ginger G1_cover.png b/resources/profiles/Ginger Additive/Ginger G1_cover.png
similarity index 100%
rename from resources/profiles/Ginger Additive/ginger G1_cover.png
rename to resources/profiles/Ginger Additive/Ginger G1_cover.png
diff --git a/resources/profiles/M3D/M3D Enabler D8500 MM Model_cover.png b/resources/profiles/M3D/M3D Enabler D8500 MM Model_cover.png
index eb067195cf..50020d51b7 100644
Binary files a/resources/profiles/M3D/M3D Enabler D8500 MM Model_cover.png and b/resources/profiles/M3D/M3D Enabler D8500 MM Model_cover.png differ
diff --git a/resources/profiles/MagicMaker/MM hj sk_cover.png b/resources/profiles/MagicMaker/MM hj SK_cover.png
similarity index 100%
rename from resources/profiles/MagicMaker/MM hj sk_cover.png
rename to resources/profiles/MagicMaker/MM hj SK_cover.png
diff --git a/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json b/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json
index 4528b72fe1..2912a51b45 100644
--- a/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json
+++ b/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json
@@ -4,6 +4,9 @@
"from": "system",
"inherits": "fdm_openeye_common",
"instantiation": "true",
+ "adaptive_bed_mesh_margin": "10",
+ "bed_mesh_max": "211,211",
+ "bed_mesh_min": "1.5,7",
"layer_change_gcode": "SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}\n_MMU_UPDATE_HEIGHT",
"machine_end_gcode": "MMU_END\nEND_PRINT",
"machine_load_filament_time": "30",
@@ -24,8 +27,8 @@
"30"
],
"machine_pause_gcode": "PAUSE",
- "machine_start_gcode": "SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nMMU_START_SETUP INITIAL_TOOL={initial_tool} TOTAL_TOOLCHANGES=!total_toolchanges! REFERENCED_TOOLS=!referenced_tools! TOOL_COLORS=!colors! TOOL_TEMPS=!temperatures! TOOL_MATERIALS=!materials! FILAMENT_NAMES=!filament_names! PURGE_VOLUMES=!purge_volumes!\nMMU_START_CHECK\nSTART_PRINT BED_TEMP=[bed_temperature_initial_layer] EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TYPE=\"{curr_bed_type}\"\n; Enter YOUR exist start_print macro call here (minus purging logic because tool may not be loaded yet)\nMMU_START_LOAD_INITIAL_TOOL\n; Optionally add YOUR additional start logic (like purging) here to run just prior to start\nSTART_PRINT_SECONDARY\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} ; For pause at layer functionality and better print stats",
- "machine_unload_filament_time": "30",
+ "machine_start_gcode": "SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nMMU_START_SETUP INITIAL_TOOL={initial_tool} TOTAL_TOOLCHANGES=!total_toolchanges! REFERENCED_TOOLS=!referenced_tools! TOOL_COLORS=!colors! TOOL_TEMPS=!temperatures! TOOL_MATERIALS=!materials! FILAMENT_NAMES=!filament_names! PURGE_VOLUMES=!purge_volumes!\nMMU_START_CHECK\nSTART_PRINT BED_TEMP=[bed_temperature_initial_layer] EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TYPE=\"{curr_bed_type}\" MESH_MIN={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} MESH_MAX={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE_MARGIN={adaptive_bed_mesh_margin}\n; Enter YOUR exist start_print macro call here (minus purging logic because tool may not be loaded yet)\nMMU_START_LOAD_INITIAL_TOOL\n; Optionally add YOUR additional start logic (like purging) here to run just prior to start\nSTART_PRINT_SECONDARY\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} ; For pause at layer functionality and better print stats",
+ "machine_unload_filament_time": "30",
"name": "OpenEYE Peacock V2 0.4 nozzle",
"nozzle_diameter": [
"0.4"
@@ -45,4 +48,4 @@
],
"setting_id": "GM001",
"type": "machine"
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/OpenEYE/machine/fdm_openeye_common.json b/resources/profiles/OpenEYE/machine/fdm_openeye_common.json
index 130e3b189f..a428532958 100644
--- a/resources/profiles/OpenEYE/machine/fdm_openeye_common.json
+++ b/resources/profiles/OpenEYE/machine/fdm_openeye_common.json
@@ -124,8 +124,8 @@
"0"
],
"machine_pause_gcode": "PAUSE",
- "machine_start_gcode": "SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nMMU_START_SETUP INITIAL_TOOL={initial_tool} TOTAL_TOOLCHANGES=!total_toolchanges! REFERENCED_TOOLS=!referenced_tools! TOOL_COLORS=!colors! TOOL_TEMPS=!temperatures! TOOL_MATERIALS=!materials! FILAMENT_NAMES=!filament_names! PURGE_VOLUMES=!purge_volumes!\nMMU_START_CHECK\nSTART_PRINT BED_TEMP=[bed_temperature_initial_layer] EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TYPE=\"{curr_bed_type}\"\n; Enter YOUR exist start_print macro call here (minus purging logic because tool may not be loaded yet)\nMMU_START_LOAD_INITIAL_TOOL\n; Optionally add YOUR additional start logic (like purging) here to run just prior to start\nSTART_PRINT_SECONDARY\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} ; For pause at layer functionality and better print stats",
- "machine_tool_change_time": "0",
+ "machine_start_gcode": "SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nMMU_START_SETUP INITIAL_TOOL={initial_tool} TOTAL_TOOLCHANGES=!total_toolchanges! REFERENCED_TOOLS=!referenced_tools! TOOL_COLORS=!colors! TOOL_TEMPS=!temperatures! TOOL_MATERIALS=!materials! FILAMENT_NAMES=!filament_names! PURGE_VOLUMES=!purge_volumes!\nMMU_START_CHECK\nSTART_PRINT BED_TEMP=[bed_temperature_initial_layer] EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TYPE=\"{curr_bed_type}\" MESH_MIN={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} MESH_MAX={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE_MARGIN={adaptive_bed_mesh_margin}\n; Enter YOUR exist start_print macro call here (minus purging logic because tool may not be loaded yet)\nMMU_START_LOAD_INITIAL_TOOL\n; Optionally add YOUR additional start logic (like purging) here to run just prior to start\nSTART_PRINT_SECONDARY\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} ; For pause at layer functionality and better print stats",
+ "machine_tool_change_time": "0",
"machine_unload_filament_time": "0",
"manual_filament_change": "0",
"max_layer_height": [
diff --git a/resources/profiles/OrcaFilamentLibrary.json b/resources/profiles/OrcaFilamentLibrary.json
index 1f4b2cf779..8e6ac439b1 100644
--- a/resources/profiles/OrcaFilamentLibrary.json
+++ b/resources/profiles/OrcaFilamentLibrary.json
@@ -108,6 +108,10 @@
"name": "COEX ABS PRIME @base",
"sub_path": "filament/COEX/COEX ABS PRIME @base.json"
},
+ {
+ "name": "Eolas Prints ABS @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints ABS @System.json"
+ },
{
"name": "FDplast ABS @base",
"sub_path": "filament/FDplast/FDplast ABS @base.json"
@@ -144,6 +148,10 @@
"name": "COEX ASA PRIME @base",
"sub_path": "filament/COEX/COEX ASA PRIME @base.json"
},
+ {
+ "name": "Eolas Prints ASA @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints ASA @System.json"
+ },
{
"name": "Generic ASA @System",
"sub_path": "filament/Generic ASA @System.json"
@@ -288,6 +296,18 @@
"name": "COEX PETG @base",
"sub_path": "filament/COEX/COEX PETG @base.json"
},
+ {
+ "name": "Eolas Prints PETG @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PETG @System.json"
+ },
+ {
+ "name": "Eolas Prints PETG Transition @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PETG Transition @System.json"
+ },
+ {
+ "name": "Eolas Prints PETG UV Resistant @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json"
+ },
{
"name": "FDplast PETG @base",
"sub_path": "filament/FDplast/FDplast PETG @base.json"
@@ -420,6 +440,42 @@
"name": "COEX PLA PRIME @base",
"sub_path": "filament/COEX/COEX PLA PRIME @base.json"
},
+ {
+ "name": "Eolas Prints PLA Antibacterial @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA High Speed @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA High Speed @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA INGEO 850 @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA INGEO 870 @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA Matte @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Matte @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA Neon @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Neon @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA Premium @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Premium @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA Silk @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Silk @System.json"
+ },
+ {
+ "name": "Eolas Prints PLA Transition @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints PLA Transition @System.json"
+ },
{
"name": "FDplast PLA @base",
"sub_path": "filament/FDplast/FDplast PLA @base.json"
@@ -444,6 +500,10 @@
"name": "NIT PLA @base",
"sub_path": "filament/NIT/NIT PLA @base.json"
},
+ {
+ "name": "Numakers PLA+ @base",
+ "sub_path": "filament/Numakers/Numakers PLA+ @base.json"
+ },
{
"name": "Overture Air PLA @base",
"sub_path": "filament/Overture/Overture Air PLA @base.json"
@@ -517,12 +577,12 @@
"sub_path": "filament/Polymaker/Panchroma PLA Neon @base.json"
},
{
- "name": "Panchroma PLA Silk @base",
- "sub_path": "filament/Polymaker/Panchroma PLA Silk @base.json"
+ "name": "Panchroma PLA Satin @base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @base.json"
},
{
- "name": "Panchroma PLA Stain @base",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @base.json"
+ "name": "Panchroma PLA Silk @base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Silk @base.json"
},
{
"name": "Panchroma PLA Starlight @base",
@@ -680,6 +740,22 @@
"name": "COEX TPU 60A @base",
"sub_path": "filament/COEX/COEX TPU 60A @base.json"
},
+ {
+ "name": "Eolas Prints TPU D60 UV Resistant @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json"
+ },
+ {
+ "name": "Eolas Prints TPU Flex 93A @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json"
+ },
+ {
+ "name": "Eolas Prints TPU Flex D53 @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json"
+ },
+ {
+ "name": "Eolas Prints TPU Transition @System",
+ "sub_path": "filament/Eolas Prints/Eolas Prints TPU Transition @System.json"
+ },
{
"name": "FDplast TPU @base",
"sub_path": "filament/FDplast/FDplast TPU @base.json"
@@ -692,10 +768,6 @@
"name": "Overture TPU @base",
"sub_path": "filament/Overture/Overture TPU @base.json"
},
- {
- "name": "Numakers PLA+ @base",
- "sub_path": "filament/Numakers/Numakers PLA+ @base.json"
- },
{
"name": "Bambu ABS @System",
"sub_path": "filament/Bambu/Bambu ABS @System.json"
@@ -980,6 +1052,10 @@
"name": "NIT PLA @System",
"sub_path": "filament/NIT/NIT PLA @System.json"
},
+ {
+ "name": "Numakers PLA+ @System",
+ "sub_path": "filament/Numakers/Numakers PLA+ @System.json"
+ },
{
"name": "Overture Air PLA @System",
"sub_path": "filament/Overture/Overture Air PLA @System.json"
@@ -1053,12 +1129,12 @@
"sub_path": "filament/Polymaker/Panchroma PLA Neon @System.json"
},
{
- "name": "Panchroma PLA Silk @System",
- "sub_path": "filament/Polymaker/Panchroma PLA Silk @System.json"
+ "name": "Panchroma PLA Satin @System",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @System.json"
},
{
- "name": "Panchroma PLA Stain @System",
- "sub_path": "filament/Polymaker/Panchroma PLA Stain @System.json"
+ "name": "Panchroma PLA Silk @System",
+ "sub_path": "filament/Polymaker/Panchroma PLA Silk @System.json"
},
{
"name": "Panchroma PLA Starlight @System",
@@ -1211,81 +1287,6 @@
{
"name": "COEX PLA+Silk @System",
"sub_path": "filament/COEX/COEX PLA+Silk @System.json"
- },
- { "name": "Numakers PLA+ @System",
- "sub_path": "filament/Numakers/Numakers PLA+ @System.json"
- },
- {
- "name": "Eolas Prints PLA Premium @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Premium @System.json"
- },
- {
- "name": "Eolas Prints PLA Matte @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Matte @System.json"
- },
- {
- "name": "Eolas Prints PLA Silk @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Silk @System.json"
- },
- {
- "name": "Eolas Prints PLA Neon @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Neon @System.json"
- },
- {
- "name": "Eolas Prints PLA High Speed @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA High Speed @System.json"
- },
- {
- "name": "Eolas Prints PLA INGEO 850 @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json"
- },
- {
- "name": "Eolas Prints PLA INGEO 870 @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json"
- },
- {
- "name": "Eolas Prints PLA Antibacterial @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json"
- },
- {
- "name": "Eolas Prints PLA Transition @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PLA Transition @System.json"
- },
- {
- "name": "Eolas Prints PETG @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PETG @System.json"
- },
- {
- "name": "Eolas Prints PETG UV Resistant @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json"
- },
- {
- "name": "Eolas Prints PETG Transition @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints PETG Transition @System.json"
- },
- {
- "name": "Eolas Prints TPU Flex 93A @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json"
- },
- {
- "name": "Eolas Prints TPU Flex D53 @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json"
- },
- {
- "name": "Eolas Prints TPU Flex D60 UV Resistant @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json"
- },
- {
- "name": "Eolas Prints TPU Transition @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints TPU Transition @System.json"
- },
- {
- "name": "Eolas Prints ABS @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints ABS @System.json"
- },
- {
- "name": "Eolas Prints ASA @System",
- "sub_path": "filament/Eolas Prints/Eolas Prints ASA @System.json"
}
],
"process_list": [],
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @System.json
similarity index 60%
rename from resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @System.json
rename to resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @System.json
index 96e40e373f..bbb5b658f6 100644
--- a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @System.json
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @System.json
@@ -1,7 +1,8 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @System",
- "inherits": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @System",
+ "renamed_from": "Panchroma PLA Stain @System",
+ "inherits": "Panchroma PLA Satin @base",
"from": "system",
"setting_id": "OGFSPM005",
"instantiation": "true",
@@ -11,4 +12,4 @@
"filament_max_volumetric_speed": [
"16"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @base.json
similarity index 87%
rename from resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @base.json
rename to resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @base.json
index 4021abe0c3..a3ae93632b 100644
--- a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Stain @base.json
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/Panchroma PLA Satin @base.json
@@ -1,6 +1,7 @@
{
"type": "filament",
- "name": "Panchroma PLA Stain @base",
+ "name": "Panchroma PLA Satin @base",
+ "renamed_from": "Panchroma PLA Stain @base",
"inherits": "fdm_filament_pla",
"from": "system",
"filament_id": "OGFPM005",
@@ -32,4 +33,4 @@
"temperature_vitrification": [
"59"
]
-}
\ No newline at end of file
+}
diff --git a/resources/profiles/Snapmaker.json b/resources/profiles/Snapmaker.json
index e5b3b2b155..a468a8edf1 100644
--- a/resources/profiles/Snapmaker.json
+++ b/resources/profiles/Snapmaker.json
@@ -462,7 +462,7 @@
"filament_list": [
{
"name": "PolyTerra PLA @0.2 nozzle",
- "sub_path": "filament/PolyTerra PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyTerra PLA @0.2 nozzle.json"
},
{
"name": "Snapmaker PLA Lite @U1 base",
@@ -482,11 +482,11 @@
},
{
"name": "PolyTerra Dual PLA @0.2 nozzle",
- "sub_path": "filament/PolyTerra Dual PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json"
},
{
"name": "PolyTerra J1 PLA @0.2 nozzle",
- "sub_path": "filament/PolyTerra J1 PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json"
},
{
"name": "Snapmaker PLA Lite @U1",
@@ -608,6 +608,14 @@
"name": "Snapmaker PET @base",
"sub_path": "filament/Snapmaker PET @base.json"
},
+ {
+ "name": "PolyLite PETG @Base",
+ "sub_path": "filament/Polymaker/PolyLite PETG @Base.json"
+ },
+ {
+ "name": "Polymaker PETG @Base",
+ "sub_path": "filament/Polymaker/Polymaker PETG @Base.json"
+ },
{
"name": "Snapmaker Dual PETG @base",
"sub_path": "filament/Snapmaker Dual PETG @base.json"
@@ -640,17 +648,105 @@
"name": "Snapmaker PETG-CF @base",
"sub_path": "filament/Snapmaker PETG-CF @base.json"
},
+ {
+ "name": "Panchroma CoPE @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma CoPE @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Celestial @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Celestial @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Galaxy @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Galaxy @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Glow @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Glow @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Luminous @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Luminous @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Marble @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Marble @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Matte @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Matte @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Metallic @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Metallic @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Neon @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Neon @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Silk @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Silk @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Starlight @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Starlight @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Temp Shift @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Temp Shift @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA Translucent @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA Translucent @U1 base.json"
+ },
+ {
+ "name": "Panchroma PLA UV Shift @U1 base",
+ "sub_path": "filament/Polymaker/Panchroma PLA UV Shift @U1 base.json"
+ },
{
"name": "PolyLite PLA @U1 base",
- "sub_path": "filament/PolyLite PLA @U1 base.json"
+ "sub_path": "filament/Polymaker/PolyLite PLA @U1 base.json"
},
{
"name": "PolyLite PLA @base",
- "sub_path": "filament/PolyLite PLA @base.json"
+ "sub_path": "filament/Polymaker/PolyLite PLA @base.json"
+ },
+ {
+ "name": "PolyLite PLA Pro @U1 base",
+ "sub_path": "filament/Polymaker/PolyLite PLA Pro @U1 base.json"
},
{
"name": "PolyTerra PLA @U1 base",
- "sub_path": "filament/PolyTerra PLA @U1 base.json"
+ "sub_path": "filament/Polymaker/PolyTerra PLA @U1 base.json"
+ },
+ {
+ "name": "Polymaker HT-PLA @Base",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA @Base.json"
+ },
+ {
+ "name": "Polymaker HT-PLA @U1 base",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA @U1 base.json"
+ },
+ {
+ "name": "Polymaker HT-PLA-GF @Base",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA-GF @Base.json"
+ },
+ {
+ "name": "Polymaker HT-PLA-GF @U1 base",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA-GF @U1 base.json"
+ },
+ {
+ "name": "Polymaker PLA Pro @Base",
+ "sub_path": "filament/Polymaker/Polymaker PLA Pro @Base.json"
},
{
"name": "Snapmaker Dual PLA @base",
@@ -884,6 +980,14 @@
"name": "Snapmaker PET",
"sub_path": "filament/Snapmaker PET.json"
},
+ {
+ "name": "PolyLite PETG @Snapmaker U1",
+ "sub_path": "filament/Polymaker/PolyLite PETG @Snapmaker U1.json"
+ },
+ {
+ "name": "Polymaker PETG @Snapmaker U1",
+ "sub_path": "filament/Polymaker/Polymaker PETG @Snapmaker U1.json"
+ },
{
"name": "Snapmaker Dual PETG",
"sub_path": "filament/Snapmaker Dual PETG.json"
@@ -936,21 +1040,109 @@
"name": "Snapmaker PETG-CF",
"sub_path": "filament/Snapmaker PETG-CF.json"
},
+ {
+ "name": "Panchroma CoPE @U1",
+ "sub_path": "filament/Polymaker/Panchroma CoPE @U1.json"
+ },
+ {
+ "name": "Panchroma PLA @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Celestial @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Celestial @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Galaxy @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Galaxy @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Glow @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Glow @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Luminous @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Luminous @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Marble @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Marble @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Matte @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Matte @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Metallic @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Metallic @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Neon @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Neon @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Satin @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Satin @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Silk @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Silk @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Starlight @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Starlight @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Temp Shift @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Temp Shift @U1.json"
+ },
+ {
+ "name": "Panchroma PLA Translucent @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA Translucent @U1.json"
+ },
+ {
+ "name": "Panchroma PLA UV Shift @U1",
+ "sub_path": "filament/Polymaker/Panchroma PLA UV Shift @U1.json"
+ },
{
"name": "PolyLite PLA @U1",
- "sub_path": "filament/PolyLite PLA @U1.json"
+ "sub_path": "filament/Polymaker/PolyLite PLA @U1.json"
},
{
"name": "PolyLite J1 PLA",
- "sub_path": "filament/PolyLite J1 PLA.json"
+ "sub_path": "filament/Polymaker/PolyLite J1 PLA.json"
},
{
"name": "PolyLite PLA @0.2 nozzle",
- "sub_path": "filament/PolyLite PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyLite PLA @0.2 nozzle.json"
+ },
+ {
+ "name": "PolyLite PLA Pro @U1",
+ "sub_path": "filament/Polymaker/PolyLite PLA Pro @U1.json"
},
{
"name": "PolyTerra PLA @U1",
- "sub_path": "filament/PolyTerra PLA @U1.json"
+ "sub_path": "filament/Polymaker/PolyTerra PLA @U1.json"
+ },
+ {
+ "name": "Polymaker HT-PLA @Snapmaker U1",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA @Snapmaker U1.json"
+ },
+ {
+ "name": "Polymaker HT-PLA @U1",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA @U1.json"
+ },
+ {
+ "name": "Polymaker HT-PLA-GF @Snapmaker U1",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA-GF @Snapmaker U1.json"
+ },
+ {
+ "name": "Polymaker HT-PLA-GF @U1",
+ "sub_path": "filament/Polymaker/Polymaker HT-PLA-GF @U1.json"
+ },
+ {
+ "name": "Polymaker PLA Pro @Snapmaker U1",
+ "sub_path": "filament/Polymaker/Polymaker PLA Pro @Snapmaker U1.json"
},
{
"name": "Snapmaker Dual PLA",
@@ -1158,11 +1350,11 @@
},
{
"name": "PolyLite Dual PLA @0.2 nozzle",
- "sub_path": "filament/PolyLite Dual PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json"
},
{
"name": "PolyLite J1 PLA @0.2 nozzle",
- "sub_path": "filament/PolyLite J1 PLA @0.2 nozzle.json"
+ "sub_path": "filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json"
},
{
"name": "Snapmaker Dual PLA Eco",
@@ -1206,7 +1398,7 @@
},
{
"name": "PolyTerra J1 PLA",
- "sub_path": "filament/PolyTerra J1 PLA.json"
+ "sub_path": "filament/Polymaker/PolyTerra J1 PLA.json"
},
{
"name": "Snapmaker PLA Matte @U1 base",
diff --git a/resources/profiles/Snapmaker/filament/PolyLite Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyLite Dual PLA @0.2 nozzle.json
deleted file mode 100644
index 6528cd8ca0..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite Dual PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite Dual PLA @0.2 nozzle",
- "inherits": "PolyLite PLA @0.2 nozzle",
- "from": "system",
- "setting_id": "490991920",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker A250 Dual (0.2 nozzle)",
- "Snapmaker A250 Dual BKit (0.2 nozzle)",
- "Snapmaker A250 Dual QS+B Kit (0.2 nozzle)",
- "Snapmaker A250 Dual QSKit (0.2 nozzle)",
- "Snapmaker A350 Dual (0.2 nozzle)",
- "Snapmaker A350 Dual BKit (0.2 nozzle)",
- "Snapmaker A350 Dual QS+B Kit (0.2 nozzle)",
- "Snapmaker A350 Dual QSKit (0.2 nozzle)",
- "Snapmaker Artisan (0.2 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyLite J1 PLA @0.2 nozzle.json
deleted file mode 100644
index 65a87c28d8..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite J1 PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite J1 PLA @0.2 nozzle",
- "inherits": "PolyLite PLA @0.2 nozzle",
- "from": "system",
- "setting_id": "431382384",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker J1 (0.2 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite J1 PLA.json b/resources/profiles/Snapmaker/filament/PolyLite J1 PLA.json
deleted file mode 100644
index 0d09c5528a..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite J1 PLA.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite J1 PLA",
- "inherits": "PolyLite PLA @base",
- "from": "system",
- "setting_id": "116125055",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker J1 (0.4 nozzle)",
- "Snapmaker J1 (0.6 nozzle)",
- "Snapmaker J1 (0.8 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyLite PLA @0.2 nozzle.json
deleted file mode 100644
index 69999b740a..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite PLA @0.2 nozzle",
- "inherits": "PolyLite PLA @base",
- "from": "system",
- "setting_id": "1592803578",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker A250 (0.2 nozzle)",
- "Snapmaker A250 BKit (0.2 nozzle)",
- "Snapmaker A250 QS+B Kit (0.2 nozzle)",
- "Snapmaker A250 QSKit (0.2 nozzle)",
- "Snapmaker A350 (0.2 nozzle)",
- "Snapmaker A350 BKit (0.2 nozzle)",
- "Snapmaker A350 QS+B Kit (0.2 nozzle)",
- "Snapmaker A350 QSKit (0.2 nozzle)"
- ],
- "filament_max_volumetric_speed": [
- "1.6"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite PLA @U1 base.json b/resources/profiles/Snapmaker/filament/PolyLite PLA @U1 base.json
deleted file mode 100644
index fb9c55cdc7..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite PLA @U1 base.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite PLA @U1 base",
- "inherits": "fdm_filament_pla",
- "from": "system",
- "filament_id": "13938660340",
- "instantiation": "false",
- "filament_flow_ratio": [
- "0.95"
- ],
- "filament_cost": [
- "90"
- ],
- "filament_max_volumetric_speed": [
- "15"
- ],
- "default_filament_colour": [
- ""
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite PLA @U1.json b/resources/profiles/Snapmaker/filament/PolyLite PLA @U1.json
deleted file mode 100644
index 0648fdde39..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite PLA @U1.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite PLA @U1",
- "inherits": "PolyLite PLA @U1 base",
- "from": "system",
- "setting_id": "6486836500",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker U1 (0.4 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyLite PLA @base.json b/resources/profiles/Snapmaker/filament/PolyLite PLA @base.json
deleted file mode 100644
index e4db1c70b6..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyLite PLA @base.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "filament",
- "name": "PolyLite PLA @base",
- "inherits": "fdm_filament_pla",
- "from": "system",
- "filament_id": "1393866034",
- "instantiation": "false",
- "filament_flow_ratio": [
- "0.95"
- ],
- "filament_cost": [
- "90"
- ],
- "filament_max_volumetric_speed": [
- "15"
- ],
- "default_filament_colour": [
- ""
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyTerra Dual PLA @0.2 nozzle.json
deleted file mode 100644
index 9ce3e9f972..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra Dual PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra Dual PLA @0.2 nozzle",
- "inherits": "PolyTerra PLA @0.2 nozzle",
- "from": "system",
- "setting_id": "1258531391",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker A250 Dual (0.2 nozzle)",
- "Snapmaker A250 Dual BKit (0.2 nozzle)",
- "Snapmaker A250 Dual QS+B Kit (0.2 nozzle)",
- "Snapmaker A250 Dual QSKit (0.2 nozzle)",
- "Snapmaker A350 Dual (0.2 nozzle)",
- "Snapmaker A350 Dual BKit (0.2 nozzle)",
- "Snapmaker A350 Dual QS+B Kit (0.2 nozzle)",
- "Snapmaker A350 Dual QSKit (0.2 nozzle)",
- "Snapmaker Artisan (0.2 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA @0.2 nozzle.json
deleted file mode 100644
index a2f99fd132..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra J1 PLA @0.2 nozzle",
- "inherits": "PolyTerra PLA @0.2 nozzle",
- "from": "system",
- "setting_id": "1072374370",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker J1 (0.2 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA.json b/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA.json
deleted file mode 100644
index c696f52735..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra J1 PLA.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra J1 PLA",
- "inherits": "PolyTerra PLA @base",
- "from": "system",
- "setting_id": "3958200796",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker J1 (0.4 nozzle)",
- "Snapmaker J1 (0.6 nozzle)",
- "Snapmaker J1 (0.8 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/PolyTerra PLA @0.2 nozzle.json
deleted file mode 100644
index f996844ce1..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra PLA @0.2 nozzle.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra PLA @0.2 nozzle",
- "inherits": "PolyTerra PLA @base",
- "from": "system",
- "setting_id": "409934824",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker A250 (0.2 nozzle)",
- "Snapmaker A250 BKit (0.2 nozzle)",
- "Snapmaker A250 QS+B Kit (0.2 nozzle)",
- "Snapmaker A250 QSKit (0.2 nozzle)",
- "Snapmaker A350 (0.2 nozzle)",
- "Snapmaker A350 BKit (0.2 nozzle)",
- "Snapmaker A350 QS+B Kit (0.2 nozzle)",
- "Snapmaker A350 QSKit (0.2 nozzle)"
- ],
- "filament_max_volumetric_speed": [
- "1.4"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1 base.json b/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1 base.json
deleted file mode 100644
index 3b7b9a8b94..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1 base.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra PLA @U1 base",
- "inherits": "fdm_filament_pla",
- "from": "system",
- "filament_id": "37895926870",
- "instantiation": "false",
- "filament_cost": [
- "80"
- ],
- "filament_density": [
- "1.31"
- ],
- "filament_max_volumetric_speed": [
- "14.4"
- ],
- "default_filament_colour": [
- ""
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1.json b/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1.json
deleted file mode 100644
index 478c008d7a..0000000000
--- a/resources/profiles/Snapmaker/filament/PolyTerra PLA @U1.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "filament",
- "name": "PolyTerra PLA @U1",
- "inherits": "PolyTerra PLA @U1 base",
- "from": "system",
- "setting_id": "12580059400",
- "instantiation": "true",
- "compatible_printers": [
- "Snapmaker U1 (0.4 nozzle)"
- ]
-}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1 base.json
new file mode 100644
index 0000000000..1575543964
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma CoPE @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM016",
+ "instantiation": "false",
+ "filament_cost": [
+ "19.99"
+ ],
+ "filament_density": [
+ "1.29"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "230"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "230"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "58"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1.json
new file mode 100644
index 0000000000..abd252e87a
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma CoPE @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma CoPE @U1",
+ "inherits": "Panchroma CoPE @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM016_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1 base.json
new file mode 100644
index 0000000000..a09edc3df1
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1 base.json
@@ -0,0 +1,44 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM001",
+ "instantiation": "false",
+ "filament_cost": [
+ "19.99"
+ ],
+ "filament_density": [
+ "1.32"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "filament_wipe": [
+ "0"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "58"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1.json
new file mode 100644
index 0000000000..a77038834b
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA @U1",
+ "inherits": "Panchroma PLA @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM001_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1 base.json
new file mode 100644
index 0000000000..305c3b8476
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Celestial @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM008",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1.json
new file mode 100644
index 0000000000..cfd1b918b1
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Celestial @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Celestial @U1",
+ "inherits": "Panchroma PLA Celestial @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM008_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1 base.json
new file mode 100644
index 0000000000..9129ce17a7
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Galaxy @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM007",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1.json
new file mode 100644
index 0000000000..465e8b461d
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Galaxy @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Galaxy @U1",
+ "inherits": "Panchroma PLA Galaxy @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM007_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1 base.json
new file mode 100644
index 0000000000..21177be0db
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Glow @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM010",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1.json
new file mode 100644
index 0000000000..5cbf021349
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Glow @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Glow @U1",
+ "inherits": "Panchroma PLA Glow @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM010_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1 base.json
new file mode 100644
index 0000000000..c8afc7bc16
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Luminous @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM011",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1.json
new file mode 100644
index 0000000000..7747c1ccfb
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Luminous @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Luminous @U1",
+ "inherits": "Panchroma PLA Luminous @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM011_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1 base.json
new file mode 100644
index 0000000000..8a462959a8
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Marble @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM003",
+ "instantiation": "false",
+ "filament_cost": [
+ "21.99"
+ ],
+ "filament_density": [
+ "1.31"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1.json
new file mode 100644
index 0000000000..8fb2780b8f
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Marble @U1.json
@@ -0,0 +1,23 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Marble @U1",
+ "inherits": "Panchroma PLA Marble @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM003_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1 base.json
new file mode 100644
index 0000000000..9ab72e1484
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Matte @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM002",
+ "instantiation": "false",
+ "filament_cost": [
+ "20.99"
+ ],
+ "filament_density": [
+ "1.31"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1.json
new file mode 100644
index 0000000000..9823adaa0c
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Matte @U1.json
@@ -0,0 +1,23 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Matte @U1",
+ "inherits": "Panchroma PLA Matte @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM002_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1 base.json
new file mode 100644
index 0000000000..f9a33ba035
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Metallic @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM012",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1.json
new file mode 100644
index 0000000000..0196929a54
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Metallic @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Metallic @U1",
+ "inherits": "Panchroma PLA Metallic @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM012_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1 base.json
new file mode 100644
index 0000000000..70332dc961
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Neon @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM013",
+ "instantiation": "false",
+ "filament_cost": [
+ "24.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1.json
new file mode 100644
index 0000000000..cc5ab3fbaf
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Neon @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Neon @U1",
+ "inherits": "Panchroma PLA Neon @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM013_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1 base.json
new file mode 100644
index 0000000000..1f38ea1a45
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1 base.json
@@ -0,0 +1,42 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Satin @U1 base",
+ "renamed_from": "Panchroma PLA Stain @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM005",
+ "instantiation": "false",
+ "filament_cost": [
+ "20.99"
+ ],
+ "filament_density": [
+ "1.24"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "230"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "230"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "59"
+ ]
+}
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1.json
new file mode 100644
index 0000000000..6e914b56a4
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Satin @U1.json
@@ -0,0 +1,27 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Satin @U1",
+ "renamed_from": "Panchroma PLA Stain @U1",
+ "inherits": "Panchroma PLA Satin @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM005_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1 base.json
new file mode 100644
index 0000000000..43e9f98164
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Silk @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM004",
+ "instantiation": "false",
+ "filament_cost": [
+ "24.99"
+ ],
+ "filament_density": [
+ "1.31"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "230"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "230"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "58"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1.json
new file mode 100644
index 0000000000..52102ab63b
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Silk @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Silk @U1",
+ "inherits": "Panchroma PLA Silk @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM004_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1 base.json
new file mode 100644
index 0000000000..0c9fd9bf52
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Starlight @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM009",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1.json
new file mode 100644
index 0000000000..9029dc250c
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Starlight @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Starlight @U1",
+ "inherits": "Panchroma PLA Starlight @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM009_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1 base.json
new file mode 100644
index 0000000000..c86779555f
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Temp Shift @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM015",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1.json
new file mode 100644
index 0000000000..5d7e17696b
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Temp Shift @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Temp Shift @U1",
+ "inherits": "Panchroma PLA Temp Shift @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM015_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1 base.json
new file mode 100644
index 0000000000..cb786e6f9a
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Translucent @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM006",
+ "instantiation": "false",
+ "filament_cost": [
+ "24.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1.json
new file mode 100644
index 0000000000..6e35878869
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA Translucent @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA Translucent @U1",
+ "inherits": "Panchroma PLA Translucent @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM006_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1 base.json
new file mode 100644
index 0000000000..c209198398
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA UV Shift @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM014",
+ "instantiation": "false",
+ "filament_cost": [
+ "29.99"
+ ],
+ "filament_density": [
+ "1.17"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "240"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1.json
new file mode 100644
index 0000000000..f85802624c
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Panchroma PLA UV Shift @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Panchroma PLA UV Shift @U1",
+ "inherits": "Panchroma PLA UV Shift @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM014_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..f47614d710
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json
@@ -0,0 +1,19 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyLite Dual PLA @0.2 nozzle",
+ "setting_id": "490991920",
+ "inherits": "PolyLite PLA @0.2 nozzle",
+ "compatible_printers": [
+ "Snapmaker A250 Dual (0.2 nozzle)",
+ "Snapmaker A250 Dual BKit (0.2 nozzle)",
+ "Snapmaker A250 Dual QS+B Kit (0.2 nozzle)",
+ "Snapmaker A250 Dual QSKit (0.2 nozzle)",
+ "Snapmaker A350 Dual (0.2 nozzle)",
+ "Snapmaker A350 Dual BKit (0.2 nozzle)",
+ "Snapmaker A350 Dual QS+B Kit (0.2 nozzle)",
+ "Snapmaker A350 Dual QSKit (0.2 nozzle)",
+ "Snapmaker Artisan (0.2 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..4e2b21f785
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json
@@ -0,0 +1,11 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyLite J1 PLA @0.2 nozzle",
+ "setting_id": "431382384",
+ "inherits": "PolyLite PLA @0.2 nozzle",
+ "compatible_printers": [
+ "Snapmaker J1 (0.2 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json
new file mode 100644
index 0000000000..ac3cdd9ba9
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json
@@ -0,0 +1,13 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyLite J1 PLA",
+ "setting_id": "116125055",
+ "inherits": "PolyLite PLA @base",
+ "compatible_printers": [
+ "Snapmaker J1 (0.4 nozzle)",
+ "Snapmaker J1 (0.6 nozzle)",
+ "Snapmaker J1 (0.8 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Base.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Base.json
new file mode 100644
index 0000000000..ed8ea01808
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Base.json
@@ -0,0 +1,29 @@
+{
+ "filament_density": [
+ "1.25"
+ ],
+ "temp_min": [
+ "230"
+ ],
+ "temp_max": [
+ "240"
+ ],
+ "temperture_vitrification": [
+ "75"
+ ],
+ "idle_temperture": [
+ "0"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "description": "",
+ "inherits": "fdm_filament_petg",
+ "name": "PolyLite PETG @Base",
+ "type": "filament",
+ "instantiation": "false",
+ "from": "system",
+ "filament_vendor": [
+ "Polymaker"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Snapmaker U1.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Snapmaker U1.json
new file mode 100644
index 0000000000..2e8a0e0943
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PETG @Snapmaker U1.json
@@ -0,0 +1,117 @@
+{
+ "type": "filament",
+ "name": "PolyLite PETG @Snapmaker U1",
+ "from": "system",
+ "instantiation": "true",
+ "cool_plate_temp": [
+ "60"
+ ],
+ "eng_plate_temp": [
+ "0"
+ ],
+ "hot_plate_temp": [
+ "80"
+ ],
+ "textured_plate_temp": [
+ "80"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "80"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "80"
+ ],
+ "overhang_fan_threshold": [
+ "95%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "0.92"
+ ],
+ "fan_cooling_layer_time": [
+ "20"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "7.5"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "40"
+ ],
+ "fan_min_speed": [
+ "0"
+ ],
+ "slow_down_min_speed": [
+ "10"
+ ],
+ "slow_down_layer_time": [
+ "6"
+ ],
+ "filament_start_gcode": [
+ "; Filament gcode\n"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "81"
+ ],
+ "filament_id": "PMPE04",
+ "nozzle_temperature_range_high": [
+ "260"
+ ],
+ "nozzle_temperature_range_low": [
+ "230"
+ ],
+ "supertack_plate_temp": [
+ "70"
+ ],
+ "supertack_plate_temp_initial_layer": [
+ "70"
+ ],
+ "setting_id": "PMPE04_U1",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "pressure_advance": [
+ "0.05"
+ ],
+ "inherits": "PolyLite PETG @Base"
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..b3c643a042
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @0.2 nozzle.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyLite PLA @0.2 nozzle",
+ "setting_id": "1592803578",
+ "inherits": "PolyLite PLA @base",
+ "compatible_printers": [
+ "Snapmaker A250 (0.2 nozzle)",
+ "Snapmaker A250 BKit (0.2 nozzle)",
+ "Snapmaker A250 QS+B Kit (0.2 nozzle)",
+ "Snapmaker A250 QSKit (0.2 nozzle)",
+ "Snapmaker A350 (0.2 nozzle)",
+ "Snapmaker A350 BKit (0.2 nozzle)",
+ "Snapmaker A350 QS+B Kit (0.2 nozzle)",
+ "Snapmaker A350 QSKit (0.2 nozzle)"
+ ],
+ "filament_max_volumetric_speed": [
+ "1.6"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1 base.json
new file mode 100644
index 0000000000..d0547572b6
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1 base.json
@@ -0,0 +1,20 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "false",
+ "name": "PolyLite PLA @U1 base",
+ "filament_id": "13938660340",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_cost": [
+ "90"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "default_filament_colour": [
+ ""
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1.json
new file mode 100644
index 0000000000..ad81f2d79d
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @U1.json
@@ -0,0 +1,11 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyLite PLA @U1",
+ "setting_id": "6486836500",
+ "inherits": "PolyLite PLA @U1 base",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @base.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @base.json
new file mode 100644
index 0000000000..2a7310f405
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA @base.json
@@ -0,0 +1,20 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "false",
+ "name": "PolyLite PLA @base",
+ "filament_id": "1393866034",
+ "inherits": "fdm_filament_pla",
+ "filament_flow_ratio": [
+ "0.95"
+ ],
+ "filament_cost": [
+ "90"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "default_filament_colour": [
+ ""
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1 base.json
new file mode 100644
index 0000000000..f5d87e4277
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1 base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "PolyLite PLA Pro @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM019",
+ "instantiation": "false",
+ "filament_cost": [
+ "24.99"
+ ],
+ "filament_density": [
+ "1.22"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "220"
+ ],
+ "nozzle_temperature_range_low": [
+ "190"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "62"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1.json
new file mode 100644
index 0000000000..f0b65f7717
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite PLA Pro @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "PolyLite PLA Pro @U1",
+ "inherits": "PolyLite PLA Pro @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM019_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..c3673b4d3c
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json
@@ -0,0 +1,19 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyTerra Dual PLA @0.2 nozzle",
+ "setting_id": "1258531391",
+ "inherits": "PolyTerra PLA @0.2 nozzle",
+ "compatible_printers": [
+ "Snapmaker A250 Dual (0.2 nozzle)",
+ "Snapmaker A250 Dual BKit (0.2 nozzle)",
+ "Snapmaker A250 Dual QS+B Kit (0.2 nozzle)",
+ "Snapmaker A250 Dual QSKit (0.2 nozzle)",
+ "Snapmaker A350 Dual (0.2 nozzle)",
+ "Snapmaker A350 Dual BKit (0.2 nozzle)",
+ "Snapmaker A350 Dual QS+B Kit (0.2 nozzle)",
+ "Snapmaker A350 Dual QSKit (0.2 nozzle)",
+ "Snapmaker Artisan (0.2 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..24fda4c652
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json
@@ -0,0 +1,11 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyTerra J1 PLA @0.2 nozzle",
+ "setting_id": "1072374370",
+ "inherits": "PolyTerra PLA @0.2 nozzle",
+ "compatible_printers": [
+ "Snapmaker J1 (0.2 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json
new file mode 100644
index 0000000000..9592d5cbd0
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json
@@ -0,0 +1,13 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyTerra J1 PLA",
+ "setting_id": "3958200796",
+ "inherits": "PolyTerra PLA @base",
+ "compatible_printers": [
+ "Snapmaker J1 (0.4 nozzle)",
+ "Snapmaker J1 (0.6 nozzle)",
+ "Snapmaker J1 (0.8 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @0.2 nozzle.json
new file mode 100644
index 0000000000..215685b8e3
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @0.2 nozzle.json
@@ -0,0 +1,21 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyTerra PLA @0.2 nozzle",
+ "setting_id": "409934824",
+ "inherits": "PolyTerra PLA @base",
+ "compatible_printers": [
+ "Snapmaker A250 (0.2 nozzle)",
+ "Snapmaker A250 BKit (0.2 nozzle)",
+ "Snapmaker A250 QS+B Kit (0.2 nozzle)",
+ "Snapmaker A250 QSKit (0.2 nozzle)",
+ "Snapmaker A350 (0.2 nozzle)",
+ "Snapmaker A350 BKit (0.2 nozzle)",
+ "Snapmaker A350 QS+B Kit (0.2 nozzle)",
+ "Snapmaker A350 QSKit (0.2 nozzle)"
+ ],
+ "filament_max_volumetric_speed": [
+ "1.4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1 base.json
new file mode 100644
index 0000000000..861179ca06
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1 base.json
@@ -0,0 +1,20 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "false",
+ "name": "PolyTerra PLA @U1 base",
+ "filament_id": "37895926870",
+ "inherits": "fdm_filament_pla",
+ "filament_cost": [
+ "80"
+ ],
+ "filament_density": [
+ "1.31"
+ ],
+ "filament_max_volumetric_speed": [
+ "14.4"
+ ],
+ "default_filament_colour": [
+ ""
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1.json
new file mode 100644
index 0000000000..f77d1d8082
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra PLA @U1.json
@@ -0,0 +1,11 @@
+{
+ "type": "filament",
+ "from": "system",
+ "instantiation": "true",
+ "name": "PolyTerra PLA @U1",
+ "setting_id": "12580059400",
+ "inherits": "PolyTerra PLA @U1 base",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Base.json
new file mode 100644
index 0000000000..77e155ade4
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Base.json
@@ -0,0 +1,29 @@
+{
+ "filament_density": [
+ "1.28"
+ ],
+ "temp_min": [
+ "210"
+ ],
+ "temp_max": [
+ "230"
+ ],
+ "temperture_vitrification": [
+ "156"
+ ],
+ "idle_temperture": [
+ "0"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "description": "",
+ "inherits": "fdm_filament_pla",
+ "name": "Polymaker HT-PLA @Base",
+ "type": "filament",
+ "instantiation": "false",
+ "from": "system",
+ "filament_vendor": [
+ "Polymaker"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Snapmaker U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Snapmaker U1.json
new file mode 100644
index 0000000000..b466d702fe
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @Snapmaker U1.json
@@ -0,0 +1,96 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA @Snapmaker U1",
+ "from": "system",
+ "instantiation": "true",
+ "cool_plate_temp": [
+ "50"
+ ],
+ "eng_plate_temp": [
+ "50"
+ ],
+ "hot_plate_temp": [
+ "65"
+ ],
+ "textured_plate_temp": [
+ "50"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "50"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "50"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "65"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "50"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "0.96"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "slow_down_min_speed": [
+ "5"
+ ],
+ "slow_down_layer_time": [
+ "6"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "additional_cooling_fan_speed": [
+ "0"
+ ],
+ "setting_id": "PMPL02_U1",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "inherits": "Polymaker HT-PLA @Base",
+ "filament_id": "PMPL02"
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1 base.json
new file mode 100644
index 0000000000..9a997d8e3f
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1 base.json
@@ -0,0 +1,53 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM017",
+ "instantiation": "false",
+ "filament_cost": [
+ "26.99"
+ ],
+ "filament_density": [
+ "1.28"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "hot_plate_temp": [
+ "65"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "65"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "nozzle_temperature_range_low": [
+ "210"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "textured_plate_temp": [
+ "65"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "65"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1.json
new file mode 100644
index 0000000000..da678d8a4c
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA @U1",
+ "inherits": "Polymaker HT-PLA @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM017_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Base.json
new file mode 100644
index 0000000000..4cd066b3d0
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Base.json
@@ -0,0 +1,29 @@
+{
+ "filament_density": [
+ "1.34"
+ ],
+ "temp_min": [
+ "210"
+ ],
+ "temp_max": [
+ "230"
+ ],
+ "temperture_vitrification": [
+ "148"
+ ],
+ "idle_temperture": [
+ "0"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "description": "",
+ "inherits": "fdm_filament_pla",
+ "name": "Polymaker HT-PLA-GF @Base",
+ "type": "filament",
+ "instantiation": "false",
+ "from": "system",
+ "filament_vendor": [
+ "Polymaker"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Snapmaker U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Snapmaker U1.json
new file mode 100644
index 0000000000..b18f79d461
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @Snapmaker U1.json
@@ -0,0 +1,96 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA-GF @Snapmaker U1",
+ "from": "system",
+ "instantiation": "true",
+ "cool_plate_temp": [
+ "50"
+ ],
+ "eng_plate_temp": [
+ "50"
+ ],
+ "hot_plate_temp": [
+ "65"
+ ],
+ "textured_plate_temp": [
+ "50"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "50"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "50"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "65"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "50"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "1.04"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "slow_down_min_speed": [
+ "5"
+ ],
+ "slow_down_layer_time": [
+ "6"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "additional_cooling_fan_speed": [
+ "0"
+ ],
+ "setting_id": "PMPL01_U1",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "inherits": "Polymaker HT-PLA-GF @Base",
+ "filament_id": "PMPL01"
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1 base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1 base.json
new file mode 100644
index 0000000000..fb70c1df40
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1 base.json
@@ -0,0 +1,53 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA-GF @U1 base",
+ "inherits": "fdm_filament_pla",
+ "from": "system",
+ "filament_id": "GFPM018",
+ "instantiation": "false",
+ "filament_cost": [
+ "32.99"
+ ],
+ "filament_density": [
+ "1.34"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "hot_plate_temp": [
+ "65"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "65"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "nozzle_temperature_range_low": [
+ "210"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ],
+ "temperature_vitrification": [
+ "60"
+ ],
+ "textured_plate_temp": [
+ "65"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "65"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1.json
new file mode 100644
index 0000000000..554d1452be
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker HT-PLA-GF @U1.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Polymaker HT-PLA-GF @U1",
+ "inherits": "Polymaker HT-PLA-GF @U1 base",
+ "from": "system",
+ "setting_id": "GFSPM018_00",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "fan_min_speed": [
+ "100"
+ ],
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "filament_max_volumetric_speed": [
+ "20"
+ ],
+ "slow_down_layer_time": [
+ "4"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Base.json
new file mode 100644
index 0000000000..04b25b012d
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Base.json
@@ -0,0 +1,29 @@
+{
+ "filament_density": [
+ "1.3"
+ ],
+ "temp_min": [
+ "240"
+ ],
+ "temp_max": [
+ "260"
+ ],
+ "temperture_vitrification": [
+ "75"
+ ],
+ "idle_temperture": [
+ "0"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "description": "",
+ "inherits": "fdm_filament_petg",
+ "name": "Polymaker PETG @Base",
+ "type": "filament",
+ "instantiation": "false",
+ "from": "system",
+ "filament_vendor": [
+ "Polymaker"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Snapmaker U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Snapmaker U1.json
new file mode 100644
index 0000000000..c7559a65f7
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PETG @Snapmaker U1.json
@@ -0,0 +1,111 @@
+{
+ "type": "filament",
+ "name": "Polymaker PETG @Snapmaker U1",
+ "from": "system",
+ "instantiation": "true",
+ "cool_plate_temp": [
+ "60"
+ ],
+ "eng_plate_temp": [
+ "0"
+ ],
+ "hot_plate_temp": [
+ "80"
+ ],
+ "textured_plate_temp": [
+ "80"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "60"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "0"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "80"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "80"
+ ],
+ "overhang_fan_threshold": [
+ "95%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "0.96"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "260"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "10"
+ ],
+ "fan_min_speed": [
+ "50"
+ ],
+ "slow_down_min_speed": [
+ "10"
+ ],
+ "slow_down_layer_time": [
+ "6"
+ ],
+ "filament_start_gcode": [
+ "; Filament gcode\n"
+ ],
+ "nozzle_temperature": [
+ "260"
+ ],
+ "temperature_vitrification": [
+ "71"
+ ],
+ "filament_id": "PMPE01",
+ "nozzle_temperature_range_high": [
+ "260"
+ ],
+ "nozzle_temperature_range_low": [
+ "240"
+ ],
+ "supertack_plate_temp": [
+ "70"
+ ],
+ "supertack_plate_temp_initial_layer": [
+ "70"
+ ],
+ "setting_id": "PMPE01_U1",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "inherits": "Polymaker PETG @Base"
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Base.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Base.json
new file mode 100644
index 0000000000..d25cf0270d
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Base.json
@@ -0,0 +1,29 @@
+{
+ "filament_density": [
+ "1.23"
+ ],
+ "temp_min": [
+ "190"
+ ],
+ "temp_max": [
+ "230"
+ ],
+ "temperture_vitrification": [
+ "55"
+ ],
+ "idle_temperture": [
+ "0"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "description": "",
+ "inherits": "fdm_filament_pla",
+ "name": "Polymaker PLA Pro @Base",
+ "type": "filament",
+ "instantiation": "false",
+ "from": "system",
+ "filament_vendor": [
+ "Polymaker"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Snapmaker U1.json b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Snapmaker U1.json
new file mode 100644
index 0000000000..8b77ae186f
--- /dev/null
+++ b/resources/profiles/Snapmaker/filament/Polymaker/Polymaker PLA Pro @Snapmaker U1.json
@@ -0,0 +1,96 @@
+{
+ "type": "filament",
+ "name": "Polymaker PLA Pro @Snapmaker U1",
+ "from": "system",
+ "instantiation": "true",
+ "cool_plate_temp": [
+ "50"
+ ],
+ "eng_plate_temp": [
+ "50"
+ ],
+ "hot_plate_temp": [
+ "65"
+ ],
+ "textured_plate_temp": [
+ "50"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "50"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "50"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "65"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "50"
+ ],
+ "overhang_fan_threshold": [
+ "50%"
+ ],
+ "overhang_fan_speed": [
+ "100"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode \n"
+ ],
+ "filament_flow_ratio": [
+ "0.96"
+ ],
+ "filament_cost": [
+ "0"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_max_volumetric_speed": [
+ "15"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_vendor": [
+ "Polymaker"
+ ],
+ "bed_type": [
+ "Cool Plate"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "fan_max_speed": [
+ "100"
+ ],
+ "slow_down_min_speed": [
+ "5"
+ ],
+ "slow_down_layer_time": [
+ "6"
+ ],
+ "filament_start_gcode": [
+ "; filament start gcode\n"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "61"
+ ],
+ "nozzle_temperature_range_high": [
+ "230"
+ ],
+ "additional_cooling_fan_speed": [
+ "0"
+ ],
+ "setting_id": "PMPL03_U1",
+ "compatible_printers": [
+ "Snapmaker U1 (0.4 nozzle)"
+ ],
+ "inherits": "Polymaker PLA Pro @Base",
+ "filament_id": "PMPL03"
+}
\ No newline at end of file
diff --git a/resources/profiles/WonderMaker/WonderMaker ZR ULtra S_cover.png b/resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png
similarity index 100%
rename from resources/profiles/WonderMaker/WonderMaker ZR ULtra S_cover.png
rename to resources/profiles/WonderMaker/WonderMaker ZR Ultra S_cover.png
diff --git a/resources/profiles/iQ.json b/resources/profiles/iQ.json
index 17d813bac9..c904ad1a1f 100644
--- a/resources/profiles/iQ.json
+++ b/resources/profiles/iQ.json
@@ -80,6 +80,10 @@
{
"name": "0.20mm Standard @iQ TiQ2 P2 - PACF Pro Fiberthree + VXL90 Xioneer (0.4 Nozzle)",
"sub_path": "process/0.20mm Standard @iQ TiQ2 P2 - PACF Pro Fiberthree + VXL90 Xioneer (0.4 Nozzle).json"
+ },
+ {
+ "name": "0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle)",
+ "sub_path": "process/0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle).json"
}
],
"filament_list": [
@@ -106,6 +110,10 @@
{
"name": "VXL90 TiQ2 P2 @iQ TiQ2 0.4 Nozzle",
"sub_path": "filament/VXL90 TiQ2 P2 @iQ TiQ2 0.4 Nozzle.json"
+ },
+ {
+ "name": "Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle",
+ "sub_path": "filament/Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle.json"
}
]
}
diff --git a/resources/profiles/iQ/filament/Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle.json b/resources/profiles/iQ/filament/Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle.json
new file mode 100644
index 0000000000..20146fa309
--- /dev/null
+++ b/resources/profiles/iQ/filament/Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle.json
@@ -0,0 +1,303 @@
+{
+ "type": "filament",
+ "name": "Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle",
+ "inherits": "fdm_filament_common",
+ "from": "system",
+ "setting_id": "IQS1",
+ "filament_id": "IQM1",
+ "instantiation": "true",
+ "compatible_prints": [
+ "0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle)"
+ ],
+ "filament_cost": [
+ "70.58"
+ ],
+ "filament_density": [
+ "1.09"
+ ],
+ "filament_end_gcode": [
+ "; filament end gcode\n{if current_extruder==0}\nG1 Z{layer_z+2} F900 ; safe distance for T0 while tool change\nG1 X-17 Y1 F9000\nG1 X-17 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\n{endif}\n\n{if current_extruder==1}\n{if current_extruder==0}T1{endif}\nG1 X-23 Y3 F9000\nG1 Y45 F9000\nG1 Y3 F9000\nG1 Y45 F9000\n{endif}\n"
+ ],
+ "filament_flow_ratio": [
+ "0.926"
+ ],
+ "filament_settings_id": [
+ "Grauts HPP4GF25 P1 @iQ TiQ2 0.4 Nozzle"
+ ],
+ "filament_shrink": [
+ "98.994%"
+ ],
+ "filament_shrinkage_compensation_z": [
+ "99%"
+ ],
+ "filament_start_gcode": [
+ "; Filament gcode\n{if current_extruder==0}\nG1 X-17 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\n{if layer_z==0}G1 Z{first_layer_height + 2.0}{endif}\n{if layer_z==0}G1 X[first_layer_print_min_0] Y[first_layer_print_min_1]{endif}\n{if layer_z==0}G1 Z{layer_z}{endif}\n{endif}\n\n{if current_extruder==1}\nG1 X-23 Y3 F9000\nG1 Y45 F9000\nG1 Y3 F9000\nG1 Y45 F9000\n{endif}\n"
+ ],
+ "filament_type": [
+ "HPP4GF25"
+ ],
+ "hot_plate_temp": [
+ "110"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "110"
+ ],
+ "idle_temperature": [
+ "180"
+ ],
+ "is_custom_defined": "0",
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "nozzle_temperature_range_high": [
+ "280"
+ ],
+ "nozzle_temperature_range_low": [
+ "220"
+ ],
+ "temperature_vitrification": [
+ "127"
+ ],
+ "version": "2.3.1.10",
+
+
+ "activate_air_filtration": [
+ "0"
+ ],
+ "activate_chamber_temp_control": [
+ "0"
+ ],
+ "adaptive_pressure_advance": [
+ "0"
+ ],
+ "adaptive_pressure_advance_bridges": [
+ "0"
+ ],
+ "adaptive_pressure_advance_model": [
+ "0,0,0\n0,0,0"
+ ],
+ "adaptive_pressure_advance_overhangs": [
+ "0"
+ ],
+ "additional_cooling_fan_speed": [
+ "0"
+ ],
+ "chamber_temperature": [
+ "0"
+ ],
+ "close_fan_the_first_x_layers": [
+ "3"
+ ],
+ "compatible_printers": [
+ "iQ TiQ2 0.4 Nozzle"
+ ],
+ "compatible_printers_condition": "",
+ "compatible_prints_condition": "",
+ "complete_print_exhaust_fan_speed": [
+ "80"
+ ],
+ "cool_plate_temp": [
+ "105"
+ ],
+ "cool_plate_temp_initial_layer": [
+ "105"
+ ],
+ "default_filament_colour": [
+ "#000000"
+ ],
+ "dont_slow_down_outer_wall": [
+ "0"
+ ],
+ "during_print_exhaust_fan_speed": [
+ "60"
+ ],
+ "enable_overhang_bridge_fan": [
+ "1"
+ ],
+ "enable_pressure_advance": [
+ "0"
+ ],
+ "eng_plate_temp": [
+ "105"
+ ],
+ "eng_plate_temp_initial_layer": [
+ "105"
+ ],
+ "fan_cooling_layer_time": [
+ "30"
+ ],
+ "fan_max_speed": [
+ "80"
+ ],
+ "fan_min_speed": [
+ "10"
+ ],
+ "filament_cooling_final_speed": [
+ "3.5"
+ ],
+ "filament_cooling_initial_speed": [
+ "10"
+ ],
+ "filament_cooling_moves": [
+ "2"
+ ],
+ "filament_deretraction_speed": [
+ "nil"
+ ],
+ "filament_diameter": [
+ "1.75"
+ ],
+ "filament_is_support": [
+ "0"
+ ],
+ "filament_loading_speed": [
+ "10"
+ ],
+ "filament_loading_speed_start": [
+ "50"
+ ],
+ "filament_long_retractions_when_cut": [
+ "nil"
+ ],
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_minimal_purge_on_wipe_tower": [
+ "15"
+ ],
+ "filament_multitool_ramming": [
+ "1"
+ ],
+ "filament_multitool_ramming_flow": [
+ "40"
+ ],
+ "filament_multitool_ramming_volume": [
+ "10"
+ ],
+ "filament_notes": [
+ ""
+ ],
+ "filament_ramming_parameters": [
+ "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
+ ],
+ "filament_retract_before_wipe": [
+ "nil"
+ ],
+ "filament_retract_lift_above": [
+ "nil"
+ ],
+ "filament_retract_lift_below": [
+ "nil"
+ ],
+ "filament_retract_lift_enforce": [
+ "nil"
+ ],
+ "filament_retract_restart_extra": [
+ "nil"
+ ],
+ "filament_retract_when_changing_layer": [
+ "nil"
+ ],
+ "filament_retraction_distances_when_cut": [
+ "nil"
+ ],
+ "filament_retraction_length": [
+ "4"
+ ],
+ "filament_retraction_minimum_travel": [
+ "nil"
+ ],
+ "filament_retraction_speed": [
+ "40"
+ ],
+ "filament_soluble": [
+ "0"
+ ],
+ "filament_stamping_distance": [
+ "45"
+ ],
+ "filament_stamping_loading_speed": [
+ "29"
+ ],
+ "filament_toolchange_delay": [
+ "0"
+ ],
+ "filament_unloading_speed": [
+ "100"
+ ],
+ "filament_unloading_speed_start": [
+ "100"
+ ],
+ "filament_vendor": [
+ "iQ Materials"
+ ],
+ "filament_wipe": [
+ "nil"
+ ],
+ "filament_wipe_distance": [
+ "nil"
+ ],
+ "filament_z_hop": [
+ "nil"
+ ],
+ "filament_z_hop_types": [
+ "nil"
+ ],
+ "full_fan_speed_layer": [
+ "0"
+ ],
+ "internal_bridge_fan_speed": [
+ "-1"
+ ],
+ "overhang_fan_speed": [
+ "80"
+ ],
+ "overhang_fan_threshold": [
+ "25%"
+ ],
+ "pellet_flow_coefficient": [
+ "0.4157"
+ ],
+ "pressure_advance": [
+ "0.02"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "required_nozzle_HRC": [
+ "0"
+ ],
+ "slow_down_for_layer_cooling": [
+ "1"
+ ],
+ "slow_down_layer_time": [
+ "3"
+ ],
+ "slow_down_min_speed": [
+ "10"
+ ],
+ "supertack_plate_temp": [
+ "35"
+ ],
+ "supertack_plate_temp_initial_layer": [
+ "35"
+ ],
+ "support_material_interface_fan_speed": [
+ "-1"
+ ],
+ "textured_cool_plate_temp": [
+ "40"
+ ],
+ "textured_cool_plate_temp_initial_layer": [
+ "40"
+ ],
+ "textured_plate_temp": [
+ "105"
+ ],
+ "textured_plate_temp_initial_layer": [
+ "105"
+ ]
+}
diff --git a/resources/profiles/iQ/filament/Polymaker PETG Polymax black P1 @iQ TiQ2 0.4 Nozzle.json b/resources/profiles/iQ/filament/Polymaker PETG Polymax black P1 @iQ TiQ2 0.4 Nozzle.json
index 457b37f8cd..054350acfc 100644
--- a/resources/profiles/iQ/filament/Polymaker PETG Polymax black P1 @iQ TiQ2 0.4 Nozzle.json
+++ b/resources/profiles/iQ/filament/Polymaker PETG Polymax black P1 @iQ TiQ2 0.4 Nozzle.json
@@ -30,9 +30,6 @@
"chamber_temperature": [
"0"
],
- "close_fan_the_first_x_layers": [
- "3"
- ],
"compatible_printers": [
"iQ TiQ2 0.4 Nozzle"
],
@@ -89,6 +86,9 @@
"filament_cooling_moves": [
"4"
],
+ "close_fan_the_first_x_layers": [
+ "1000"
+ ],
"filament_cost": [
"29.99"
],
@@ -162,7 +162,7 @@
"nil"
],
"filament_retraction_length": [
- "0.2"
+ "0.4"
],
"filament_retraction_minimum_travel": [
"nil"
@@ -222,7 +222,7 @@
"0"
],
"hot_plate_temp": [
- "80"
+ "70"
],
"hot_plate_temp_initial_layer": [
"80"
@@ -237,7 +237,7 @@
"-1"
],
"nozzle_temperature": [
- "250"
+ "240"
],
"nozzle_temperature_initial_layer": [
"250"
@@ -261,7 +261,7 @@
"0.02"
],
"reduce_fan_stop_start_freq": [
- "1"
+ "0"
],
"required_nozzle_HRC": [
"3"
diff --git a/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle).json b/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle).json
new file mode 100644
index 0000000000..0a542fe938
--- /dev/null
+++ b/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle).json
@@ -0,0 +1,70 @@
+{
+ "type": "process",
+ "inherits": "fdm_process_tiq_common",
+ "from": "system",
+ "instantiation": "true",
+ "default_acceleration": "1500",
+ "enable_extra_bridge_layer": "apply_to_all",
+ "enable_prime_tower": "0",
+ "initial_layer_infill_speed": "100",
+ "inner_wall_acceleration": "1500",
+ "inner_wall_speed": "100",
+ "is_custom_defined": "0",
+ "name": "0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle)",
+ "notes": "Pre-Select: FBA Time Delay: 0 EPC Factor: 0\n\nDeutsch P1 HPP4GF25\n\n1. Überprüfen Sie, dass sich das Grauts HPP4GF25 im linken Extruder befindet. Halten Sie das Filament trocken! Detailierte Trocknungsanleitung, siehe unten.\n\n2. Überprüfen Sie, dass sich eine 0,4 mm Wolfram-Kupfer Düse im linken Extruder befindet.\n\n3. Verwenden Sie Magigoo Kleber für PPGF auf der PET-Folie, um eine bessere Haftung zu gewährleisten, im Singledruck in der Regel auf PET-Folie nicht erforderlich.\n\n4. Reinigen Sie ggf. die Düse mit einer Messing-Drahtbürste.\nNun sind sie bereit, um Ihren Druck zu starten.\n\n\nTipp: Am besten lässt sich das Bauteil bei einer Druckplattentemperatur von 80°C entfernen, da dann der Kleber weich wird.\n\n\nEnglish P1 HPP4GF25\n\n1. Check Left extruder filament: Grauts HPP4GF25 - Keep the filament dry!! Detailed drying instruction below.\n\n2. Check left extruder nozzle: 0.4mm Wolfram\n\n3. Check bed: PET with Magigoo glue for PPGF\n\n4. Check nozzle: Clean it with brush\n\nWELLDONE! YOU ARE READY NOW TO START YOUR PRINT JOB!\n\n\nTip: The component is best removed at a printing plate temperature of 80°C, as this softens the adhesive.",
+ "outer_wall_acceleration": "1500",
+ "outer_wall_speed": "80",
+ "print_settings_id": "0.20mm Standard @iQ TiQ2 P1 - HPP4GF25 Grauts (0.4 Nozzle)",
+ "sparse_infill_speed": "100",
+ "support_angle": "0",
+ "support_base_pattern": "default",
+ "support_interface_bottom_layers": "0",
+ "support_interface_top_layers": "3",
+ "support_object_first_layer_gap": "0.3",
+ "support_object_xy_distance": "0.35",
+ "support_on_build_plate_only": "0",
+ "support_speed": "100",
+ "support_style": "snug",
+ "support_top_z_distance": "0.2",
+ "support_type": "normal(auto)",
+ "top_surface_acceleration": "1500",
+ "top_surface_speed": "80",
+ "travel_acceleration": "1500",
+ "version": "2.3.1.10",
+
+ "bridge_flow": "1.07",
+ "bridge_speed": "25",
+ "brim_type": "no_brim",
+ "enable_support": "1",
+ "exclude_object": "0",
+ "gcode_label_objects": "0",
+ "compatible_printers": [
+ "iQ TiQ2 0.4 Nozzle"
+ ],
+ "internal_bridge_speed": "50%",
+ "internal_solid_infill_speed": "60",
+ "ironing_pattern": "concentric",
+ "prime_tower_width": "80",
+ "layer_height": "0.2",
+ "reduce_crossing_wall": "1",
+ "skirt_height": "1",
+ "skirt_loops": "2",
+ "small_perimeter_speed": "30%",
+ "small_perimeter_threshold": "5",
+ "sparse_infill_density": "30%",
+ "sparse_infill_pattern": "triangles",
+ "support_base_pattern_spacing": "1",
+ "support_bottom_interface_spacing": "0.3",
+ "support_bottom_z_distance": "0.24",
+ "support_expansion": "0.5",
+ "support_filament": "1",
+ "support_interface_filament": "1",
+ "support_interface_pattern": "rectilinear_interlaced",
+ "support_interface_spacing": "0",
+ "top_shell_thickness": "0",
+ "top_solid_infill_flow_ratio": "0.98",
+ "tree_support_branch_diameter_angle": "10",
+ "tree_support_branch_diameter_organic": "3",
+ "tree_support_tip_diameter": "2",
+ "wall_loops": "2"
+}
diff --git a/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - PETG Polymax Polymaker (0.4 Nozzle).json b/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - PETG Polymax Polymaker (0.4 Nozzle).json
index 096eb82e13..1093c7c1c7 100644
--- a/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - PETG Polymax Polymaker (0.4 Nozzle).json
+++ b/resources/profiles/iQ/process/0.20mm Standard @iQ TiQ2 P1 - PETG Polymax Polymaker (0.4 Nozzle).json
@@ -20,6 +20,9 @@
"enable_overhang_speed": "0",
"enable_prime_tower": "0",
"gap_infill_speed": "50",
+ "thick_internal_bridges": "0",
+ "enable_extra_bridge_layer": "apply_to_all",
+ "bottom_shell_thickness": "0.8",
"initial_layer_infill_speed": "25",
"initial_layer_speed": "25",
"initial_layer_travel_speed": "50%",
@@ -63,10 +66,11 @@
"tree_support_wall_count": "2",
"wall_direction": "ccw",
"wall_loops": "3",
- "wall_sequence": "inner-outer-inner wall",
+ "wall_sequence": "inner wall/outer wall",
"support_base_pattern": "rectilinear-grid",
"support_interface_pattern": "rectilinear_interlaced",
"support_interface_spacing": "0",
- "small_perimeter_speed": "30%",
+ "small_perimeter_speed": "50",
+ "support_interface_speed": "50",
"brim_type": "no_brim"
}
\ No newline at end of file
diff --git a/resources/web/flush/WipingDialog.html b/resources/web/flush/WipingDialog.html
index efaea1c8ea..249ee03449 100644
--- a/resources/web/flush/WipingDialog.html
+++ b/resources/web/flush/WipingDialog.html
@@ -432,10 +432,11 @@
return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
}
-
function updateVolumeRange(min_volume,max_volume){
+ // Orca: "Typical" guidance only unlinked from upper bound in the slicer.
+ const TYPICAL_MAX_FLUSH_VOLUME = 900;
const panel = document.getElementById('volume_range_panel');
- panel.innerText = panel.innerText.replace(/\[.*\]/, `[${min_volume}, ${max_volume}]`);
+ panel.innerText = panel.innerText.replace(/\[.*\]/, `[${min_volume}, ${TYPICAL_MAX_FLUSH_VOLUME}]`);
}
function updateMultiplierRange(min_multiplier,max_multiplier){
diff --git a/scripts/flatpak/io.github.softfever.OrcaSlicer.metainfo.xml b/scripts/flatpak/io.github.softfever.OrcaSlicer.metainfo.xml
index 96fd4c3ad7..c63f02d96b 100755
--- a/scripts/flatpak/io.github.softfever.OrcaSlicer.metainfo.xml
+++ b/scripts/flatpak/io.github.softfever.OrcaSlicer.metainfo.xml
@@ -11,7 +11,7 @@
Get even more perfect prints!
SoftFever
https://github.com/OrcaSlicer/OrcaSlicer
- https://github.com/OrcaSlicer/OrcaSlicer/wiki
+ https://www.orcaslicer.com/wiki
https://github.com/OrcaSlicer/OrcaSlicer/issues/
https://ko-fi.com/SoftFever
0BSD
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 16f6a4a606..4fd9b565b3 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -134,6 +135,25 @@ void AppConfig::set_defaults()
if (!get("use_legacy_opengl").empty())
erase("app", "use_legacy_opengl");
+ // Migrate legacy_networking boolean to network_plugin_version string
+ std::string legacy_networking = get("legacy_networking");
+ std::string network_version = get("network_plugin_version");
+
+ if (!legacy_networking.empty()) {
+ // Old legacy_networking setting exists - migrate it
+ bool was_legacy = (legacy_networking == "true" || legacy_networking == "1");
+
+ if (was_legacy && network_version.empty()) {
+ // User had legacy mode enabled - set to legacy version number
+ BOOST_LOG_TRIVIAL(info) << "Migrating legacy_networking=true to network_plugin_version=01.10.01.01";
+ set_network_plugin_version(BAMBU_NETWORK_AGENT_VERSION_LEGACY);
+ }
+ // Note: If was_legacy=false, we leave the version empty and let the GUI layer set it to the latest version
+
+ // Remove the old setting
+ erase("app", "legacy_networking");
+ }
+
#ifdef __APPLE__
if (get("use_retina_opengl").empty())
set_bool("use_retina_opengl", true);
@@ -277,9 +297,6 @@ void AppConfig::set_defaults()
if (get("allow_abnormal_storage").empty()) {
set_bool("allow_abnormal_storage", false);
}
- if (get("legacy_networking").empty()) {
- set_bool("legacy_networking", false);
- }
if(get("check_stable_update_only").empty()) {
set_bool("check_stable_update_only", false);
@@ -314,10 +331,18 @@ void AppConfig::set_defaults()
set("auto_calculate_flush","all");
}
+ if (get("show_canvas_zoom_button").empty()) {
+ set_bool("show_canvas_zoom_button", true);
+ }
+
if (get("remember_printer_config").empty()) {
set_bool("remember_printer_config", true);
}
+ if (get("group_filament_presets").empty()) {
+ set("group_filament_presets", "1"); // All "0" / None "1" / By Type "2" / By Vendor "3"
+ }
+
if (get("enable_high_low_temp_mixed_printing").empty()){
set_bool("enable_high_low_temp_mixed_printing", false);
}
@@ -1432,6 +1457,82 @@ std::string AppConfig::get_nozzle_volume_types_from_config(const std::string& pr
return nozzle_volume_types;
}
+std::string AppConfig::get_network_plugin_version() const
+{
+ return get(SETTING_NETWORK_PLUGIN_VERSION);
+}
+
+void AppConfig::set_network_plugin_version(const std::string& version)
+{
+ set(SETTING_NETWORK_PLUGIN_VERSION, version);
+}
+
+std::vector AppConfig::get_skipped_network_versions() const
+{
+ std::vector result;
+ std::string skipped = get(SETTING_NETWORK_PLUGIN_SKIPPED_VERSIONS);
+ if (skipped.empty())
+ return result;
+
+ std::stringstream ss(skipped);
+ std::string version;
+ while (std::getline(ss, version, ';')) {
+ if (!version.empty())
+ result.push_back(version);
+ }
+ return result;
+}
+
+void AppConfig::add_skipped_network_version(const std::string& version)
+{
+ auto skipped = get_skipped_network_versions();
+ if (std::find(skipped.begin(), skipped.end(), version) == skipped.end()) {
+ skipped.push_back(version);
+ std::string joined;
+ for (size_t i = 0; i < skipped.size(); ++i) {
+ if (i > 0) joined += ";";
+ joined += skipped[i];
+ }
+ set(SETTING_NETWORK_PLUGIN_SKIPPED_VERSIONS, joined);
+ }
+}
+
+bool AppConfig::is_network_version_skipped(const std::string& version) const
+{
+ auto skipped = get_skipped_network_versions();
+ return std::find(skipped.begin(), skipped.end(), version) != skipped.end();
+}
+
+void AppConfig::clear_skipped_network_versions()
+{
+ set(SETTING_NETWORK_PLUGIN_SKIPPED_VERSIONS, "");
+}
+
+bool AppConfig::is_network_update_prompt_disabled() const
+{
+ return get_bool(SETTING_NETWORK_PLUGIN_UPDATE_DISABLED);
+}
+
+void AppConfig::set_network_update_prompt_disabled(bool disabled)
+{
+ set_bool(SETTING_NETWORK_PLUGIN_UPDATE_DISABLED, disabled);
+}
+
+bool AppConfig::should_remind_network_update_later() const
+{
+ return get_bool(SETTING_NETWORK_PLUGIN_REMIND_LATER);
+}
+
+void AppConfig::set_remind_network_update_later(bool remind)
+{
+ set_bool(SETTING_NETWORK_PLUGIN_REMIND_LATER, remind);
+}
+
+void AppConfig::clear_remind_network_update_later()
+{
+ set_bool(SETTING_NETWORK_PLUGIN_REMIND_LATER, false);
+}
+
void AppConfig::reset_selections()
{
auto it = m_storage.find("presets");
diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp
index 9307877552..b521410ce9 100644
--- a/src/libslic3r/AppConfig.hpp
+++ b/src/libslic3r/AppConfig.hpp
@@ -24,6 +24,12 @@ using namespace nlohmann;
#define OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK "always_ask"
#define OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY "load_geometry_only"
+#define SETTING_NETWORK_PLUGIN_VERSION "network_plugin_version"
+#define SETTING_NETWORK_PLUGIN_SKIPPED_VERSIONS "network_plugin_skipped_versions"
+#define SETTING_NETWORK_PLUGIN_UPDATE_DISABLED "network_plugin_update_prompts_disabled"
+#define SETTING_NETWORK_PLUGIN_REMIND_LATER "network_plugin_remind_later"
+#define BAMBU_NETWORK_AGENT_VERSION_LEGACY "01.10.01.01"
+
#define SUPPORT_DARK_MODE
//#define _MSW_DARK_MODE
@@ -347,6 +353,21 @@ public:
static const std::string SECTION_MATERIALS;
static const std::string SECTION_EMBOSS_STYLE;
+ std::string get_network_plugin_version() const;
+ void set_network_plugin_version(const std::string& version);
+
+ std::vector get_skipped_network_versions() const;
+ void add_skipped_network_version(const std::string& version);
+ bool is_network_version_skipped(const std::string& version) const;
+ void clear_skipped_network_versions();
+
+ bool is_network_update_prompt_disabled() const;
+ void set_network_update_prompt_disabled(bool disabled);
+
+ bool should_remind_network_update_later() const;
+ void set_remind_network_update_later(bool remind);
+ void clear_remind_network_update_later();
+
private:
template
bool get_3dmouse_device_numeric_value(const std::string &device_name, const char *parameter_name, T &out) const
diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index d21ed2e544..35d971a465 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -1,5 +1,3 @@
-#include "clipper/clipper_z.hpp"
-
#include "ClipperUtils.hpp"
#include "EdgeGrid.hpp"
#include "Layer.hpp"
@@ -10,8 +8,8 @@
#include "MaterialType.hpp"
#include "Model.hpp"
#include
-#include
-#include
+#include
+#include
#include
#include
@@ -54,16 +52,63 @@ static void append_and_translate(Polygons &dst, const Polygons &src, const Print
dst[dst_idx].translate(instance_shift);
}
-static float max_brim_width(const ConstPrintObjectPtrsAdaptor &objects)
+//ORCA: Brim can follow the post-EFC outline when enabled.
+static bool use_brim_efc_outline(const PrintObject &object)
{
- assert(!objects.empty());
- return float(std::accumulate(objects.begin(), objects.end(), 0.,
- [](double partial_result, const PrintObject *object) {
- return std::max(partial_result, object->config().brim_type == btNoBrim ? 0. : object->config().brim_width.value);
- }));
+ return object.config().brim_use_efc_outline.value
+ && object.config().elefant_foot_compensation.value > 0.
+ && object.config().elefant_foot_compensation_layers.value > 0
+ && object.config().raft_layers.value == 0;
}
-// Returns ExPolygons of the bottom layer of the print object after elephant foot compensation.
+//ORCA: Helper for snapping painted ears to the EFC outline.
+static bool closest_point_on_expolygons(const ExPolygons &polygons, const Point &from, Point &closest_out)
+{
+ double min_dist2 = std::numeric_limits::max();
+ bool found = false;
+
+ for (const ExPolygon &poly : polygons) {
+ for (int i = 0; i < poly.num_contours(); ++i) {
+ const Point *candidate = poly.contour_or_hole(i).closest_point(from);
+ if (candidate == nullptr)
+ continue;
+ const int64_t dx = int64_t(candidate->x()) - int64_t(from.x());
+ const int64_t dy = int64_t(candidate->y()) - int64_t(from.y());
+ const double dist2 = double(dx * dx + dy * dy);
+ if (dist2 < min_dist2) {
+ min_dist2 = dist2;
+ closest_out = *candidate;
+ found = true;
+ }
+ }
+ }
+ return found;
+}
+
+//ORCA: Helper for matching painted ears to their original island before EFC snapping.
+static int find_containing_expolygon_index(const ExPolygons &polygons, const Point &from)
+{
+ for (size_t idx = 0; idx < polygons.size(); ++idx) {
+ if (polygons[idx].contains(from))
+ return int(idx);
+ }
+ return -1;
+}
+
+//ORCA: Keep painted ear snapping on the matching island when using EFC outline.
+static bool closest_point_on_matching_island(const ExPolygons &raw_outline, const ExPolygons &efc_outline, const Point &from, Point &closest_out)
+{
+ const int island_idx = find_containing_expolygon_index(raw_outline, from);
+ if (island_idx >= 0) {
+ ExPolygons island_outline = intersection_ex(efc_outline, raw_outline[island_idx]);
+ if (!island_outline.empty())
+ return closest_point_on_expolygons(island_outline, from, closest_out);
+ }
+ return closest_point_on_expolygons(efc_outline, from, closest_out);
+}
+//ORCA: Use post-processed first-layer slices (including EFC) for brim outline.
+// Returns ExPolygons of the bottom layer after all first-layer modifiers
+// (including elephant foot compensation, if enabled) have been applied.
static ExPolygons get_print_object_bottom_layer_expolygons(const PrintObject &print_object)
{
ExPolygons ex_polygons;
@@ -71,506 +116,6 @@ static ExPolygons get_print_object_bottom_layer_expolygons(const PrintObject &pr
Slic3r::append(ex_polygons, closing_ex(region->slices.surfaces, float(SCALED_EPSILON)));
return ex_polygons;
}
-
-// Returns ExPolygons of bottom layer for every print object in Print after elephant foot compensation.
-static std::vector get_print_bottom_layers_expolygons(const Print &print)
-{
- std::vector bottom_layers_expolygons;
- bottom_layers_expolygons.reserve(print.objects().size());
- for (const PrintObject *object : print.objects())
- bottom_layers_expolygons.emplace_back(get_print_object_bottom_layer_expolygons(*object));
-
- return bottom_layers_expolygons;
-}
-
-static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print, const std::vector &bottom_layers_expolygons)
-{
- assert(print.objects().size() == bottom_layers_expolygons.size());
- Polygons islands;
- ConstPrintObjectPtrs island_to_object;
- for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) {
- const PrintObject *object = print.objects()[print_object_idx];
- Polygons islands_object;
- islands_object.reserve(bottom_layers_expolygons[print_object_idx].size());
- for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx])
- islands_object.emplace_back(ex_poly.contour);
-
- islands.reserve(islands.size() + object->instances().size() * islands_object.size());
- for (const PrintInstance& instance : object->instances()) {
- Point instance_shift = instance.shift_without_plate_offset();
- for (Polygon& poly : islands_object) {
- islands.emplace_back(poly);
- islands.back().translate(instance_shift);
- island_to_object.emplace_back(object);
- }
- }
- }
- assert(islands.size() == island_to_object.size());
-
- ClipperLib_Z::Paths islands_clip;
- islands_clip.reserve(islands.size());
- for (const Polygon &poly : islands) {
- islands_clip.emplace_back();
- ClipperLib_Z::Path &island_clip = islands_clip.back();
- island_clip.reserve(poly.points.size());
- int island_idx = int(&poly - &islands.front());
- // The Z coordinate carries index of the island used to get the pointer to the object.
- for (const Point &pt : poly.points)
- island_clip.emplace_back(pt.x(), pt.y(), island_idx + 1);
- }
-
- // Init Clipper
- ClipperLib_Z::Clipper clipper;
- // Assign the maximum Z from four points. This values is valid index of the island
- clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
- const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
- pt.z() = std::max(std::max(e1bot.z(), e1top.z()), std::max(e2bot.z(), e2top.z()));
- });
- // Add islands
- clipper.AddPaths(islands_clip, ClipperLib_Z::ptSubject, true);
- // Execute union operation to construct polytree
- ClipperLib_Z::PolyTree islands_polytree;
- //FIXME likely pftNonZero or ptfPositive would be better. Why are we using ptfEvenOdd for Unions?
- clipper.Execute(ClipperLib_Z::ctUnion, islands_polytree, ClipperLib_Z::pftEvenOdd, ClipperLib_Z::pftEvenOdd);
-
- std::unordered_set processed_objects_idx;
- ConstPrintObjectPtrs top_level_objects_with_brim;
- for (int i = 0; i < islands_polytree.ChildCount(); ++i) {
- for (const ClipperLib_Z::IntPoint &point : islands_polytree.Childs[i]->Contour) {
- if (point.z() != 0 && processed_objects_idx.find(island_to_object[point.z() - 1]->id().id) == processed_objects_idx.end()) {
- top_level_objects_with_brim.emplace_back(island_to_object[point.z() - 1]);
- processed_objects_idx.insert(island_to_object[point.z() - 1]->id().id);
- }
- }
- }
- return top_level_objects_with_brim;
-}
-
-static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_level_objects_with_brim, const double scaled_resolution)
-{
- Polygons islands;
- for (const PrintObject *object : top_level_objects_with_brim) {
- if (!object->has_brim())
- continue;
-
- //FIXME how about the brim type?
- auto brim_object_gap = float(scale_(object->config().brim_object_gap.value));
- Polygons islands_object;
- for (const ExPolygon &ex_poly : get_print_object_bottom_layer_expolygons(*object)) {
- Polygons contour_offset = offset(ex_poly.contour, brim_object_gap, ClipperLib::jtSquare);
- for (Polygon &poly : contour_offset)
- poly.douglas_peucker(scaled_resolution);
-
- polygons_append(islands_object, std::move(contour_offset));
- }
-
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- Polygons contour_offset = offset(support_contour, brim_object_gap, ClipperLib::jtSquare);
- for (Polygon& poly : contour_offset)
- poly.douglas_peucker(scaled_resolution);
-
- polygons_append(islands_object, std::move(contour_offset));
- }
- }
-
- for (const PrintInstance &instance : object->instances())
- append_and_translate(islands, islands_object, instance);
- }
- return islands;
-}
-
-static ExPolygons top_level_outer_brim_area(const Print &print,
- const ConstPrintObjectPtrs &top_level_objects_with_brim,
- const std::vector &bottom_layers_expolygons,
- const float no_brim_offset,
- // BBS
- double& brim_width_max,
- std::map& brim_width_map)
-{
- const auto scaled_resolution = scaled(print.config().resolution.value);
-
- assert(print.objects().size() == bottom_layers_expolygons.size());
- std::unordered_set top_level_objects_idx;
- top_level_objects_idx.reserve(top_level_objects_with_brim.size());
- for (const PrintObject *object : top_level_objects_with_brim)
- top_level_objects_idx.insert(object->id().id);
-
- ExPolygons brim_area;
- ExPolygons no_brim_area;
- brim_width_max = 0;
- for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) {
- const PrintObject *object = print.objects()[print_object_idx];
- const BrimType brim_type = object->config().brim_type.value;
- const float brim_object_gap = scale_(object->config().brim_object_gap.value);
- // recording the autoAssigned brimWidth and corresponding objs
- double brimWidthAuto = object->config().brim_width.value;
- double flowWidth = print.brim_flow().scaled_spacing() * SCALING_FACTOR;
- brimWidthAuto = floor(brimWidthAuto / flowWidth / 2) * flowWidth * 2;
- brim_width_map.insert(std::make_pair(object->id(), brimWidthAuto));
- brim_width_max = std::max(brim_width_max, brimWidthAuto);
- const float brim_width = scale_(brimWidthAuto);
- const bool is_top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end();
-
- ExPolygons brim_area_object;
- ExPolygons no_brim_area_object;
- for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx]) {
- if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim)
- append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_object_gap, ClipperLib::jtRound, scaled_resolution), offset(ex_poly.contour, brim_object_gap, ClipperLib::jtSquare)));
-
- // After 7ff76d07684858fd937ef2f5d863f105a10f798e offset and shrink don't work with CW polygons (holes), so let's make it CCW.
- Polygons ex_poly_holes_reversed = ex_poly.holes;
- polygons_reverse(ex_poly_holes_reversed);
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, shrink_ex(ex_poly_holes_reversed, no_brim_offset, ClipperLib::jtSquare));
-
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset, ClipperLib::jtSquare), ex_poly_holes_reversed));
-
- if (brim_type != BrimType::btNoBrim)
- append(no_brim_area_object, offset_ex(ExPolygon(ex_poly.contour), brim_object_gap, ClipperLib::jtSquare));
-
- no_brim_area_object.emplace_back(ex_poly.contour);
- }
-
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim)
- append(brim_area_object, diff_ex(offset(support_contour, brim_width + brim_object_gap, ClipperLib::jtRound, scaled_resolution), offset(support_contour, brim_object_gap)));
-
- if (brim_type != BrimType::btNoBrim)
- append(no_brim_area_object, offset_ex(ExPolygon(support_contour), brim_object_gap));
-
- no_brim_area_object.emplace_back(support_contour);
- }
- }
-
- for (const PrintInstance &instance : object->instances()) {
- append_and_translate(brim_area, brim_area_object, instance);
- append_and_translate(no_brim_area, no_brim_area_object, instance);
- }
- }
-
- return diff_ex(brim_area, no_brim_area);
-}
-
-// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders
-static ExPolygons top_level_outer_brim_area(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim,
- const float no_brim_offset, double& brim_width_max, std::map& brim_width_map,
- std::map& brimAreaMap,
- std::map& supportBrimAreaMap, std::vector>& objPrintVec)
-{
- std::unordered_set top_level_objects_idx;
- top_level_objects_idx.reserve(top_level_objects_with_brim.size());
- for (const PrintObject* object : top_level_objects_with_brim)
- top_level_objects_idx.insert(object->id().id);
-
- unsigned int support_material_extruder = 1;
- if (print.has_support_material()) {
- assert(top_level_objects_with_brim.front()->config().support_filament >= 0);
- if (top_level_objects_with_brim.front()->config().support_filament > 0)
- support_material_extruder = top_level_objects_with_brim.front()->config().support_filament;
- }
-
- ExPolygons brim_area;
- ExPolygons no_brim_area;
- brim_width_max = 0;
- struct brimWritten {
- bool obj;
- bool sup;
- };
- std::map brimToWrite;
- for (const auto& objectWithExtruder : objPrintVec)
- brimToWrite.insert({ objectWithExtruder.first, {true,true} });
-
- for (unsigned int extruderNo : print.extruders()) {
- ++extruderNo;
- for (const auto &objectWithExtruder : objPrintVec) {
- const PrintObject* object = print.get_object(objectWithExtruder.first);
- const BrimType brim_type = object->config().brim_type.value;
- const float brim_offset = scale_(object->config().brim_object_gap.value);
- // recording the autoAssigned brimWidth and corresponding objs
- double brimWidthAuto = object->config().brim_width.value;
- double flowWidth = print.brim_flow().scaled_spacing() * SCALING_FACTOR;
- brimWidthAuto = floor(brimWidthAuto / flowWidth / 2) * flowWidth * 2;
- brim_width_map.insert(std::make_pair(object->id(), brimWidthAuto));
- brim_width_max = std::max(brim_width_max, brimWidthAuto);
- const float brim_width = scale_(brimWidthAuto);
- const bool is_top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end();
-
- ExPolygons nullBrim;
- brimAreaMap.insert(std::make_pair(object->id(), nullBrim));
- ExPolygons brim_area_object;
- ExPolygons brim_area_support;
- ExPolygons no_brim_area_object;
- ExPolygons no_brim_area_support;
- if (objectWithExtruder.second == extruderNo && brimToWrite.at(object->id()).obj) {
- for (const ExPolygon& ex_poly : object->layers().front()->lslices) {
- if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim) {
- append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset, jtRound, SCALED_RESOLUTION),
- offset_ex(ex_poly.contour, brim_offset)));
- }
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, offset_ex(ex_poly.holes, -no_brim_offset));
-
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly.holes));
-
- if (brim_type != BrimType::btNoBrim)
- append(no_brim_area_object, offset_ex(ExPolygon(ex_poly.contour), brim_offset));
-
- no_brim_area_object.emplace_back(ex_poly.contour);
- }
- brimToWrite.at(object->id()).obj = false;
- for (const PrintInstance& instance : object->instances()) {
- if (!brim_area_object.empty())
- append_and_translate(brim_area, brim_area_object, instance, print, brimAreaMap);
- append_and_translate(no_brim_area, no_brim_area_object, instance);
- }
- if (brimAreaMap.find(object->id()) != brimAreaMap.end())
- expolygons_append(brim_area, brimAreaMap[object->id()]);
- }
- if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) {
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- //BBS: no brim offset for supports
- if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim)
- append(brim_area_support, diff_ex(offset(support_contour, brim_width, jtRound, SCALED_RESOLUTION), offset(support_contour, 0)));
-
- if (brim_type != BrimType::btNoBrim)
- append(no_brim_area_support, offset_ex(support_contour, 0));
-
- no_brim_area_support.emplace_back(support_contour);
- }
- }
-
- brimToWrite.at(object->id()).sup = false;
- for (const PrintInstance& instance : object->instances()) {
- if (!brim_area_support.empty())
- append_and_translate(brim_area, brim_area_support, instance, print, supportBrimAreaMap);
- append_and_translate(no_brim_area, no_brim_area_support, instance);
- }
- if (supportBrimAreaMap.find(object->id()) != supportBrimAreaMap.end())
- expolygons_append(brim_area, supportBrimAreaMap[object->id()]);
- }
- }
- }
- for (const PrintObject* object : print.objects()) {
- if (brimAreaMap.find(object->id()) != brimAreaMap.end())
- brimAreaMap[object->id()] = diff_ex(brimAreaMap[object->id()], no_brim_area);
- if (supportBrimAreaMap.find(object->id()) != supportBrimAreaMap.end())
- supportBrimAreaMap[object->id()] = diff_ex(supportBrimAreaMap[object->id()], no_brim_area);
- }
- return diff_ex(std::move(brim_area), no_brim_area);
-}
-static ExPolygons inner_brim_area(const Print &print,
- const ConstPrintObjectPtrs &top_level_objects_with_brim,
- const std::vector &bottom_layers_expolygons,
- const float no_brim_offset)
-{
- assert(print.objects().size() == bottom_layers_expolygons.size());
- std::unordered_set top_level_objects_idx;
- top_level_objects_idx.reserve(top_level_objects_with_brim.size());
- for (const PrintObject *object : top_level_objects_with_brim)
- top_level_objects_idx.insert(object->id().id);
-
- ExPolygons brim_area;
- ExPolygons no_brim_area;
- Polygons holes;
- for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) {
- const PrintObject *object = print.objects()[print_object_idx];
- const BrimType brim_type = object->config().brim_type.value;
- const float brim_object_gap = scale_(object->config().brim_object_gap.value);
- double flowWidth = print.brim_flow().scaled_spacing() * SCALING_FACTOR;
- const float brim_width = scale_(floor(object->config().brim_width.value / flowWidth / 2) * flowWidth * 2);
- const bool top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end();
-
- ExPolygons brim_area_object;
- ExPolygons no_brim_area_object;
- Polygons holes_object;
- for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx]) {
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) {
- if (top_outer_brim)
- no_brim_area_object.emplace_back(ex_poly);
- else
- append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_object_gap, ClipperLib::jtSquare), offset(ex_poly.contour, brim_object_gap, ClipperLib::jtSquare)));
- }
-
- // After 7ff76d07684858fd937ef2f5d863f105a10f798e offset and shrink don't work with CW polygons (holes), so let's make it CCW.
- Polygons ex_poly_holes_reversed = ex_poly.holes;
- polygons_reverse(ex_poly_holes_reversed);
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim)
- append(brim_area_object, diff_ex(shrink_ex(ex_poly_holes_reversed, brim_object_gap, ClipperLib::jtSquare), shrink_ex(ex_poly_holes_reversed, brim_width + brim_object_gap, ClipperLib::jtSquare)));
-
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset, ClipperLib::jtSquare), ex_poly_holes_reversed));
-
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, diff_ex(ExPolygon(ex_poly.contour), shrink_ex(ex_poly_holes_reversed, no_brim_offset, ClipperLib::jtSquare)));
-
- append(holes_object, ex_poly_holes_reversed);
- }
- append(no_brim_area_object, offset_ex(bottom_layers_expolygons[print_object_idx], brim_object_gap, ClipperLib::jtSquare));
-
- for (const PrintInstance &instance : object->instances()) {
- append_and_translate(brim_area, brim_area_object, instance);
- append_and_translate(no_brim_area, no_brim_area_object, instance);
- append_and_translate(holes, holes_object, instance);
- }
- }
-
- return diff_ex(intersection_ex(to_polygons(std::move(brim_area)), holes), no_brim_area);
-}
-
-// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders
-static ExPolygons inner_brim_area(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim,
- const float no_brim_offset, std::map& brimAreaMap,
- std::map& supportBrimAreaMap,
- std::vector>& objPrintVec)
-{
- std::unordered_set top_level_objects_idx;
- top_level_objects_idx.reserve(top_level_objects_with_brim.size());
- for (const PrintObject* object : top_level_objects_with_brim)
- top_level_objects_idx.insert(object->id().id);
-
- unsigned int support_material_extruder = 1;
- if (print.has_support_material()) {
- assert(top_level_objects_with_brim.front()->config().support_filament >= 0);
- if (top_level_objects_with_brim.front()->config().support_filament > 0)
- support_material_extruder = top_level_objects_with_brim.front()->config().support_filament;
- }
-
- ExPolygons brim_area;
- ExPolygons no_brim_area;
- Polygons holes;
- Polygon bedShape(get_bed_shape(print.config()));
- holes.emplace_back(get_bed_shape(print.config()));
- std::map innerBrimAreaMap;
- std::map innerSupportBrimAreaMap;
-
- struct brimWritten {
- bool obj;
- bool sup;
- };
- std::map brimToWrite;
- for (const auto& objectWithExtruder : objPrintVec)
- brimToWrite.insert({ objectWithExtruder.first, {true,true} });
-
-
- for (unsigned int extruderNo : print.extruders()) {
- ++extruderNo;
- for (const auto& objectWithExtruder : objPrintVec) {
- const PrintObject* object = print.get_object(objectWithExtruder.first);
- const BrimType brim_type = object->config().brim_type.value;
- const float brim_offset = scale_(object->config().brim_object_gap.value);
- double flowWidth = print.brim_flow().scaled_spacing() * SCALING_FACTOR;
- const float brim_width = scale_(floor(object->config().brim_width.value / flowWidth / 2) * flowWidth * 2);
- const bool top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end();
-
- ExPolygons brim_area_object;
- ExPolygons no_brim_area_object;
- ExPolygons brim_area_support;
- ExPolygons no_brim_area_support;
- Polygons holes_object;
- Polygons holes_support;
- if (objectWithExtruder.second == extruderNo && brimToWrite.at(object->id()).obj) {
- for (const ExPolygon& ex_poly : object->layers().front()->lslices) {
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) {
- if (top_outer_brim)
- no_brim_area_object.emplace_back(ex_poly);
- else
- append(brim_area_object, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset, jtRound, SCALED_RESOLUTION), offset_ex(ex_poly.contour, brim_offset)));
- }
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner)
- append(brim_area_object, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset)));
- if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly.holes));
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
- append(no_brim_area_object, offset_ex(ex_poly.holes, -no_brim_offset));
- append(holes_object, ex_poly.holes);
- }
- append(no_brim_area_object, offset_ex(object->layers().front()->lslices, brim_offset));
- brimToWrite.at(object->id()).obj = false;
- for (const PrintInstance& instance : object->instances()) {
- if (!brim_area_object.empty())
- append_and_translate(brim_area, brim_area_object, instance, print, innerBrimAreaMap);
- append_and_translate(no_brim_area, no_brim_area_object, instance);
- append_and_translate(holes, holes_object, instance);
- }
- if (innerBrimAreaMap.find(object->id()) != innerBrimAreaMap.end())
- expolygons_append(brim_area, innerBrimAreaMap[object->id()]);
- }
- if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) {
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) {
- if (!top_outer_brim)
- append(brim_area_support, diff_ex(offset_ex(support_contour, brim_width + brim_offset, jtRound, SCALED_RESOLUTION), offset_ex(support_contour, brim_offset)));
- }
- if (brim_type != BrimType::btNoBrim)
- append(no_brim_area_support, offset_ex(support_contour, 0));
- no_brim_area_support.emplace_back(support_contour);
- }
- }
- }
- brimToWrite.at(object->id()).sup = false;
- for (const PrintInstance& instance : object->instances()) {
- if (!brim_area_support.empty())
- append_and_translate(brim_area, brim_area_support, instance, print, innerSupportBrimAreaMap);
- append_and_translate(no_brim_area, no_brim_area_support, instance);
- append_and_translate(holes, holes_support, instance);
- }
- if (innerSupportBrimAreaMap.find(object->id()) != innerSupportBrimAreaMap.end())
- expolygons_append(brim_area, innerSupportBrimAreaMap[object->id()]);
- }
- }
- for (const PrintObject* object : print.objects()) {
- if (innerBrimAreaMap.find(object->id()) != innerBrimAreaMap.end()) {
- innerBrimAreaMap[object->id()] = intersection_ex(to_polygons(innerBrimAreaMap[object->id()]), holes);
- append(brimAreaMap[object->id()], innerBrimAreaMap[object->id()]);
- }
- if (innerSupportBrimAreaMap.find(object->id()) != innerSupportBrimAreaMap.end()) {
- innerSupportBrimAreaMap[object->id()] = intersection_ex(to_polygons(innerSupportBrimAreaMap[object->id()]), holes);
- append(supportBrimAreaMap[object->id()], innerSupportBrimAreaMap[object->id()]);
- }
- }
- for (const PrintObject* object : print.objects()) {
- if (brimAreaMap.find(object->id()) != brimAreaMap.end())
- brimAreaMap[object->id()] = diff_ex(brimAreaMap[object->id()], no_brim_area);
- if (supportBrimAreaMap.find(object->id()) != supportBrimAreaMap.end())
- supportBrimAreaMap[object->id()] = diff_ex(supportBrimAreaMap[object->id()], no_brim_area);
- }
- brim_area = intersection_ex(to_polygons(brim_area), holes);
- append(no_brim_area, brim_area);
- return no_brim_area;
-}
-
-//BBS maximum temperature difference from print object class
-double getTemperatureFromExtruder(const PrintObject* printObject) {
- auto print = printObject->print();
- std::vector extrudersFirstLayer;
- auto firstLayerRegions = printObject->layers().front()->regions();
- if (!firstLayerRegions.empty()) {
- for (const LayerRegion* regionPtr : firstLayerRegions) {
- if (regionPtr->has_extrusions())
- extrudersFirstLayer.push_back(regionPtr->region().extruder(frExternalPerimeter));
- }
- }
-
- const PrintConfig& config = print->config();
- int curr_bed_type = config.option("curr_bed_type")->getInt();
- const ConfigOptionInts* bed_temp_1st_layer_opt = config.option(get_bed_temp_1st_layer_key((BedType)curr_bed_type));
-
- double maxDeltaTemp = 0;
- for (auto extruderID : extrudersFirstLayer) {
- int bedTemp = bed_temp_1st_layer_opt->get_at(extruderID - 1);
- if (bedTemp > maxDeltaTemp)
- maxDeltaTemp = bedTemp;
- }
-
- return maxDeltaTemp;
-}
//BBS adhesion coefficients from print object class
double getadhesionCoeff(const PrintObject* printObject)
{
@@ -711,50 +256,6 @@ bool compSecondMoment(const ExPolygons& expolys, double& smExpolysX, double& smE
return true;
}
-
-
-
-//BBS: config brimwidth by volumes
-double configBrimWidthByVolumes(double deltaT, double adhesion, double maxSpeed, const ModelVolume* modelVolumePtr, const ExPolygons& expolys)
-{
- // height of a volume
- double height = 0;
- if (modelVolumePtr->is_model_part()) {
- auto rawBoundingbox = modelVolumePtr->mesh().transformed_bounding_box(modelVolumePtr->get_matrix());
- auto bbox = modelVolumePtr->get_object()->instances.front()->transform_bounding_box(rawBoundingbox);
- auto bbox_size = bbox.size();
- height = bbox_size(2);
- }
-
- // sencond moment of the expolygons of the first layer of the volume
- double Ixx = -1.e30, Iyy = -1.e30;
- if (!expolys.empty()) {
- if (!compSecondMoment(expolys, Ixx, Iyy))
- Ixx = Iyy = -1.e30;
- }
- Ixx = Ixx * SCALING_FACTOR * SCALING_FACTOR * SCALING_FACTOR * SCALING_FACTOR;
- Iyy = Iyy * SCALING_FACTOR * SCALING_FACTOR * SCALING_FACTOR * SCALING_FACTOR;
-
- // bounding box of the expolygons of the first layer of the volume
- BoundingBox bbox2;
- for (const auto& expoly : expolys)
- bbox2.merge(get_extents(expoly.contour));
- const double& bboxX = bbox2.size()(0);
- const double& bboxY = bbox2.size()(1);
- double thermalLength = sqrt(bboxX * bboxX + bboxY * bboxY) * SCALING_FACTOR;
- double thermalLengthRef = Model::getThermalLength(modelVolumePtr);
-
- double height_to_area = std::max(height / Ixx * (bbox2.size()(1) * SCALING_FACTOR), height / Iyy * (bbox2.size()(0) * SCALING_FACTOR));
- double brim_width = adhesion * std::min(std::min(std::max(height_to_area * maxSpeed / 24, thermalLength * 8. / thermalLengthRef * std::min(height, 30.) / 30.), 18.), 1.5 * thermalLength);
- // small brims are omitted
- if (brim_width < 5 && brim_width < 1.5 * thermalLength)
- brim_width = 0;
- // large brims are omitted
- if (brim_width > 18) brim_width = 18.;
-
- return brim_width;
-}
-
//BBS: config brimwidth by group of volumes
double configBrimWidthByVolumeGroups(double adhesion, double maxSpeed, const std::vector modelVolumePtrs, const ExPolygons& expolys, double &groupHeight)
{
@@ -857,6 +358,14 @@ static ExPolygons make_brim_ears(const PrintObject* object, const double& flowWi
if (brim_ear_points.size() <= 0) {
return mouse_ears_ex;
}
+ //ORCA: Painted ears can snap to the EFC-adjusted outline when enabled.
+ const bool use_efc_outline = use_brim_efc_outline(*object);
+ const ExPolygons &raw_outline = object->layers().front()->lslices;
+ //ORCA: Lazily computed EFC-adjusted bottom outline.
+ //Stored separately so we can avoid recomputation unless EFC snapping is used.
+ ExPolygons efc_outline_storage;
+ const ExPolygons* efc_outline = nullptr;
+
const Geometry::Transformation& trsf = object->model_object()->instances[0]->get_transformation();
Transform3d model_trsf = trsf.get_matrix_no_offset();
const Point ¢er_offset = object->center_offset();
@@ -880,6 +389,29 @@ static ExPolygons make_brim_ears(const PrintObject* object, const double& flowWi
Vec3f pos = pt.transform(model_trsf);
int32_t pt_x = scale_(pos.x());
int32_t pt_y = scale_(pos.y());
+
+ //ORCA: Snap painted ears to the EFC-adjusted outline when enabled.
+ if (use_efc_outline) {
+ if (efc_outline == nullptr) {
+ //ORCA: Compute EFC-adjusted outline lazily for painted ear snapping.
+ efc_outline_storage = get_print_object_bottom_layer_expolygons(*object);
+ efc_outline = &efc_outline_storage;
+ }
+
+ if (!efc_outline->empty()) {
+ Point closest_point;
+ //ORCA: Snap within the matching island to avoid drifting to another island.
+ if (closest_point_on_matching_island(
+ raw_outline,
+ *efc_outline,
+ Point(pt_x, pt_y),
+ closest_point)) {
+ pt_x = closest_point.x();
+ pt_y = closest_point.y();
+ }
+ }
+ }
+
mouse_ears_ex.back().contour.translate(Point(pt_x, pt_y));
}
return mouse_ears_ex;
@@ -926,6 +458,14 @@ static ExPolygons outer_inner_brim_area(const Print& print,
const bool has_outer_brim = brim_type == btOuterOnly || brim_type == btOuterAndInner || brim_type == btAutoBrim || use_auto_brim_ears || use_brim_ears;
coord_t ear_detection_length = scale_(object->config().brim_ears_detection_length.value);
coordf_t brim_ears_max_angle = object->config().brim_ears_max_angle.value;
+ //ORCA: Select brim base slices from EFC-compensated outline when enabled.
+ const bool use_efc_outline = use_brim_efc_outline(*object);
+ ExPolygons brim_slices_storage;
+ const ExPolygons* brim_slices = nullptr;
+ //ORCA: Select EFC-adjusted bottom outline when enabled.
+ if (use_efc_outline)
+ brim_slices_storage = get_print_object_bottom_layer_expolygons(*object);
+ brim_slices = use_efc_outline ? &brim_slices_storage : &object->layers().front()->lslices;
ExPolygons brim_area_object;
ExPolygons no_brim_area_object;
@@ -961,64 +501,72 @@ static ExPolygons outer_inner_brim_area(const Print& print,
double brimWidthRaw = configBrimWidthByVolumeGroups(adhesion, maxSpeed, groupVolumePtrs, volumeGroup.slices, groupHeight);
brim_width = scale_(floor(brimWidthRaw / flowWidth / 2) * flowWidth * 2);
}
- for (const ExPolygon& ex_poly : volumeGroup.slices) {
- // BBS: additional brim width will be added if part's adhesion area is too small and brim is not generated
- float brim_width_mod;
- if (brim_width < scale_(5.) && has_brim_auto && groupHeight > 10.) {
- brim_width_mod = ex_poly.area() / ex_poly.contour.length() < scaled_half_min_adh_length
- && brim_width < scaled_flow_width ? brim_width + scaled_additional_brim_width : brim_width;
- }
- else {
- brim_width_mod = brim_width;
- }
- //BBS: brim width should be limited to the 1.5*boundingboxSize of a single polygon.
- if (has_brim_auto) {
- BoundingBox bbox2 = ex_poly.contour.bounding_box();
- brim_width_mod = std::min(brim_width_mod, float(std::max(bbox2.size()(0), bbox2.size()(1))));
- }
- brim_width_mod = floor(brim_width_mod / scaled_flow_width / 2) * scaled_flow_width * 2;
-
- Polygons ex_poly_holes_reversed = ex_poly.holes;
- polygons_reverse(ex_poly_holes_reversed);
-
- if (has_outer_brim) {
- // BBS: inner and outer boundary are offset from the same polygon incase of round off error.
- auto innerExpoly = offset_ex(ex_poly.contour, brim_offset, jtRound, SCALED_RESOLUTION);
- ExPolygons outerExpoly;
- if (use_brim_ears) {
- outerExpoly = make_brim_ears(object, flowWidth, brim_offset, flow, true);
- //outerExpoly = offset_ex(outerExpoly, brim_width_mod, jtRound, SCALED_RESOLUTION);
- } else if (use_auto_brim_ears) {
- coord_t size_ear = (brim_width_mod - brim_offset - flow.scaled_spacing());
- outerExpoly = make_brim_ears_auto(innerExpoly, size_ear, ear_detection_length, brim_ears_max_angle, true);
- }else {
- outerExpoly = offset_ex(innerExpoly, brim_width_mod, jtRound, SCALED_RESOLUTION);
- }
- append(brim_area_object, diff_ex(outerExpoly, innerExpoly));
- }
- if (has_inner_brim) {
- ExPolygons outerExpoly;
- auto innerExpoly = offset_ex(ex_poly_holes_reversed, -brim_width - brim_offset);
- if (use_brim_ears) {
- outerExpoly = make_brim_ears(object, flowWidth, brim_offset, flow, false);
- } else if (use_auto_brim_ears) {
- coord_t size_ear = (brim_width - brim_offset - flow.scaled_spacing());
- outerExpoly = make_brim_ears_auto(offset_ex(ex_poly_holes_reversed, -brim_offset), size_ear, ear_detection_length, brim_ears_max_angle, false);
- }else {
- outerExpoly = offset_ex(ex_poly_holes_reversed, -brim_offset);
- }
- append(brim_area_object, intersection_ex(diff_ex(outerExpoly, innerExpoly), ex_poly_holes_reversed));
- }
- if (!has_inner_brim) {
- // BBS: brim should be apart from holes
- append(no_brim_area_object, diff_ex(ex_poly_holes_reversed, offset_ex(ex_poly_holes_reversed, -no_brim_offset)));
- }
- if (!has_outer_brim)
- append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly_holes_reversed));
- append(holes_object, ex_poly_holes_reversed);
+ ExPolygons volume_group_slices_efc;
+ const ExPolygons* volume_group_slices = &volumeGroup.slices;
+ if (use_efc_outline) {
+ //ORCA: When using EFC outline, restrict per-volume-group slices to the
+ // EFC-adjusted bottom footprint to keep brim width heuristics consistent.
+ volume_group_slices_efc = intersection_ex(*brim_slices, volumeGroup.slices);
+ volume_group_slices = &volume_group_slices_efc;
}
- }
- auto objectIsland = offset_ex(object->layers().front()->lslices, brim_offset, jtRound, SCALED_RESOLUTION);
+ for (const ExPolygon& ex_poly : *volume_group_slices) {
+ // BBS: additional brim width will be added if part's adhesion area is too small and brim is not generated
+ float brim_width_mod;
+ if (brim_width < scale_(5.) && has_brim_auto && groupHeight > 10.) {
+ brim_width_mod = ex_poly.area() / ex_poly.contour.length() < scaled_half_min_adh_length
+ && brim_width < scaled_flow_width ? brim_width + scaled_additional_brim_width : brim_width;
+ }
+ else {
+ brim_width_mod = brim_width;
+ }
+ //BBS: brim width should be limited to the 1.5*boundingboxSize of a single polygon.
+ if (has_brim_auto) {
+ BoundingBox bbox2 = ex_poly.contour.bounding_box();
+ brim_width_mod = std::min(brim_width_mod, float(std::max(bbox2.size()(0), bbox2.size()(1))));
+ }
+ brim_width_mod = floor(brim_width_mod / scaled_flow_width / 2) * scaled_flow_width * 2;
+
+ Polygons ex_poly_holes_reversed = ex_poly.holes;
+ polygons_reverse(ex_poly_holes_reversed);
+
+ if (has_outer_brim) {
+ // BBS: inner and outer boundary are offset from the same polygon incase of round off error.
+ auto innerExpoly = offset_ex(ex_poly.contour, brim_offset, jtRound, SCALED_RESOLUTION);
+ ExPolygons outerExpoly;
+ if (use_brim_ears) {
+ outerExpoly = make_brim_ears(object, flowWidth, brim_offset, flow, true);
+ //outerExpoly = offset_ex(outerExpoly, brim_width_mod, jtRound, SCALED_RESOLUTION);
+ } else if (use_auto_brim_ears) {
+ coord_t size_ear = (brim_width_mod - brim_offset - flow.scaled_spacing());
+ outerExpoly = make_brim_ears_auto(innerExpoly, size_ear, ear_detection_length, brim_ears_max_angle, true);
+ }else {
+ outerExpoly = offset_ex(innerExpoly, brim_width_mod, jtRound, SCALED_RESOLUTION);
+ }
+ append(brim_area_object, diff_ex(outerExpoly, innerExpoly));
+ }
+ if (has_inner_brim) {
+ ExPolygons outerExpoly;
+ auto innerExpoly = offset_ex(ex_poly_holes_reversed, -brim_width - brim_offset);
+ if (use_brim_ears) {
+ outerExpoly = make_brim_ears(object, flowWidth, brim_offset, flow, false);
+ } else if (use_auto_brim_ears) {
+ coord_t size_ear = (brim_width - brim_offset - flow.scaled_spacing());
+ outerExpoly = make_brim_ears_auto(offset_ex(ex_poly_holes_reversed, -brim_offset), size_ear, ear_detection_length, brim_ears_max_angle, false);
+ }else {
+ outerExpoly = offset_ex(ex_poly_holes_reversed, -brim_offset);
+ }
+ append(brim_area_object, intersection_ex(diff_ex(outerExpoly, innerExpoly), ex_poly_holes_reversed));
+ }
+ if (!has_inner_brim) {
+ // BBS: brim should be apart from holes
+ append(no_brim_area_object, diff_ex(ex_poly_holes_reversed, offset_ex(ex_poly_holes_reversed, -no_brim_offset)));
+ }
+ if (!has_outer_brim)
+ append(no_brim_area_object, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly_holes_reversed));
+ append(holes_object, ex_poly_holes_reversed);
+ }
+ }
+ auto objectIsland = offset_ex(*brim_slices, brim_offset, jtRound, SCALED_RESOLUTION);
append(no_brim_area_object, objectIsland);
brimToWrite.at(object->id()).obj = false;
@@ -1261,393 +809,8 @@ static Polylines connect_brim_lines(Polylines &&polylines, const Polygons &brim_
return std::move(polylines);
}
-
-// BBS: this function is used to generate brim for inner island inside holes
-// Collect island + brim area to be minused when generating inner brim for holes
-static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim,
- ExtrusionEntityCollection &brim, ExPolygons &islands_area_ex)
-{
- const auto scaled_resolution = scaled(print.config().resolution.value);
-
- auto save_polygon_if_is_inner_island = [scaled_resolution](const Polygons& holes_area, Polygon& contour, std::map& hole_island_pair) {
- for (size_t i = 0; i < holes_area.size(); i++) {
- Polygons contour_polys;
- contour_polys.push_back(contour);
- if (diff_ex(contour_polys, { holes_area[i] }).empty()) {
- // BBS: this is an inner island inside holes_area[i], save
- contour.douglas_peucker(scaled_resolution);
- hole_island_pair[i].push_back(contour);
- break;
- }
- }
- };
-
- Flow flow = print.brim_flow();
- for (const PrintObject* object : top_level_objects_with_brim) {
- const BrimType brim_type = object->config().brim_type.value;
- // BBS: don't need to handle this object if hasn't enabled outer_brim
- if (brim_type == BrimType::btNoBrim)
- continue;
-
- //BBS: 1 collect holes area which is used to limit the brim of inner island
- Polygons holes_area;
- for (const ExPolygon& ex_poly : object->layers().front()->lslices)
- polygons_append(holes_area, ex_poly.holes);
-
-
- //BBS: 2 get the island polygons inside holes, saved as map
- std::map hole_island_pair;
- for (const ExPolygon& ex_poly : object->layers().front()->lslices) {
- Polygon counter = ex_poly.contour;
- save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair);
- }
-
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- Polygon counter = support_contour;
- save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair);
- }
- }
-
- //BBS: 3 generate loops, only save part of loop which inside hole
- const float brim_offset = scale_(object->config().brim_object_gap.value);
- const float brim_width = scale_(object->config().brim_width.value);
- if (brim_type == BrimType::btInnerOnly) {
- // If brim_type is btInnerOnly, we actually doesn't generate loops for inner island.
- // Only update islands_area_ex and return
- for (auto it = hole_island_pair.begin(); it != hole_island_pair.end(); it++) {
- ExPolygons islands_area_ex_object = intersection_ex(offset(it->second, brim_offset), offset(holes_area[it->first], -brim_offset));
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_object, instance);
- }
- }
- else {
- size_t num_loops = size_t(floor(brim_width / float(flow.scaled_spacing())));
- for (auto it = hole_island_pair.begin(); it != hole_island_pair.end(); it++) {
- Polygons loops;
- Polygons inner_islands = offset(it->second, brim_offset);
- Polygons brimable_area = offset(holes_area[it->first], -brim_offset); //offset to keep away from hole
- Polygons contour = inner_islands;
- for (size_t i = 0; i < num_loops; ++i) {
- contour = offset(contour, float(flow.scaled_spacing()), jtSquare);
- for (Polygon& poly : contour)
- poly.douglas_peucker(scaled_resolution);
- polygons_append(loops, offset(contour, -0.5f * float(flow.scaled_spacing())));
- }
- // BBS: to be checked.
- //loops = union_pt_chained_outside_in(loops, false);
- loops = union_pt_chained_outside_in(loops);
-
- std::vector loops_pl_by_levels;
- {
- Polylines loops_pl = to_polylines(loops);
- loops_pl_by_levels.assign(loops_pl.size(), Polylines());
- tbb::parallel_for(tbb::blocked_range(0, loops_pl.size()),
- [&loops_pl_by_levels, &loops_pl, &brimable_area](const tbb::blocked_range& range) {
- for (size_t i = range.begin(); i < range.end(); ++i) {
- loops_pl_by_levels[i] = chain_polylines(intersection_pl({ std::move(loops_pl[i]) }, brimable_area));
- }
- });
- }
-
- // BBS: Reduce down to the ordered list of polylines.
- Polylines all_loops_object;
- for (Polylines& polylines : loops_pl_by_levels)
- append(all_loops_object, std::move(polylines));
- loops_pl_by_levels.clear();
-
- optimize_polylines_by_reversing(&all_loops_object);
- all_loops_object = connect_brim_lines(std::move(all_loops_object), offset(inner_islands, float(SCALED_EPSILON)), float(flow.scaled_spacing()) * 2.f);
-
- Polylines final_loops;
- for (const PrintInstance& instance : object->instances()) {
- size_t dst_idx = final_loops.size();
- final_loops.insert(final_loops.end(), all_loops_object.begin(), all_loops_object.end());
- Point instance_shift = instance.shift_without_plate_offset();
- for (; dst_idx < final_loops.size(); ++dst_idx)
- final_loops[dst_idx].translate(instance_shift);
-
- }
- extrusion_entities_append_loops_and_paths(brim.entities, std::move(final_loops),
- erBrim, float(flow.mm3_per_mm()), float(flow.width()),
- float(print.skirt_first_layer_height()));
-
- //BBS: save all inner island and inner island brim area here, which is necesary if generate inner brim for holes
- //Inner brim of holes must not occupy this area
- ExPolygons islands_area_ex_object = intersection_ex(contour, brimable_area);
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_object, instance);
- }
- }
- }
-}
-
-//BBS: the brim are generated one by one, and sorted by objs/supports and extruders
-static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim,
- std::map& innerbrimAreaMap,
- std::map& innerSupportBrimAreaMap,
- ExPolygons& islands_area_ex, ExPolygons& NobrimArea,
- std::vector>& objPrintVec)
-{
- auto save_polygon_if_is_inner_island = [](const Polygons& holes_area, Polygon& counter, std::map& hole_island_pair) {
- for (size_t i = 0; i < holes_area.size(); i++) {
- if (diff_ex(Polygons{ counter }, { holes_area[i] }).empty()) {
- // BBS: this is an inner island inside holes_area[i], save
- counter.douglas_peucker(SCALED_RESOLUTION);
- hole_island_pair[i].push_back(counter);
- break;
- }
- }
- };
-
- unsigned int support_material_extruder = 1;
- if (print.has_support_material()) {
- assert(top_level_objects_with_brim.front()->config().support_filament >= 0);
- if (top_level_objects_with_brim.front()->config().support_filament > 0)
- support_material_extruder = top_level_objects_with_brim.front()->config().support_filament;
- }
-
- std::unordered_set top_level_objects_idx;
- top_level_objects_idx.reserve(top_level_objects_with_brim.size());
- for (const PrintObject* object : top_level_objects_with_brim)
- top_level_objects_idx.insert(object->id().id);
-
- struct brimWritten {
- bool obj;
- bool sup;
- };
- std::map brimToWrite;
- for (const auto& objectWithExtruder : objPrintVec)
- if (top_level_objects_idx.find(objectWithExtruder.first.id) != top_level_objects_idx.end())
- brimToWrite.insert({ objectWithExtruder.first, {true,true} });
-
- Flow flow = print.brim_flow();
- for (unsigned int extruderNo : print.extruders()) {
- ++extruderNo;
- for (const auto& objectWithExtruder : objPrintVec) {
- if (top_level_objects_idx.find(objectWithExtruder.first.id) != top_level_objects_idx.end()) {
- const PrintObject* object = print.get_object(objectWithExtruder.first);
- const BrimType brim_type = object->config().brim_type.value;
- // BBS: don't need to handle this object if hasn't enabled outer_brim
- if (brim_type == BrimType::btNoBrim)
- continue;
-
- //BBS: 1 collect holes area which is used to limit the brim of inner island
- Polygons holes_area;
- for (const ExPolygon& ex_poly : object->layers().front()->lslices)
- polygons_append(holes_area, ex_poly.holes);
-
-
- //BBS: 2 get the island polygons inside holes, saved as map
- std::map hole_island_pair;
- for (const ExPolygon& ex_poly : object->layers().front()->lslices) {
- Polygon counter = ex_poly.contour;
- save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair);
- }
- std::map hole_island_pair_supports;
- if (!object->support_layers().empty()) {
- for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
- Polygon counter = support_contour;
- save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair_supports);
- }
- }
-
- //BBS: 3 generate loops, only save part of loop which inside hole
- const float brim_offset = scale_(object->config().brim_object_gap.value);
- const float brim_width = floor(scale_(object->config().brim_width.value) / 2 / flow.scaled_spacing()) * 2 * flow.scaled_spacing();
- if (objectWithExtruder.second == extruderNo && brimToWrite.at(object->id()).obj) {
- if (brim_type == BrimType::btInnerOnly) {
- // If brim_type is btInnerOnly, we actually doesn't generate loops for inner island.
- // Only update islands_area_ex and return
- for (auto it = hole_island_pair.begin(); it != hole_island_pair.end(); it++) {
- ExPolygons islands_area_ex_object = intersection_ex(offset(it->second, brim_offset), offset(holes_area[it->first], -brim_offset));
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_object, instance);
- }
- brimToWrite.at(object->id()).obj = false;
- }
- else {
- for (auto it = hole_island_pair.begin(); it != hole_island_pair.end(); it++) {
- Polygons loops;
- Polygons inner_islands = offset(it->second, brim_offset);
- Polygons brimable_area = offset(holes_area[it->first], -brim_offset); //offset to keep away from hole
- Polygons contour = offset(inner_islands, brim_offset + brim_width, jtRound, SCALED_RESOLUTION);
- for (Polygon& poly : contour)
- poly.douglas_peucker(SCALED_RESOLUTION);
-
-
- //BBS: save all inner island and inner island brim area here, which is necesary if generate inner brim for holes
- //Inner brim of holes must not occupy this area
- ExPolygons islands_area_ex_object = intersection_ex(contour, brimable_area);
- ExPolygons inner_islands_exp = offset_ex(inner_islands, 0.);
- islands_area_ex_object = diff_ex(islands_area_ex_object, inner_islands_exp);
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_object, instance, print, innerbrimAreaMap);
- }
- brimToWrite.at(object->id()).obj = false;
- }
- if (innerbrimAreaMap.find(object->id()) != innerbrimAreaMap.end())
- expolygons_append(islands_area_ex, innerbrimAreaMap[object->id()]);
- }
-
-
- if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) {
- if (brim_type == BrimType::btInnerOnly) {
- // If brim_type is btInnerOnly, we actually doesn't generate loops for inner island.
- // Only update islands_area_ex and return
- for (auto it = hole_island_pair_supports.begin(); it != hole_island_pair_supports.end(); it++) {
- ExPolygons islands_area_ex_support = intersection_ex(offset(it->second, 0), offset(holes_area[it->first], 0));
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_support, instance);
- }
- brimToWrite.at(object->id()).sup = false;
- }
- else {
- for (auto it = hole_island_pair_supports.begin(); it != hole_island_pair_supports.end(); it++) {
- Polygons loops;
- Polygons inner_islands = offset(it->second, 0);
- Polygons brimable_area = offset(holes_area[it->first], -float(flow.scaled_spacing())); //offset to keep away from hole
- Polygons contour = offset(inner_islands, brim_width, jtRound, SCALED_RESOLUTION);
- for (Polygon& poly : contour)
- poly.douglas_peucker(SCALED_RESOLUTION);
-
-
- //BBS: save all inner island and inner island brim area here, which is necesary if generate inner brim for holes
- //Inner brim of holes must not occupy this area
- ExPolygons islands_area_ex_support = intersection_ex(contour, brimable_area);
- ExPolygons inner_islands_exp = offset_ex(inner_islands, 0.);
- islands_area_ex_support = diff_ex(islands_area_ex_support, inner_islands_exp);
- for (const PrintInstance& instance : object->instances())
- append_and_translate(islands_area_ex, islands_area_ex_support, instance, print, innerSupportBrimAreaMap);
-
- }
- brimToWrite.at(object->id()).sup = false;
- }
- if (innerSupportBrimAreaMap.find(object->id()) != innerSupportBrimAreaMap.end())
- expolygons_append(islands_area_ex, innerSupportBrimAreaMap[object->id()]);
- }
- }
- }
- }
- islands_area_ex = diff_ex(islands_area_ex, NobrimArea);
- for (const PrintObject* object : print.objects()) {
- if (innerbrimAreaMap.find(object->id()) != innerbrimAreaMap.end())
- innerbrimAreaMap[object->id()] = diff_ex(innerbrimAreaMap[object->id()], NobrimArea);
- if (innerSupportBrimAreaMap.find(object->id()) != innerSupportBrimAreaMap.end())
- innerSupportBrimAreaMap[object->id()] = diff_ex(innerSupportBrimAreaMap[object->id()], NobrimArea);
- }
-}
-static void make_inner_brim(const Print &print,
- const ConstPrintObjectPtrs &top_level_objects_with_brim,
- const std::vector &bottom_layers_expolygons,
- ExtrusionEntityCollection &brim)
-{
- assert(print.objects().size() == bottom_layers_expolygons.size());
- const auto scaled_resolution = scaled(print.config().resolution.value);
-
- //BBS: generate brim for inner island first
- ExPolygons inner_islands_ex;
- make_inner_island_brim(print, top_level_objects_with_brim, brim, inner_islands_ex);
-
-#ifdef INNER_ISLAND_BRIM_DEBUG_TO_SVG
- static int irun = 0;
- BoundingBox bbox_svg;
- bbox_svg.merge(get_extents(inner_islands_ex));
- {
- std::stringstream stri;
- stri << "inner_island_and_brim_area_" << irun << ".svg";
- SVG svg(stri.str(), bbox_svg);
- svg.draw(to_polylines(inner_islands_ex), "blue");
- svg.Close();
- }
- ++ irun;
-#endif
-
- Flow flow = print.brim_flow();
- ExPolygons islands_ex = inner_brim_area(print, top_level_objects_with_brim, bottom_layers_expolygons, float(flow.scaled_spacing()));
- //BBS: brim of hole must not overlap with inner island and inner island brim
- if (!inner_islands_ex.empty()) {
- islands_ex = diff_ex(islands_ex, inner_islands_ex);
- }
-
- Polygons loops;
- islands_ex = offset_ex(islands_ex, -0.5f * float(flow.scaled_spacing()));// jtSquare seems not working when expandign the holes
- for (size_t i = 0; !islands_ex.empty(); ++i) {
- for (ExPolygon &poly_ex : islands_ex)
- poly_ex.douglas_peucker(scaled_resolution);
- polygons_append(loops, to_polygons(islands_ex));// jtSquare seems not working when expandign the holes
- islands_ex = offset_ex(islands_ex, -1.3f * float(flow.scaled_spacing()));
- islands_ex = offset_ex(islands_ex, .3f * float(flow.scaled_spacing()));
- }
-
- loops = union_pt_chained_outside_in(loops);
- std::reverse(loops.begin(), loops.end());
- extrusion_entities_append_loops(brim.entities, std::move(loops), erBrim, float(flow.mm3_per_mm()),
- float(flow.width()), float(print.skirt_first_layer_height()));
-}
-
-// BBS: generate inner brim by objs
-static void make_inner_brim(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim,
- std::map& brimAreaMap, std::map& supportBrimAreaMap,
- std::vector>& objPrintVec)
-{
- //BBS: generate brim for inner island first
-
-
-#ifdef INNER_ISLAND_BRIM_DEBUG_TO_SVG
- static int irun = 0;
- BoundingBox bbox_svg;
- bbox_svg.merge(get_extents(inner_islands_ex));
- {
- std::stringstream stri;
- stri << "inner_island_and_brim_area_" << irun << ".svg";
- SVG svg(stri.str(), bbox_svg);
- svg.draw(to_polylines(inner_islands_ex), "blue");
- svg.Close();
- }
- ++irun;
-#endif
-
- Flow flow = print.brim_flow();
- ExPolygons NoBrim = inner_brim_area(print, top_level_objects_with_brim,
- float(flow.scaled_spacing()), brimAreaMap, supportBrimAreaMap, objPrintVec);
-
- ExPolygons inner_islands_ex;
- std::map innerBrimAreaMap;
- std::map innerSupportBrimAreaMap;
- /*make_inner_island_brim(print, top_level_objects_with_brim, innerBrimAreaMap, innerSupportBrimAreaMap,
- inner_islands_ex, NoBrim, objPrintVec);*/
-
- //BBS: brim of hole must not overlap with inner island and inner island brim
- if (!inner_islands_ex.empty()) {
- if (brimAreaMap.size() > 0) {
- for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
- if (!iter->second.empty()) {
- iter->second = diff_ex(iter->second, inner_islands_ex);
- };
- }
- }
- if (supportBrimAreaMap.size() > 0) {
- for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
- if (!iter->second.empty()) {
- iter->second = diff_ex(iter->second, inner_islands_ex);
- };
- }
- }
- for (const PrintObject* object : print.objects()) {
- if (innerBrimAreaMap.find(object->id()) != innerBrimAreaMap.end()) {
- append(brimAreaMap[object->id()], innerBrimAreaMap[object->id()]);
- }
- if (innerSupportBrimAreaMap.find(object->id()) != innerSupportBrimAreaMap.end()) {
- append(supportBrimAreaMap[object->id()], innerSupportBrimAreaMap[object->id()]);
- }
- }
- }
-}
-
-
//BBS: generate out brim by offseting ExPolygons 'islands_area_ex'
-Polygons tryExPolygonOffset(const ExPolygons islandAreaEx, const Print& print)
+Polygons tryExPolygonOffset(const ExPolygons& islandAreaEx, const Print& print)
{
const auto scaled_resolution = scaled(print.config().resolution.value);
Polygons loops;
@@ -1718,8 +881,6 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
std::vector> &objPrintVec,
std::vector& printExtruders)
{
-
- double brim_width_max = 0;
std::map brim_width_map;
std::map brimAreaMap;
std::map supportBrimAreaMap;
@@ -1732,7 +893,10 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
for (const ObjectID printObjID : print.print_object_ids()) {
BoundingBox bbx;
PrintObject* object = const_cast(print.get_object(printObjID));
- for (const ExPolygon& ex_poly : object->layers().front()->lslices)
+ //ORCA: Use EFC-compensated outline for brim bounding box when enabled.
+ const ExPolygons brim_slices = use_brim_efc_outline(*object) ?
+ get_print_object_bottom_layer_expolygons(*object) : object->layers().front()->lslices;
+ for (const ExPolygon& ex_poly : brim_slices)
for (const PrintInstance& instance : object->instances()) {
auto ex_poly_translated = ex_poly;
ex_poly_translated.translate(instance.shift_without_plate_offset());
@@ -1774,9 +938,6 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
};
}
-
- size_t num_loops = size_t(floor(brim_width_max / flow.spacing()));
- BOOST_LOG_TRIVIAL(debug) << "brim_width_max, num_loops: " << brim_width_max << ", " << num_loops;
}
} // namespace Slic3r
diff --git a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
index 2e6f7efd9d..a9b5099383 100644
--- a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
+++ b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
@@ -162,8 +162,8 @@ void fuzzy_extrusion_line(Arachne::ExtrusionJunctions& ext_lines, coordf_t slice
}
if (ext_lines.back().p == ext_lines.front().p) { // Connect endpoints.
- out.front().p = out.back().p;
- out.front().w = out.back().w;
+ out.back().p = out.front().p;
+ out.back().w = out.front().w;
}
if (out.size() >= 3)
diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp
index c585329079..eff83efe3e 100644
--- a/src/libslic3r/Fill/FillBase.cpp
+++ b/src/libslic3r/Fill/FillBase.cpp
@@ -1707,6 +1707,12 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vectorcontour_idx];
+
+ // Orca: If multiline infill is requested, skip connections that are too short.
+ if (params.multiline > 1 && arc.arc_length < scale_(spacing) * params.multiline) {
+ continue;
+ }
+
const std::vector &contour_params = graph.boundary_params[cp1->contour_idx];
if (polyline_idx1 != polyline_idx2) {
Polyline &polyline1 = infill_ordered[polyline_idx1];
diff --git a/src/libslic3r/FlushVolCalc.cpp b/src/libslic3r/FlushVolCalc.cpp
index 675732d767..9bdbc1737d 100644
--- a/src/libslic3r/FlushVolCalc.cpp
+++ b/src/libslic3r/FlushVolCalc.cpp
@@ -10,7 +10,8 @@ namespace Slic3r {
const int g_min_flush_volume_from_support = 700;
const int g_flush_volume_to_support = 230;
-const int g_max_flush_volume = 900;
+const int g_max_flush_volume = 20000; //Orca: increase limit to 20k vs 900 in upstream BBS code.
+ // Retain a clamp to guard against extreme values entered in the UI
static float to_radians(float degree)
{
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 707dadd9f9..0e07e3fdb8 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -3084,10 +3084,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_sorted_layer_filaments.emplace_back(lt.extruders);
}
- // Orca: finish tracking power lost recovery
+ // Orca: disable power loss recovery if it was enabled earlier
{
- if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == true) {
- file.write(m_writer.enable_power_loss_recovery(false));
+ const auto plr_mode = print.config().enable_power_loss_recovery.value;
+ if (m_second_layer_things_done && plr_mode == PowerLossRecoveryMode::Enable) {
+ file.write(m_writer.enable_power_loss_recovery(PowerLossRecoveryMode::Disable));
}
}
++ finished_objects;
@@ -3165,9 +3166,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_sorted_layer_filaments.emplace_back(lt.extruders);
}
- // Orca: finish tracking power lost recovery
- if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == true) {
- file.write(m_writer.enable_power_loss_recovery(false));
+ // Orca: disable power loss recovery
+ if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == PowerLossRecoveryMode::Enable) {
+ file.write(m_writer.enable_power_loss_recovery(PowerLossRecoveryMode::Disable));
}
if (m_wipe_tower)
// Purge the extruder, pull out the active filament.
@@ -4381,10 +4382,9 @@ LayerResult GCode::process_layer(
}
if (!first_layer && !m_second_layer_things_done) {
- // Orca: start tracking power lost recovery
- if (print.config().enable_power_loss_recovery.value == true) {
- gcode += m_writer.enable_power_loss_recovery(true);
- }
+ // Orca: set power loss recovery
+ const auto plr_mode = print.config().enable_power_loss_recovery.value;
+ gcode += m_writer.enable_power_loss_recovery(plr_mode);
if (print.is_BBL_printer()) {
// BBS: open first layer inspection at second layer
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 2bf29aa002..30c48df054 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -97,7 +97,8 @@ public:
m_enable_timelapse_print(print_config.timelapse_type.value == TimelapseType::tlSmooth),
m_enable_wrapping_detection(print_config.enable_wrapping_detection && (print_config.wrapping_exclude_area.values.size() > 2) && (slice_used_filaments.size() <= 1)),
m_is_first_print(true),
- m_print_config(&print_config)
+ m_print_config(&print_config),
+ m_last_wipe_tower_print_z(print_config.z_offset.value)
{
// initialize with the extruder offset of master extruder id
m_extruder_offsets.resize(print_config.filament_map.size(), print_config.extruder_offset.get_at(print_config.master_extruder_id.value - 1));
@@ -143,7 +144,7 @@ private:
// Current layer index.
int m_layer_idx;
int m_tool_change_idx;
- double m_last_wipe_tower_print_z = 0.f;
+ double m_last_wipe_tower_print_z;
// BBS
Vec3d m_plate_origin;
diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index 9f7687d2c6..bd413d3782 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -1846,7 +1846,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
// sanity check
if(m_preheat_steps < 1)
m_preheat_steps = 1;
- m_result.backtrace_enabled = m_preheat_time > 0 && (m_is_XL_printer || (!m_single_extruder_multi_material && filament_count > 1));
+ m_result.backtrace_enabled = config.ooze_prevention && m_preheat_time > 0 && (m_is_XL_printer || (!m_single_extruder_multi_material && filament_count > 1));
assert(config.nozzle_volume.size() == config.nozzle_diameter.size());
m_nozzle_volume.resize(config.nozzle_volume.size());
diff --git a/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp b/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp
index e472b20794..20377cfe8d 100644
--- a/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp
+++ b/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.cpp
@@ -15,7 +15,6 @@
#include "../PrintConfig.hpp"
#include "SmallAreaInfillFlowCompensator.hpp"
-#include "spline/spline.h"
#include
namespace Slic3r {
@@ -47,37 +46,43 @@ SmallAreaInfillFlowCompensator::SmallAreaInfillFlowCompensator(const Slic3r::GCo
}
} catch (...) {
std::stringstream ss;
- ss << "Error parsing data point in small area infill compensation model:" << line << std::endl;
+ ss << "Small Area Flow Compensation: Error parsing data point in small area infill compensation model:" << line << std::endl;
throw Slic3r::InvalidArgument(ss.str());
}
}
}
- for (int i = 0; i < eLengths.size(); i++) {
+ for (size_t i = 0; i < eLengths.size(); i++) {
if (i == 0) {
if (!nearly_equal(eLengths[i], 0.0)) {
- throw Slic3r::InvalidArgument("First extrusion length for small area infill compensation model must be 0");
+ throw Slic3r::InvalidArgument("Small Area Flow Compensation: First extrusion length for small area infill compensation model must be 0");
}
} else {
if (nearly_equal(eLengths[i], 0.0)) {
- throw Slic3r::InvalidArgument("Only the first extrusion length for small area infill compensation model can be 0");
+ throw Slic3r::InvalidArgument("Small Area Flow Compensation: Only the first extrusion length for small area infill compensation model can be 0");
}
if (eLengths[i] <= eLengths[i - 1]) {
- throw Slic3r::InvalidArgument("Extrusion lengths for subsequent points must be increasing");
+ throw Slic3r::InvalidArgument("Small Area Flow Compensation: Extrusion lengths for subsequent points must be increasing");
}
}
}
- if (!flowComps.empty() && !nearly_equal(flowComps.back(), 1.0)) {
- throw Slic3r::InvalidArgument("Final compensation factor for small area infill flow compensation model must be 1.0");
+ for (size_t i = 1; i < flowComps.size(); ++i) {
+ if (flowComps[i] <= flowComps[i - 1]) {
+ throw Slic3r::InvalidArgument("Small Area Flow Compensation: Flow compensation factors must strictly increase with extrusion length");
+ }
}
- flowModel = std::make_unique();
- flowModel->set_points(eLengths, flowComps);
+ if (!flowComps.empty() && !nearly_equal(flowComps.back(), 1.0)) {
+ throw Slic3r::InvalidArgument("Small Area Flow Compensation: Final compensation factor for small area infill flow compensation model must be 1.0");
+ }
+
+ flowModel = std::make_unique(eLengths, flowComps);
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "Error parsing small area infill compensation model: " << e.what();
+ throw;
}
}
@@ -92,7 +97,7 @@ double SmallAreaInfillFlowCompensator::flow_comp_model(const double line_length)
return 1.0;
}
- return (*flowModel)(line_length);
+ return flowModel->interpolate(line_length);
}
double SmallAreaInfillFlowCompensator::modify_flow(const double line_length, const double dE, const ExtrusionRole role)
diff --git a/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.hpp b/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.hpp
index 1bfa5149f7..de1df98170 100644
--- a/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.hpp
+++ b/src/libslic3r/GCode/SmallAreaInfillFlowCompensator.hpp
@@ -4,12 +4,9 @@
#include "../libslic3r.h"
#include "../PrintConfig.hpp"
#include "../ExtrusionEntity.hpp"
+#include "PchipInterpolatorHelper.hpp"
#include
-namespace tk {
-class spline;
-} // namespace tk
-
namespace Slic3r {
class SmallAreaInfillFlowCompensator
@@ -26,8 +23,7 @@ private:
std::vector eLengths;
std::vector flowComps;
- // TODO: Cubic Spline
- std::unique_ptr flowModel;
+ std::unique_ptr flowModel;
double flow_comp_model(const double line_length);
diff --git a/src/libslic3r/GCode/WipeTower2.cpp b/src/libslic3r/GCode/WipeTower2.cpp
index cf5a68b436..19e98e4a09 100644
--- a/src/libslic3r/GCode/WipeTower2.cpp
+++ b/src/libslic3r/GCode/WipeTower2.cpp
@@ -1215,6 +1215,10 @@ WipeTower::ToolChangeResult WipeTower2::construct_tcr(WipeTowerWriter2& writer,
result.extrusions = std::move(writer.extrusions());
result.wipe_path = std::move(writer.wipe_path());
result.is_finish_first = is_finish;
+ // ORCA: Always initialize the tool_change_start_pos with a valid position
+ // to avoid undefined variable travel on X in Gcode.cpp function std::string WipeTowerIntegration::post_process_wipe_tower_moves
+ result.tool_change_start_pos = result.start_pos; // always valid fallback
+
return result;
}
@@ -2032,7 +2036,11 @@ WipeTower::ToolChangeResult WipeTower2::finish_layer()
// brim (first layer only)
if (first_layer) {
writer.append("; WIPE_TOWER_BRIM_START\n");
- size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing;
+ float brim_width = m_wipe_tower_brim_width;
+ if (brim_width < 0.f)
+ brim_width = WipeTower::get_auto_brim_by_height(m_wipe_tower_height);
+
+ size_t loops_num = (brim_width + spacing / 2.f) / spacing;
for (size_t i = 0; i < loops_num; ++ i) {
poly = offset(poly, scale_(spacing)).front();
diff --git a/src/libslic3r/GCode/WipeTower2.hpp b/src/libslic3r/GCode/WipeTower2.hpp
index 3dbc066634..6242b634a8 100644
--- a/src/libslic3r/GCode/WipeTower2.hpp
+++ b/src/libslic3r/GCode/WipeTower2.hpp
@@ -58,10 +58,18 @@ public:
std::vector> get_z_and_depth_pairs() const;
float get_brim_width() const { return m_wipe_tower_brim_width_real; }
float get_wipe_tower_height() const { return m_wipe_tower_height; }
-
-
-
-
+ // ORCA: Match WipeTower API used by Print skirt/brim planning.
+ // Returned bounding box is in WIPE-TOWER-LOCAL coordinates (before placement on the bed).
+ // Include brim and y-shift to match what WT gcode actually prints.
+ BoundingBoxf get_bbx() const{
+ const float brim = m_wipe_tower_brim_width_real;
+ const Vec2d min(-brim, -brim + double(m_y_shift));
+ const Vec2d max(double(m_wipe_tower_width) + brim, double(m_wipe_tower_depth) + brim + double(m_y_shift));
+ return BoundingBoxf(min, max);
+ }
+ // WT2 doesn't currently compute a rib-origin compensation like WipeTower (m_rib_offset),
+ // so expose a zero offset for consistency purposes (to maintain API parity).
+ Vec2f get_rib_offset() const { return Vec2f::Zero(); }
// Switch to a next layer.
void set_layer(
diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp
index f3d218750b..1008e5eab1 100644
--- a/src/libslic3r/GCodeWriter.cpp
+++ b/src/libslic3r/GCodeWriter.cpp
@@ -444,23 +444,28 @@ std::string GCodeWriter::reset_e(bool force)
}
}
-std::string GCodeWriter::enable_power_loss_recovery(bool enable)
+std::string GCodeWriter::enable_power_loss_recovery(PowerLossRecoveryMode mode)
{
std::ostringstream gcode;
-
+
+ if (mode == PowerLossRecoveryMode::PrinterConfiguration)
+ return std::string();
+
+ const bool enable = mode == PowerLossRecoveryMode::Enable;
+
if (m_is_bbl_printers) {
- gcode << "; start tracking Power Loss Recovery https://wiki.bambulab.com/en/knowledge-sharing/power-loss-recovery\n";
- gcode << "M1003 S" << (enable ? "1" : "0") << "\n";
+ gcode << "M1003 S" << (enable ? "1" : "0");
}
else if (FLAVOR_IS(gcfMarlinFirmware)) {
- gcode << "; start tracking Power-loss Recovery https://marlinfw.org/docs/gcode/M413.html\n";
- gcode << "M413 S" << (enable ? "1" : "0") << "\n";
+ gcode << "M413 S" << (enable ? "1" : "0");
+ } else {
+ return std::string();
}
-
+ if (GCodeWriter::full_gcode_comment) gcode << " ; set Power-loss Recovery";
+ gcode << "\n";
return gcode.str();
}
-
std::string GCodeWriter::update_progress(unsigned int num, unsigned int tot, bool allow_100) const
{
if (FLAVOR_IS_NOT(gcfMakerWare) && FLAVOR_IS_NOT(gcfSailfish))
diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp
index 32e737164d..dbc64694e2 100644
--- a/src/libslic3r/GCodeWriter.hpp
+++ b/src/libslic3r/GCodeWriter.hpp
@@ -61,7 +61,7 @@ public:
std::string set_input_shaping(char axis, float damp, float freq, std::string type) const;
std::string reset_e(bool force = false);
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
- std::string enable_power_loss_recovery(bool enable);
+ std::string enable_power_loss_recovery(PowerLossRecoveryMode mode);
// return false if this extruder was already selected
bool need_toolchange(unsigned int filament_id) const;
std::string set_extruder(unsigned int filament_id);
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 3ca75d28f3..4e78b31b46 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -904,7 +904,7 @@ static std::vector s_Preset_print_options {
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed",
"bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
"outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_height","single_loop_draft_shield", "draft_shield",
- "brim_width", "brim_object_gap", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
+ "brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
"support_base_pattern", "support_base_pattern_spacing", "support_expansion", "support_style",
// BBS
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 330b489141..7a0a6dd867 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -3333,6 +3333,8 @@ void Print::_make_wipe_tower()
m_wipe_tower_data.z_and_depth_pairs = wipe_tower.get_z_and_depth_pairs();
m_wipe_tower_data.brim_width = wipe_tower.get_brim_width();
m_wipe_tower_data.height = wipe_tower.get_wipe_tower_height();
+ m_wipe_tower_data.bbx = wipe_tower.get_bbx();
+ m_wipe_tower_data.rib_offset = wipe_tower.get_rib_offset();
// Unload the current filament over the purge tower.
coordf_t layer_height = m_objects.front()->config().layer_height.value;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 37fc895411..7549eb821d 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -161,6 +161,14 @@ static t_config_enum_values s_keys_map_BedTempFormula {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(BedTempFormula)
+// Orca
+static t_config_enum_values s_keys_map_PowerLossRecoveryMode {
+ { "printer_configuration", int(PowerLossRecoveryMode::PrinterConfiguration) },
+ { "enable", int(PowerLossRecoveryMode::Enable) },
+ { "disable", int(PowerLossRecoveryMode::Disable) }
+};
+CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PowerLossRecoveryMode)
+
static t_config_enum_values s_keys_map_FuzzySkinType {
{ "none", int(FuzzySkinType::None) },
{ "external", int(FuzzySkinType::External) },
@@ -1562,6 +1570,16 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.));
+ def = this->add("brim_use_efc_outline", coBool);
+ def->label = L("Brim follows compensated outline");
+ def->category = L("Support");
+ def->tooltip = L("When enabled, the brim is aligned with the first-layer perimeter geometry after Elephant Foot Compensation is applied.\n"
+ "This option is intended for cases where Elephant Foot Compensation significantly alters the first-layer footprint.\n"
+ "\n"
+ "If your current setup already works well, enabling it may be unnecessary and can cause the brim to fuse with upper layers." );
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionBool(false));
+
def = this->add("brim_ears", coBool);
def->label = L("Brim ears");
def->category = L("Support");
@@ -3366,11 +3384,18 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionBool(false));
// Orca
- def = this->add("enable_power_loss_recovery", coBool);
- def->label = L("Turn on Power Loss Recovery");
- def->tooltip = L("Enable this to insert power loss recovery commands in generated G-code.(Only for Bambu Lab printers and Marlin firmware based printers)");
+ def = this->add("enable_power_loss_recovery", coEnum);
+ def->label = L("Power Loss Recovery");
+ def->tooltip = L("Choose how to control power loss recovery. When set to Printer configuration, the slicer will not emit power loss recovery G-code and will leave the printer's configuration unchanged. Applicable to Bambu Lab or Marlin 2 firmware based printers.");
def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionBool(false));
+ def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
+ def->enum_values.push_back("printer_configuration");
+ def->enum_values.push_back("enable");
+ def->enum_values.push_back("disable");
+ def->enum_labels.push_back(L("Printer configuration"));
+ def->enum_labels.push_back(L("Enable"));
+ def->enum_labels.push_back(L("Disable"));
+ def->set_default_value(new ConfigOptionEnum(PowerLossRecoveryMode::PrinterConfiguration));
//BBS
// def = this->add("spaghetti_detector", coBool);
@@ -7432,6 +7457,13 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
else if (opt_key == "extruder_type") {
ReplaceString(value, "DirectDrive", "Direct Drive");
}
+ else if (opt_key == "enable_power_loss_recovery") {
+ if (value == "1" || boost::iequals(value, "true")) {
+ value = "enable";
+ } else if (value == "0" || boost::iequals(value, "false")) {
+ value = "disable";
+ }
+ }
else if(opt_key == "ensure_vertical_shell_thickness") {
if(value == "1") {
value = "ensure_all";
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 3e34a8362b..998764f292 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -102,6 +102,13 @@ enum class BedTempFormula {
count,
};
+// Orca
+enum class PowerLossRecoveryMode {
+ PrinterConfiguration,
+ Enable,
+ Disable,
+};
+
// BBS
enum class WallSequence {
InnerOuter,
@@ -507,6 +514,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WipeTowerWallType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType)
+CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PowerLossRecoveryMode)
#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS
@@ -874,6 +882,7 @@ PRINT_CONFIG_CLASS_DEFINE(
PrintObjectConfig,
((ConfigOptionFloat, brim_object_gap))
+ ((ConfigOptionBool, brim_use_efc_outline))
((ConfigOptionEnum, brim_type))
((ConfigOptionFloat, brim_width))
((ConfigOptionFloat, brim_ears_detection_length))
@@ -1271,7 +1280,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionIntsNullable, filament_flush_temp))
// BBS
((ConfigOptionBool, scan_first_layer))
- ((ConfigOptionBool, enable_power_loss_recovery))
+ ((ConfigOptionEnum, enable_power_loss_recovery))
((ConfigOptionBool, enable_wrapping_detection))
((ConfigOptionInt, wrapping_detection_layers))
((ConfigOptionPoints, wrapping_exclude_area))
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 7cc98209cf..4b4237dca1 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -1006,6 +1006,7 @@ bool PrintObject::invalidate_state_by_config_options(
for (const t_config_option_key &opt_key : opt_keys) {
if ( opt_key == "brim_width"
|| opt_key == "brim_object_gap"
+ || opt_key == "brim_use_efc_outline"
|| opt_key == "brim_type"
|| opt_key == "brim_ears_max_angle"
|| opt_key == "brim_ears_detection_length"
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index ca4f9c4123..e6f28b68fe 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -456,6 +456,8 @@ set(SLIC3R_GUI_SOURCES
GUI/UnsavedChangesDialog.hpp
GUI/UpdateDialogs.cpp
GUI/UpdateDialogs.hpp
+ GUI/NetworkPluginDialog.cpp
+ GUI/NetworkPluginDialog.hpp
GUI/UpgradePanel.cpp
GUI/UpgradePanel.hpp
GUI/UserManager.cpp
@@ -492,6 +494,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Widgets/ErrorMsgStaticText.hpp
GUI/Widgets/FanControl.cpp
GUI/Widgets/FanControl.hpp
+ GUI/Widgets/HyperLink.cpp
+ GUI/Widgets/HyperLink.hpp
GUI/Widgets/ImageSwitchButton.cpp
GUI/Widgets/ImageSwitchButton.hpp
GUI/Widgets/Label.cpp
@@ -703,7 +707,13 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES})
encoding_check(libslic3r_gui)
-target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
+if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ set(_opengl_link_lib "")
+else()
+ set(_opengl_link_lib OpenGL::GL)
+endif()
+
+target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW ${_opengl_link_lib} hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
if (MSVC)
target_link_libraries(libslic3r_gui Setupapi.lib)
@@ -721,7 +731,11 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
${CURL_LIBRARIES}
)
elseif (APPLE)
- target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY} "-framework Security")
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
+ target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY} "-framework Security" "-framework OpenGL")
+ else()
+ target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY} "-framework Security")
+ endif()
endif()
if (SLIC3R_STATIC)
diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp
index a649f6b833..19a32c2d21 100644
--- a/src/slic3r/GUI/AMSMaterialsSetting.cpp
+++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp
@@ -298,11 +298,7 @@ void AMSMaterialsSetting::create_panel_kn(wxWindow* parent)
if (language.find("zh") == 0)
region = "zh";
wxString link_url = wxString::Format("https://wiki.bambulab.com/%s/software/bambu-studio/calibration_pa", region);
- m_wiki_ctrl = new wxHyperlinkCtrl(parent, wxID_ANY, "Wiki", link_url);
- m_wiki_ctrl->SetNormalColour(*wxBLUE);
- m_wiki_ctrl->SetHoverColour(wxColour(0, 0, 200));
- m_wiki_ctrl->SetVisitedColour(*wxBLUE);
- m_wiki_ctrl->SetFont(Label::Head_14);
+ m_wiki_ctrl = new HyperLink(parent, "Wiki Guide", link_url);
cali_title_sizer->Add(m_ratio_text, 0, wxALIGN_CENTER_VERTICAL);
cali_title_sizer->Add(m_wiki_ctrl, 0, wxALIGN_CENTER_VERTICAL);
diff --git a/src/slic3r/GUI/AMSMaterialsSetting.hpp b/src/slic3r/GUI/AMSMaterialsSetting.hpp
index c678ec0717..84688896e6 100644
--- a/src/slic3r/GUI/AMSMaterialsSetting.hpp
+++ b/src/slic3r/GUI/AMSMaterialsSetting.hpp
@@ -14,8 +14,8 @@
#include "Widgets/CheckBox.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/TextInput.hpp"
+#include "Widgets/HyperLink.hpp"
#include "slic3r/Utils/CalibUtils.hpp"
-#include
#define AMS_MATERIALS_SETTING_DEF_COLOUR wxColour(255, 255, 255)
#define AMS_MATERIALS_SETTING_GREY900 wxColour(38, 46, 48)
@@ -174,7 +174,7 @@ protected:
wxPanel * m_panel_kn;
wxStaticText* m_ratio_text;
- wxHyperlinkCtrl * m_wiki_ctrl;
+ HyperLink * m_wiki_ctrl;
wxStaticText* m_k_param;
TextInput* m_input_k_val;
wxStaticText* m_n_param;
diff --git a/src/slic3r/GUI/BindDialog.cpp b/src/slic3r/GUI/BindDialog.cpp
index 7610fbe820..3847f8f2f1 100644
--- a/src/slic3r/GUI/BindDialog.cpp
+++ b/src/slic3r/GUI/BindDialog.cpp
@@ -98,18 +98,8 @@ PingCodeBindDialog::PingCodeBindDialog(Plater* plater /*= nullptr*/)
m_status_text->Wrap(FromDIP(440));
m_status_text->SetForegroundColour(wxColour(38, 46, 48));
- m_link_show_ping_code_wiki = new wxStaticText(request_bind_panel, wxID_ANY, _L("Can't find Pin Code?"));
- m_link_show_ping_code_wiki->SetFont(Label::Body_14);
- m_link_show_ping_code_wiki->SetBackgroundColour(*wxWHITE);
- m_link_show_ping_code_wiki->SetForegroundColour(wxColour(31, 142, 234));
-
- m_link_show_ping_code_wiki->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
- m_link_show_ping_code_wiki->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
-
- m_link_show_ping_code_wiki->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
- m_ping_code_wiki = "https://wiki.bambulab.com/en/bambu-studio/manual/pin-code";
- wxLaunchDefaultBrowser(m_ping_code_wiki);
- });
+ // ORCA standardized HyperLink
+ m_link_show_ping_code_wiki = new HyperLink(request_bind_panel, _L("Can't find Pin Code?"), "https://wiki.bambulab.com/en/bambu-studio/manual/pin-code");
m_text_input_title = new wxStaticText(request_bind_panel, wxID_ANY, _L("Pin Code"));
m_text_input_title->SetFont(Label::Body_14);
@@ -453,11 +443,11 @@ PingCodeBindDialog::~PingCodeBindDialog() {
m_st_privacy_title->SetFont(Label::Body_13);
m_st_privacy_title->SetForegroundColour(wxColour(38, 46, 48));
- auto m_link_Terms_title = new Label(m_panel_agreement, _L("Terms and Conditions"));
+ // ORCA standardized HyperLink
+ auto m_link_Terms_title = new HyperLink(m_panel_agreement, _L("Terms and Conditions"));
m_link_Terms_title->SetFont(Label::Head_13);
m_link_Terms_title->SetMaxSize(wxSize(FromDIP(450), -1));
m_link_Terms_title->Wrap(FromDIP(450));
- m_link_Terms_title->SetForegroundColour(wxColour("#009688"));
m_link_Terms_title->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
wxString txt = _L("Thank you for purchasing a Bambu Lab device. Before using your Bambu Lab device, please read the terms and conditions. "
"By clicking to agree to use your Bambu Lab device, you agree to abide by the Privacy Policy and Terms of Use (collectively, the \"Terms\"). "
@@ -467,18 +457,16 @@ PingCodeBindDialog::~PingCodeBindDialog() {
confirm_dlg.CenterOnParent();
confirm_dlg.on_show();
});
- m_link_Terms_title->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
- m_link_Terms_title->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
auto m_st_and_title = new Label(m_panel_agreement, _L("and"));
m_st_and_title->SetFont(Label::Body_13);
m_st_and_title->SetForegroundColour(wxColour(38, 46, 48));
- auto m_link_privacy_title = new Label(m_panel_agreement, _L("Privacy Policy"));
+ // ORCA standardized HyperLink
+ auto m_link_privacy_title = new HyperLink(m_panel_agreement, _L("Privacy Policy"));
m_link_privacy_title->SetFont(Label::Head_13);
m_link_privacy_title->SetMaxSize(wxSize(FromDIP(450), -1));
m_link_privacy_title->Wrap(FromDIP(450));
- m_link_privacy_title->SetForegroundColour(wxColour("#009688"));
m_link_privacy_title->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
std::string url;
std::string country_code = Slic3r::GUI::wxGetApp().app_config->get_country_code();
@@ -491,8 +479,6 @@ PingCodeBindDialog::~PingCodeBindDialog() {
}
wxLaunchDefaultBrowser(url);
});
- m_link_privacy_title->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND);});
- m_link_privacy_title->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW);});
sizere_notice_agreement->Add(0, 0, 0, wxTOP, FromDIP(4));
sizer_privacy_agreement->Add(m_st_privacy_title, 0, wxALIGN_CENTER, 0);
@@ -514,13 +500,11 @@ PingCodeBindDialog::~PingCodeBindDialog() {
m_st_notice_title->SetFont(Label::Body_13);
m_st_notice_title->SetForegroundColour(wxColour(38, 46, 48));
- auto m_link_notice_title = new Label(m_panel_agreement, notice_link_title);
+ // ORCA standardized HyperLink
+ auto m_link_notice_title = new HyperLink(m_panel_agreement, notice_link_title);
m_link_notice_title->SetFont(Label::Head_13);
m_link_notice_title->SetMaxSize(wxSize(FromDIP(450), -1));
m_link_notice_title->Wrap(FromDIP(450));
- m_link_notice_title->SetForegroundColour(wxColour("#009688"));
- m_link_notice_title->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
- m_link_notice_title->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
m_link_notice_title->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
wxString txt = _L("In the 3D Printing community, we learn from each other's successes and failures to adjust "
"our own slicing parameters and settings. %s follows the same principle and uses machine "
@@ -580,13 +564,8 @@ PingCodeBindDialog::~PingCodeBindDialog() {
wxBoxSizer* m_sizer_bind_failed_info = new wxBoxSizer(wxVERTICAL);
m_sw_bind_failed_info->SetSizer( m_sizer_bind_failed_info );
- m_link_network_state = new wxHyperlinkCtrl(m_sw_bind_failed_info, wxID_ANY,_L("Check the status of current system services"),"");
- m_link_network_state->SetFont(::Label::Body_12);
- m_link_network_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); });
- m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND); });
- m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW); });
-
-
+ // ORCA standardized HyperLink
+ m_link_network_state = new HyperLink(m_sw_bind_failed_info, _L("Check the status of current system services"), wxGetApp().link_to_network_check());
wxBoxSizer* sizer_error_code = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_error_desc = new wxBoxSizer(wxHORIZONTAL);
diff --git a/src/slic3r/GUI/BindDialog.hpp b/src/slic3r/GUI/BindDialog.hpp
index a4ffd8fbff..b809bc523b 100644
--- a/src/slic3r/GUI/BindDialog.hpp
+++ b/src/slic3r/GUI/BindDialog.hpp
@@ -17,13 +17,13 @@
#include
#include
#include
-#include
#include "wxExtensions.hpp"
#include "Widgets/StepCtrl.hpp"
#include "Widgets/ProgressDialog.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/ProgressBar.hpp"
#include "Widgets/RoundedRectangle.hpp"
+#include "Widgets/HyperLink.hpp"
#include "Jobs/BindJob.hpp"
#include "BBLStatusBar.hpp"
#include "BBLStatusBarBind.hpp"
@@ -56,7 +56,7 @@ private:
Label* m_status_text;
wxStaticText* m_text_input_title;
- wxStaticText* m_link_show_ping_code_wiki;
+ HyperLink* m_link_show_ping_code_wiki; // ORCA
TextInput* m_text_input_single_code[PING_CODE_LENGTH];
Button* m_button_bind;
Button* m_button_cancel;
@@ -70,7 +70,7 @@ private:
Label* m_st_txt_error_code{ nullptr };
Label* m_st_txt_error_desc{ nullptr };
Label* m_st_txt_extra_info{ nullptr };
- wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ HyperLink* m_link_network_state{ nullptr };
wxString m_result_info;
wxString m_result_extra;
wxString m_ping_code_wiki;
@@ -114,7 +114,7 @@ private:
Label* m_st_txt_error_code{ nullptr };
Label* m_st_txt_error_desc{ nullptr };
Label* m_st_txt_extra_info{ nullptr };
- wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ HyperLink* m_link_network_state{ nullptr };
wxString m_result_info;
wxString m_result_extra;
bool m_show_error_info_state = true;
diff --git a/src/slic3r/GUI/CalibrationPanel.cpp b/src/slic3r/GUI/CalibrationPanel.cpp
index 055cbe905d..12162615aa 100644
--- a/src/slic3r/GUI/CalibrationPanel.cpp
+++ b/src/slic3r/GUI/CalibrationPanel.cpp
@@ -269,7 +269,7 @@ void SelectMObjectPopup::Popup(wxWindow* WXUNUSED(focus))
}
}
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxTimerEvent(*m_refresh_timer));
PopupWindow::Popup();
}
@@ -505,7 +505,7 @@ void CalibrationPanel::init_timer()
m_refresh_timer = new wxTimer();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(REFRESH_INTERVAL);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxCommandEvent(wxEVT_TIMER));
}
void CalibrationPanel::on_timer(wxTimerEvent& event) {
@@ -634,7 +634,7 @@ bool CalibrationPanel::Show(bool show) {
m_refresh_timer->Stop();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(REFRESH_INTERVAL);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxCommandEvent(wxEVT_TIMER));
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (dev) {
diff --git a/src/slic3r/GUI/CalibrationWizardPage.cpp b/src/slic3r/GUI/CalibrationWizardPage.cpp
index 3da543e79d..13e7023190 100644
--- a/src/slic3r/GUI/CalibrationWizardPage.cpp
+++ b/src/slic3r/GUI/CalibrationWizardPage.cpp
@@ -466,21 +466,12 @@ void CaliPageCaption::init_bitmaps() {
void CaliPageCaption::create_wiki(wxWindow* parent)
{
- m_wiki_text = new Label(parent, _L("Wiki"));
- m_wiki_text->SetFont(Label::Head_14);
- m_wiki_text->SetForegroundColour({ 0, 88, 220 });
- m_wiki_text->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) {
- e.Skip();
- SetCursor(wxCURSOR_HAND);
- });
- m_wiki_text->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
- e.Skip();
- SetCursor(wxCURSOR_ARROW);
- });
+ // ORCA standardized HyperLink
+ m_wiki_text = new HyperLink(parent, _L("Wiki Guide"));
m_wiki_text->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty())
wxLaunchDefaultBrowser(m_wiki_url);
- });
+ });
}
void CaliPageCaption::show_prev_btn(bool show)
diff --git a/src/slic3r/GUI/CalibrationWizardPage.hpp b/src/slic3r/GUI/CalibrationWizardPage.hpp
index d03979cd55..524b1a6029 100644
--- a/src/slic3r/GUI/CalibrationWizardPage.hpp
+++ b/src/slic3r/GUI/CalibrationWizardPage.hpp
@@ -7,6 +7,7 @@
#include "Widgets/TextInput.hpp"
#include "Widgets/AMSControl.hpp"
#include "Widgets/ProgressBar.hpp"
+#include "Widgets/HyperLink.hpp"
#include "wxExtensions.hpp"
#include "PresetComboBoxes.hpp"
@@ -140,7 +141,7 @@ private:
void init_bitmaps();
void create_wiki(wxWindow* parent);
- Label* m_wiki_text;
+ HyperLink* m_wiki_text; // ORCA
wxString m_wiki_url;
ScalableBitmap m_prev_bmp_normal;
ScalableBitmap m_prev_bmp_hover;
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index 6c5fa69534..90944e673e 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -705,6 +705,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool have_brim = (config->opt_enum("brim_type") != btNoBrim);
toggle_field("brim_object_gap", have_brim);
+ toggle_field("brim_use_efc_outline", have_brim);
bool have_brim_width = (config->opt_enum("brim_type") != btNoBrim) && config->opt_enum("brim_type") != btAutoBrim &&
config->opt_enum("brim_type") != btPainted;
toggle_field("brim_width", have_brim_width);
diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp
index 7eb3beda82..269cd6ed12 100644
--- a/src/slic3r/GUI/CreatePresetsDialog.cpp
+++ b/src/slic3r/GUI/CreatePresetsDialog.cpp
@@ -17,6 +17,7 @@
#include "Tab.hpp"
#include "MainFrame.hpp"
#include "libslic3r_version.h"
+#include "Widgets/HyperLink.hpp" // ORCA
#define NAME_OPTION_COMBOBOX_SIZE wxSize(FromDIP(200), FromDIP(24))
#define FILAMENT_PRESET_COMBOBOX_SIZE wxSize(FromDIP(300), FromDIP(24))
@@ -5027,8 +5028,8 @@ wxPanel *PresetTree::get_child_item(wxPanel *parent, std::shared_ptr pre
bool base_id_error = false;
if (preset->inherits() == "" && preset->base_id != "") base_id_error = true;
if (base_id_error) {
- std::string wiki_url = "https://wiki.bambulab.com/en/software/bambu-studio/custom-filament-issue";
- wxHyperlinkCtrl *m_download_hyperlink = new wxHyperlinkCtrl(panel, wxID_ANY, _L("[Delete Required]"), wiki_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
+ // ORCA standardized HyperLink
+ HyperLink *m_download_hyperlink = new HyperLink(panel, _L("[Delete Required]"), "https://wiki.bambulab.com/en/software/bambu-studio/custom-filament-issue");
m_download_hyperlink->SetFont(Label::Body_10);
sizer->Add(m_download_hyperlink, 0, wxEXPAND | wxALL, 5);
}
diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp
index d19f1aa0dd..5c32f42c2b 100644
--- a/src/slic3r/GUI/DeviceCore/DevManager.cpp
+++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp
@@ -90,6 +90,25 @@ namespace Slic3r
userMachineList.clear();
}
+ void DeviceManager::set_agent(NetworkAgent* agent)
+ {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": updating agent for "
+ << localMachineList.size() << " local and "
+ << userMachineList.size() << " user machines";
+ m_agent = agent;
+
+ std::lock_guard lock(listMutex);
+ for (auto& it : localMachineList) {
+ if (it.second) {
+ it.second->set_agent(agent);
+ }
+ }
+ for (auto& it : userMachineList) {
+ if (it.second) {
+ it.second->set_agent(agent);
+ }
+ }
+ }
void DeviceManager::EnableMultiMachine(bool enable)
{
diff --git a/src/slic3r/GUI/DeviceCore/DevManager.h b/src/slic3r/GUI/DeviceCore/DevManager.h
index fbc30c0050..5ecb77401d 100644
--- a/src/slic3r/GUI/DeviceCore/DevManager.h
+++ b/src/slic3r/GUI/DeviceCore/DevManager.h
@@ -40,7 +40,7 @@ public:
public:
NetworkAgent* get_agent() const { return m_agent; }
- void set_agent(NetworkAgent* agent) { m_agent = agent; }
+ void set_agent(NetworkAgent* agent);
void start_refresher();
void stop_refresher();
diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp
index 112b514ab3..f4362cc3f7 100644
--- a/src/slic3r/GUI/DeviceManager.hpp
+++ b/src/slic3r/GUI/DeviceManager.hpp
@@ -135,6 +135,8 @@ public:
MachineObject(DeviceManager* manager, NetworkAgent* agent, std::string name, std::string id, std::string ip);
~MachineObject();
+ void set_agent(NetworkAgent* agent) { m_agent = agent; }
+
public:
enum ActiveState {
NotActive,
diff --git a/src/slic3r/GUI/DownloadProgressDialog.cpp b/src/slic3r/GUI/DownloadProgressDialog.cpp
index 1c4f7a9bfb..7ded82037e 100644
--- a/src/slic3r/GUI/DownloadProgressDialog.cpp
+++ b/src/slic3r/GUI/DownloadProgressDialog.cpp
@@ -19,10 +19,13 @@
//#include "ConfigWizard.hpp"
#include "wxExtensions.hpp"
#include "slic3r/GUI/MainFrame.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
#include "GUI_App.hpp"
#include "Jobs/BoostThreadWorker.hpp"
#include "Jobs/PlaterWorker.hpp"
+#include "Widgets/HyperLink.hpp" // ORCA
+
#define DESIGN_INPUT_SIZE wxSize(FromDIP(100), -1)
namespace Slic3r {
@@ -72,7 +75,8 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
sizer_download_failed->Add(m_statictext_download_failed, 0, wxALIGN_CENTER | wxALL, 5);
- auto m_download_hyperlink = new wxHyperlinkCtrl(m_panel_download_failed, wxID_ANY, _L("click here to see more info"), download_failed_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
+ // ORCA standardized HyperLink
+ auto m_download_hyperlink = new HyperLink(m_panel_download_failed, _L("click here to see more info"), download_failed_url);
sizer_download_failed->Add(m_download_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
@@ -93,7 +97,8 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
sizer_install_failed->Add(m_statictext_install_failed, 0, wxALIGN_CENTER | wxALL, 5);
- auto m_install_hyperlink = new wxHyperlinkCtrl(m_panel_install_failed, wxID_ANY, _L("click here to see more info"), install_failed_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
+ // ORCA standardized HyperLink
+ auto m_install_hyperlink = new HyperLink(m_panel_install_failed, _L("click here to see more info"), install_failed_url);
sizer_install_failed->Add(m_install_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
@@ -203,6 +208,16 @@ void DownloadProgressDialog::update_release_note(std::string release_note, std::
std::unique_ptr DownloadProgressDialog::make_job() { return std::make_unique(); }
-void DownloadProgressDialog::on_finish() { wxGetApp().restart_networking(); }
+void DownloadProgressDialog::on_finish()
+{
+ if (wxGetApp().hot_reload_network_plugin()) {
+ return;
+ }
+
+ MessageDialog dlg(nullptr,
+ _L("The network plugin was installed but could not be loaded. Please restart the application."),
+ _L("Restart Required"), wxOK | wxICON_INFORMATION);
+ dlg.ShowModal();
+}
}} // namespace Slic3r::GUI
diff --git a/src/slic3r/GUI/FilamentGroupPopup.cpp b/src/slic3r/GUI/FilamentGroupPopup.cpp
index 89c9dbd8de..df78e69a80 100644
--- a/src/slic3r/GUI/FilamentGroupPopup.cpp
+++ b/src/slic3r/GUI/FilamentGroupPopup.cpp
@@ -147,15 +147,10 @@ FilamentGroupPopup::FilamentGroupPopup(wxWindow *parent) : PopupWindow(parent, w
{
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
- const std::string wiki_path = Slic3r::resources_dir() + "/wiki/filament_group_wiki_zh.html";
+ const std::string wiki_path = Slic3r::resources_dir() + "/wiki/filament_group_wiki_zh.html"; // NEEDFIX this link is broken
auto* wiki_sizer = new wxBoxSizer(wxHORIZONTAL);
- wiki_link = new wxStaticText(this, wxID_ANY, _L("Learn more"));
- wiki_link->SetBackgroundColour(BackGroundColor);
- wiki_link->SetForegroundColour(GreenColor);
- wiki_link->SetFont(Label::Body_12.Underlined());
- wiki_link->SetCursor(wxCursor(wxCURSOR_HAND));
- wiki_link->Bind(wxEVT_LEFT_DOWN, [wiki_path](wxMouseEvent &) { wxLaunchDefaultBrowser(wxString(wiki_path.c_str())); });
+ wiki_link = new HyperLink(this, _L("Wiki Guide"), wxString(wiki_path.c_str())); // ORCA
wiki_sizer->Add(wiki_link, 0, wxALIGN_CENTER | wxALL, FromDIP(3));
button_sizer->Add(wiki_sizer, 0, wxLEFT, horizontal_margin);
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 00d15ddadd..ce859e1a7b 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -6044,6 +6044,7 @@ static const float cameraProjection[16] = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.
void GLCanvas3D::_render_3d_navigator()
{
if (!wxGetApp().show_3d_navigator()) {
+ m_canvas_toolbar_pos[0] = 0;
return;
}
@@ -6090,7 +6091,7 @@ void GLCanvas3D::_render_3d_navigator()
}
const float size = 128 * sc;
- m_axis_button_pos[0] = size - 10;
+ m_canvas_toolbar_pos[0] = size;
const auto result = ImGuizmo::ViewManipulate(cameraView, cameraProjection, ImGuizmo::OPERATION::ROTATE, ImGuizmo::MODE::WORLD, nullptr,
camDistance, ImVec2(viewManipulateLeft, viewManipulateTop - size), ImVec2(size, size),
0x00101010);
@@ -6126,7 +6127,6 @@ void GLCanvas3D::_render_3d_navigator()
request_extra_frame();
}
- _render_camera_toolbar();
}
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
@@ -7989,6 +7989,8 @@ void GLCanvas3D::_render_overlays()
m_labels.render(sorted_instances);
_render_3d_navigator();
+
+ _render_canvas_toolbar();
}
void GLCanvas3D::_render_style_editor()
@@ -8627,47 +8629,169 @@ void GLCanvas3D::_render_return_toolbar() const
imgui.end();
}
-void GLCanvas3D::_render_camera_toolbar()
+void GLCanvas3D::_render_canvas_toolbar()
{
- float font_size = ImGui::GetFontSize();
- float sc = get_scale();
- ImVec2 button_icon_size = ImVec2(font_size * 2.5, font_size * 2.5);
+ ImGuiWrapper &imgui = *wxGetApp().imgui();
+ float sc = get_scale();
- ImGuiWrapper &imgui = *wxGetApp().imgui();
- float window_width = button_icon_size.x + imgui.scaled(2.0f);
- float window_height = button_icon_size.y + imgui.scaled(2.0f);
+ #ifdef WIN32
+ const int dpi = get_dpi_for_window(wxGetApp().GetTopWindow());
+ sc *= (float) dpi / (float) DPI_DEFAULT;
+ #endif // WIN32
- Size cnv_size = get_canvas_size();
- m_axis_button_pos[1] = cnv_size.get_height() - button_icon_size[1] - 20 * sc;
- imgui.set_next_window_pos(m_axis_button_pos[0], m_axis_button_pos[1], ImGuiCond_Always, 0, 0);
-#ifdef __WINDOWS__
- imgui.set_next_window_size(window_width, window_height, ImGuiCond_Always);
-#endif
+ ImVec2 btn_size = ImVec2(36.f, 36.f) * sc;
+ ImVec2 margin = ImVec2(m_canvas_toolbar_pos[0] > 0 ? 0.f : (10.f * sc), 10.f * sc);
+ ImVec2 spacing = ImVec2(6.f, 6.f) * sc;
+ ImVec2 padding = ImVec2(2.f, 2.f) * sc;
+ Vec2i32 pos = {
+ m_canvas_toolbar_pos[0] + margin.x,
+ get_canvas_size().get_height() - margin.y
+ };
+ bool zoom_btn = wxGetApp().show_canvas_zoom_button();
- imgui.begin(_L("Toggle Axis"), ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove |
+ imgui.set_next_window_pos(pos[0], pos[1], ImGuiCond_Always, 0, 1); // pivot bottom-left
+
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0 );
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , {0,0});
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing , {0,0});
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding , padding); // without padding images clipping
+
+ imgui.begin(_L("Canvas Toolbar"), ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse);//
- ImTextureID normal_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_DARK : GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE);
- ImTextureID hover_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_DARK_HOVER : GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_HOVER);
+ ImTextureID m_normal_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_MENU_DARK : GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_MENU);
+ ImTextureID m_hover_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_MENU_DARK_HOVER : GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_MENU_HOVER);
- ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0});
-
- if (ImGui::ImageButton3(normal_id, hover_id, button_icon_size, ImVec2(0, 0), ImVec2(1, 1), -1,
- ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1), ImVec2(10, 0))) {
- //select_view("plate");
-
- if (m_canvas_type == ECanvasType::CanvasView3D || m_canvas_type == ECanvasType::CanvasPreview) {
- toggle_world_axes_visibility(false);
+ if (ImGui::ImageButton3(m_normal_id, m_hover_id, btn_size)) {
+ if(!ImGui::IsPopupOpen("CanvasToolbarMenu")){
+ ImGui::SetNextWindowPos(ImVec2(pos[0] + padding.x, pos[1] - padding.y - (zoom_btn ? (btn_size.y + spacing.y) : 0.f)), ImGuiCond_Always, ImVec2(0, 1)); // pivot bottom-left
+ ImGui::OpenPopup("CanvasToolbarMenu");
}
+ }
+ if(zoom_btn){
+ ImGui::Dummy({ 0, spacing.y});
+
+ ImTextureID z_normal_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_ZOOM_DARK : GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_ZOOM);
+ ImTextureID z_hover_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_ZOOM_DARK_HOVER : GLGizmosManager::MENU_ICON_NAME::IC_CANVAS_ZOOM_HOVER);
+
+ if (ImGui::ImageButton3(z_normal_id, z_hover_id, btn_size)) {
+ select_view("plate");
+ if (m_selection.is_empty()) {
+ if (m_canvas_type == ECanvasType::CanvasAssembleView)
+ zoom_to_volumes();
+ else
+ zoom_to_bed();
+ } else {
+ zoom_to_selection();
+ }
+ } else if (ImGui::IsItemHovered()) {
+ auto tooltip = _L("Fit camera to scene or selected object.");
+ auto width = ImGui::CalcTextSize(tooltip.c_str()).x + imgui.scaled(2.0f);
+ imgui.tooltip(tooltip, width);
+ }
}
- if (ImGui::IsItemHovered()) {
- auto temp_tooltip = _L("Toggle Axis");
- auto width = ImGui::CalcTextSize(temp_tooltip.c_str()).x + imgui.scaled(2.0f);
- imgui.tooltip(temp_tooltip, width);
+
+ ImGui::PopStyleVar(4); // Window
+
+ ImGui::PushStyleColor(ImGuiCol_PopupBg , m_is_dark ? ImGuiWrapper::COL_TOOLBAR_BG_DARK : ImGuiWrapper::COL_TOOLBAR_BG);
+ ImGui::PushStyleColor(ImGuiCol_Separator , m_is_dark ? ImVec4(1, 1, 1, .20f) : ImVec4(0, 0, 0, .2f));
+ ImGui::PushStyleColor(ImGuiCol_Text , m_is_dark ? ImVec4(1, 1, 1, .88f) : ImVec4(50 / 255.f, 58 / 255.f, 61 / 255.f, 1.f));
+ ImGui::PushStyleColor(ImGuiCol_TextDisabled , m_is_dark ? ImVec4(1, 1, 1, .44f) : ImVec4(50 / 255.f, 58 / 255.f, 61 / 255.f, .5f));
+ ImGui::PushStyleColor(ImGuiCol_HeaderHovered , ImVec4(0, 0, 0, 0.f)); // bg color for menu item
+ ImGui::PushStyleColor(ImGuiCol_BorderActive , ImGuiWrapper::COL_ORCA);
+ ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.f );
+ ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding , 8.f * sc);
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f * sc);
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 2.f * sc);
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding , ImVec2(4.f, 10.f) * sc);
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing , ImVec2(0.f, 8.f ) * sc);
+
+ if (ImGui::BeginPopup("CanvasToolbarMenu")) {
+ ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
+
+ Plater* p = wxGetApp().plater();
+ AppConfig* cfg = wxGetApp().app_config;
+
+ auto create_menu_item = [this, sc](
+ const std::string& name,
+ bool enable,
+ bool condition,
+ const std::function& action
+ ) {
+ ImGui::Dummy({2.f * sc,0});
+ ImGui::SameLine();
+ if (ImGui::BBLMenuItem((" " + _u8L(name)).c_str(), nullptr, false, enable, ImGui::CalcTextSize(_u8L(name).c_str()).y))
+ action();
+ ImGui::SameLine(12.f * sc);
+ ImGui::TextColored(enable ? ImVec4(1,1,1,1) : ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled), "%s", into_u8(condition ? ImGui::VisibleIcon : ImGui::HiddenIcon).c_str());
+ };
+
+ create_menu_item( "3D Navigator",
+ m_canvas_type != ECanvasType::CanvasAssembleView, // not work on assembly
+ wxGetApp().show_3d_navigator(),
+ [this]{
+ wxGetApp().toggle_show_3d_navigator();
+ ImGui::CloseCurrentPopup(); // Close popup to show changes on UI
+ }
+ );
+
+ create_menu_item( "Zoom button",
+ true, // work on all
+ wxGetApp().show_canvas_zoom_button(),
+ [this]{
+ wxGetApp().toggle_canvas_zoom_button();
+ ImGui::CloseCurrentPopup(); // Close popup to show changes on UI
+ }
+ );
+
+ ImGui::Separator();
+
+ create_menu_item( "Overhangs",
+ m_canvas_type == ECanvasType::CanvasView3D, // work only on prepare
+ p->is_view3D_overhang_shown(),
+ [this, p]{p->show_view3D_overhang(!p->is_view3D_overhang_shown());}
+ );
+
+ create_menu_item( "Outline",
+ m_canvas_type != ECanvasType::CanvasPreview, // not work on preview
+ wxGetApp().show_outline(),
+ [this]{wxGetApp().toggle_show_outline();}
+ );
+
+ ImGui::Separator();
+
+ create_menu_item( "Perspective",
+ true, // work on all
+ cfg->get_bool("use_perspective_camera"),
+ [this, &cfg]{
+ cfg->set_bool("use_perspective_camera", !(cfg->get_bool("use_perspective_camera")));
+ wxGetApp().update_ui_from_settings();
+ }
+ );
+
+ ImGui::Separator();
+
+ create_menu_item( "Axes",
+ m_canvas_type != ECanvasType::CanvasAssembleView, // not work on assembly
+ m_show_world_axes,
+ [this]{toggle_world_axes_visibility(false);}
+ );
+
+ // will add an option for gridlines in here
+
+ create_menu_item( "Labels",
+ m_canvas_type == ECanvasType::CanvasView3D, // work only on prepare
+ p->are_view3D_labels_shown(),
+ [this, p]{p->show_view3D_labels(!p->are_view3D_labels_shown());}
+ );
+
+ ImGui::PopItemFlag();
+ ImGui::EndPopup();
}
- ImGui::PopStyleVar(2);
+
+ ImGui::PopStyleColor(6);
+ ImGui::PopStyleVar(6);
imgui.end();
}
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index aab67615d9..6931b305d6 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -543,7 +543,7 @@ private:
mutable IMToolbar m_sel_plate_toolbar;
mutable GLToolbar m_assemble_view_toolbar;
mutable IMReturnToolbar m_return_toolbar;
- mutable Vec2i32 m_axis_button_pos = {128, 5};
+ mutable Vec2i32 m_canvas_toolbar_pos = {140, 5};
mutable float m_sc{1};
mutable float m_paint_toolbar_width;
@@ -1246,7 +1246,7 @@ private:
void _render_imgui_select_plate_toolbar();
void _render_assemble_view_toolbar() const;
void _render_return_toolbar() const;
- void _render_camera_toolbar();
+ void _render_canvas_toolbar();
void _render_separator_toolbar_right() const;
void _render_separator_toolbar_left() const;
void _render_collapse_toolbar() const;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 27816e2b67..fda19112d4 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -98,6 +99,7 @@
#include "UnsavedChangesDialog.hpp"
#include "SavePresetDialog.hpp"
#include "PrintHostDialogs.hpp"
+#include "NetworkPluginDialog.hpp"
#include "DesktopIntegrationDialog.hpp"
#include "SendSystemInfoDialog.hpp"
#include "ParamsDialog.hpp"
@@ -959,15 +961,7 @@ void GUI_App::post_init()
m_show_gcode_window = app_config->get_bool("show_gcode_window");
if (m_networking_need_update) {
- //updating networking
- int ret = updating_bambu_networking();
- if (!ret) {
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__<<":networking plugin updated successfully";
- //restart_networking();
- }
- else {
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__<<":networking plugin updated failed";
- }
+ show_network_plugin_download_dialog(false);
}
// Start preset sync after project opened, otherwise we could have preset change during project opening which could cause crash
@@ -1177,12 +1171,20 @@ std::string GUI_App::get_plugin_url(std::string name, std::string country_code)
{
std::string url = get_http_url(country_code);
- std::string curr_version = NetworkAgent::use_legacy_network ? BAMBU_NETWORK_AGENT_VERSION_LEGACY : BAMBU_NETWORK_AGENT_VERSION;
+ std::string curr_version;
+ if (NetworkAgent::use_legacy_network) {
+ curr_version = BAMBU_NETWORK_AGENT_VERSION_LEGACY;
+ } else if (name == "plugins" && app_config) {
+ std::string user_version = app_config->get_network_plugin_version();
+ curr_version = user_version.empty() ? BBL::get_latest_network_version() : user_version;
+ } else {
+ curr_version = BBL::get_latest_network_version();
+ }
+
std::string using_version = curr_version.substr(0, 9) + "00";
if (name == "cameratools")
using_version = curr_version.substr(0, 6) + "00.00";
url += (boost::format("?slicer/%1%/cloud=%2%") % name % using_version).str();
- //url += (boost::format("?slicer/plugins/cloud=%1%") % "01.01.00.00").str();
return url;
}
@@ -1413,6 +1415,32 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP
return InstallStatusUnzipFailed;
}
+ boost::filesystem::path legacy_lib_path, legacy_lib_backup;
+ bool had_existing_legacy = false;
+ if (name == "plugins") {
+#if defined(_MSC_VER) || defined(_WIN32)
+ legacy_lib_path = plugin_folder / (std::string(BAMBU_NETWORK_LIBRARY) + ".dll");
+#elif defined(__WXMAC__)
+ legacy_lib_path = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + ".dylib");
+#else
+ legacy_lib_path = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + ".so");
+#endif
+ legacy_lib_backup = legacy_lib_path;
+ legacy_lib_backup += ".backup";
+
+ if (boost::filesystem::exists(legacy_lib_path)) {
+ had_existing_legacy = true;
+ boost::system::error_code ec;
+ boost::filesystem::rename(legacy_lib_path, legacy_lib_backup, ec);
+ if (ec) {
+ BOOST_LOG_TRIVIAL(warning) << "[install_plugin] failed to backup existing legacy library: " << ec.message();
+ had_existing_legacy = false;
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "[install_plugin] backed up existing legacy library";
+ }
+ }
+ }
+
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
mz_zip_archive_file_stat stat;
BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, got %2% files")%__LINE__ %num_entries;
@@ -1487,6 +1515,47 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP
}
close_zip_reader(&archive);
+
+ if (name == "plugins") {
+ std::string config_version = app_config->get_network_plugin_version();
+ if (config_version.empty()) {
+ config_version = BBL::get_latest_network_version();
+ BOOST_LOG_TRIVIAL(info) << "[install_plugin] config_version was empty, using latest: " << config_version;
+ app_config->set_network_plugin_version(config_version);
+ GUI::wxGetApp().CallAfter([this] {
+ if (app_config)
+ app_config->save();
+ });
+ }
+ if (!config_version.empty() && boost::filesystem::exists(legacy_lib_path)) {
+#if defined(_MSC_VER) || defined(_WIN32)
+ auto versioned_lib = plugin_folder / (std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".dll");
+#elif defined(__WXMAC__)
+ auto versioned_lib = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".dylib");
+#else
+ auto versioned_lib = plugin_folder / (std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_" + config_version + ".so");
+#endif
+ BOOST_LOG_TRIVIAL(info) << "[install_plugin] renaming newly extracted " << legacy_lib_path.string() << " to " << versioned_lib.string();
+ boost::system::error_code ec;
+ if (boost::filesystem::exists(versioned_lib)) {
+ boost::filesystem::remove(versioned_lib, ec);
+ }
+ boost::filesystem::rename(legacy_lib_path, versioned_lib, ec);
+ if (ec) {
+ BOOST_LOG_TRIVIAL(error) << "[install_plugin] failed to rename to versioned: " << ec.message();
+ }
+ }
+
+ if (had_existing_legacy && boost::filesystem::exists(legacy_lib_backup)) {
+ BOOST_LOG_TRIVIAL(info) << "[install_plugin] restoring backed up legacy library";
+ boost::system::error_code ec;
+ boost::filesystem::rename(legacy_lib_backup, legacy_lib_path, ec);
+ if (ec) {
+ BOOST_LOG_TRIVIAL(warning) << "[install_plugin] failed to restore legacy library backup: " << ec.message();
+ }
+ }
+ }
+
{
fs::path dir_path(plugin_folder);
if (fs::exists(dir_path) && fs::is_directory(dir_path)) {
@@ -1519,6 +1588,8 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP
}
}
}
+
+
if (pro_fn)
pro_fn(InstallStatusInstallCompleted, 100, cancel);
if (name == "plugins")
@@ -1572,6 +1643,247 @@ void GUI_App::restart_networking()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" exit, m_agent=%1%")%m_agent;
}
+// Network plugin hot reload timeout constants (in milliseconds)
+namespace {
+ constexpr int CALLBACK_DRAIN_TIMEOUT_MS = 200; // Time to drain pending CallAfter callbacks
+ constexpr int NETWORK_IDLE_TIMEOUT_MS = 500; // Max wait for network operations to complete
+ constexpr int FINAL_DRAIN_TIMEOUT_MS = 100; // Final event processing before destruction
+ constexpr int POLL_INTERVAL_MS = 50; // Polling interval for state checks
+ constexpr int MAX_YIELD_ITERATIONS = 20; // Maximum wxYield calls per drain cycle
+}
+
+// Process pending wx events with bounded iteration count
+void GUI_App::drain_pending_events(int timeout_ms)
+{
+ const auto deadline = std::chrono::steady_clock::now() +
+ std::chrono::milliseconds(timeout_ms);
+ int yield_count = 0;
+
+ while (std::chrono::steady_clock::now() < deadline) {
+ // Process pending events
+ if (wxTheApp) {
+ wxTheApp->ProcessPendingEvents();
+ }
+
+ // Bounded wxYield to prevent infinite loops
+ if (yield_count < MAX_YIELD_ITERATIONS) {
+ wxYield();
+ ++yield_count;
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
+ }
+}
+
+// Wait for network operations to complete with state verification
+bool GUI_App::wait_for_network_idle(int timeout_ms)
+{
+ const auto deadline = std::chrono::steady_clock::now() +
+ std::chrono::milliseconds(timeout_ms);
+
+ while (std::chrono::steady_clock::now() < deadline) {
+ if (!m_agent) {
+ return true; // Agent already gone
+ }
+
+ // Verify all operations completed
+ bool server_disconnected = !m_agent->is_server_connected();
+
+ if (server_disconnected) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": network is idle";
+ return true;
+ }
+
+ // Process events while waiting
+ if (wxTheApp) {
+ wxTheApp->ProcessPendingEvents();
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
+ }
+
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": timeout after " << timeout_ms
+ << "ms, server_connected=" << (m_agent ? m_agent->is_server_connected() : false);
+ return false;
+}
+
+bool GUI_App::hot_reload_network_plugin()
+{
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": starting hot reload";
+
+ wxBusyCursor busy;
+ wxBusyInfo info(_L("Reloading network plugin..."), mainframe);
+ wxYield();
+ wxWindowDisabler disabler;
+
+ if (mainframe) {
+ int current_tab = mainframe->m_tabpanel->GetSelection();
+ if (current_tab == MainFrame::TabPosition::tpMonitor) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": navigating away from Monitor tab before unload";
+ mainframe->m_tabpanel->SetSelection(MainFrame::TabPosition::tp3DEditor);
+ }
+ }
+
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": stopping sync thread before unload";
+ if (m_user_sync_token) {
+ m_user_sync_token.reset();
+ }
+ if (m_sync_update_thread.joinable()) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": waiting for sync thread to finish";
+ m_sync_update_thread.join();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": sync thread finished";
+ }
+
+ if (m_agent) {
+ // Phase 1: Clear all callbacks (stops new invocations)
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 1 - clearing callbacks";
+ m_agent->set_on_ssdp_msg_fn(nullptr);
+ m_agent->set_on_user_login_fn(nullptr);
+ m_agent->set_on_printer_connected_fn(nullptr);
+ m_agent->set_on_server_connected_fn(nullptr);
+ m_agent->set_on_http_error_fn(nullptr);
+ m_agent->set_on_subscribe_failure_fn(nullptr);
+ m_agent->set_on_message_fn(nullptr);
+ m_agent->set_on_user_message_fn(nullptr);
+ m_agent->set_on_local_connect_fn(nullptr);
+ m_agent->set_on_local_message_fn(nullptr);
+ m_agent->set_queue_on_main_fn(nullptr);
+
+ // Phase 2: Drain pending CallAfter callbacks (bounded)
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 2 - draining callbacks";
+ drain_pending_events(CALLBACK_DRAIN_TIMEOUT_MS);
+
+ // Phase 3: Stop operations and verify return values
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 3 - stopping operations";
+ bool discovery_stopped = m_agent->start_discovery(false, false);
+ int disconnect_result = m_agent->disconnect_printer();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": discovery_stopped=" << discovery_stopped
+ << ", disconnect_result=" << disconnect_result;
+
+ // Phase 4: Wait for idle with state verification
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 4 - waiting for idle";
+ bool became_idle = wait_for_network_idle(NETWORK_IDLE_TIMEOUT_MS);
+ if (!became_idle) {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": proceeding despite timeout";
+ }
+
+ // Phase 5: Final bounded drain before destruction
+ drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
+
+ // Phase 6: Destroy agent
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 6 - destroying agent";
+ delete m_agent;
+ m_agent = nullptr;
+ }
+
+ // Phase 7: Unload module
+ if (Slic3r::NetworkAgent::is_network_module_loaded()) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 7 - unloading module";
+ drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
+ int unload_result = Slic3r::NetworkAgent::unload_network_module();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unload_result=" << unload_result;
+ }
+
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": calling restart_networking";
+ restart_networking();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": restart_networking returned";
+
+ std::string loaded_version = Slic3r::NetworkAgent::get_version();
+ bool success = m_agent != nullptr && !loaded_version.empty() && loaded_version != "00.00.00.00";
+ bool user_logged_in = m_agent && m_agent->is_user_login();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": after restart_networking, is_user_login = " << user_logged_in
+ << ", m_agent = " << (m_agent ? "valid" : "null")
+ << ", version = " << loaded_version;
+
+ if (success && m_agent && m_device_manager) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": connecting to cloud server";
+ m_agent->connect_server();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": re-subscribing to cloud printers";
+ m_device_manager->add_user_subscribe();
+ }
+
+ if (mainframe && mainframe->m_monitor) {
+ mainframe->m_monitor->update_network_version_footer();
+ mainframe->m_monitor->set_default();
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": reset monitor panel";
+ }
+
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": hot reload " << (success ? "successful" : "failed");
+ return success;
+}
+
+std::string GUI_App::get_latest_network_version() const
+{
+ return BBL::get_latest_network_version();
+}
+
+bool GUI_App::has_network_update_available() const
+{
+ std::string current = Slic3r::NetworkAgent::get_version();
+ std::string latest = get_latest_network_version();
+
+ if (current.empty() || current == "00.00.00.00")
+ return false;
+
+ return current.substr(0, 8) != latest.substr(0, 8);
+}
+
+void GUI_App::show_network_plugin_download_dialog(bool is_update)
+{
+ auto load_error = Slic3r::NetworkAgent::get_load_error();
+
+ NetworkPluginDownloadDialog::Mode mode;
+ if (load_error.has_error) {
+ mode = NetworkPluginDownloadDialog::Mode::CorruptedPlugin;
+ } else if (is_update) {
+ mode = NetworkPluginDownloadDialog::Mode::UpdateAvailable;
+ } else {
+ mode = NetworkPluginDownloadDialog::Mode::MissingPlugin;
+ }
+
+ std::string current_version = Slic3r::NetworkAgent::get_version();
+
+ NetworkPluginDownloadDialog dlg(mainframe, mode, current_version,
+ load_error.message, load_error.technical_details);
+
+ int result = dlg.ShowModal();
+
+ switch (result) {
+ case NetworkPluginDownloadDialog::RESULT_DOWNLOAD:
+ {
+ std::string selected = dlg.get_selected_version();
+ app_config->set_network_plugin_version(selected);
+ app_config->save();
+
+ DownloadProgressDialog download_dlg(_L("Downloading Network Plugin"));
+ download_dlg.ShowModal();
+ }
+ break;
+
+ case NetworkPluginDownloadDialog::RESULT_REMIND_LATER:
+ app_config->set_remind_network_update_later(true);
+ app_config->save();
+ break;
+
+ case NetworkPluginDownloadDialog::RESULT_SKIP_VERSION:
+ {
+ std::string latest = get_latest_network_version();
+ app_config->add_skipped_network_version(latest);
+ app_config->save();
+ }
+ break;
+
+ case NetworkPluginDownloadDialog::RESULT_DONT_ASK:
+ app_config->set_network_update_prompt_disabled(true);
+ app_config->save();
+ break;
+
+ case NetworkPluginDownloadDialog::RESULT_SKIP:
+ default:
+ break;
+ }
+}
+
void GUI_App::remove_old_networking_plugins()
{
std::string data_dir_str = data_dir();
@@ -1601,8 +1913,20 @@ bool GUI_App::check_networking_version()
if (!network_ver.empty()) {
BOOST_LOG_TRIVIAL(info) << "get_network_agent_version=" << network_ver;
}
- std::string studio_ver = NetworkAgent::use_legacy_network ? BAMBU_NETWORK_AGENT_VERSION_LEGACY : BAMBU_NETWORK_AGENT_VERSION;
- if (network_ver.length() >= 8) {
+
+ std::string studio_ver;
+ if (NetworkAgent::use_legacy_network) {
+ studio_ver = BAMBU_NETWORK_AGENT_VERSION_LEGACY;
+ } else if (app_config) {
+ std::string user_version = app_config->get_network_plugin_version();
+ studio_ver = user_version.empty() ? BBL::get_latest_network_version() : user_version;
+ } else {
+ studio_ver = BBL::get_latest_network_version();
+ }
+
+ BOOST_LOG_TRIVIAL(info) << "check_networking_version: network_ver=" << network_ver << ", expected=" << studio_ver;
+
+ if (network_ver.length() >= 8 && studio_ver.length() >= 8) {
if (network_ver.substr(0,8) == studio_ver.substr(0,8)) {
m_networking_compatible = true;
return true;
@@ -2071,7 +2395,13 @@ void GUI_App::init_app_config()
}
// Change current dirtory of application
- [[maybe_unused]] auto unused_result = chdir(encode_path((Slic3r::data_dir() + "/log").c_str()).c_str());
+
+#ifdef _WIN32
+ [[maybe_unused]] auto unused_result = _chdir(encode_path((Slic3r::data_dir() + "/log").c_str()).c_str());
+#else
+ [[maybe_unused]] auto unused_result = chdir(encode_path((Slic3r::data_dir() + "/log").c_str()).c_str());
+#endif
+
} else {
m_datadir_redefined = true;
}
@@ -2668,8 +2998,11 @@ bool GUI_App::on_init_inner()
std::map extra_headers = get_extra_header();
Slic3r::Http::set_extra_headers(extra_headers);
- // Orca: select network plugin version
- NetworkAgent::use_legacy_network = app_config->get_bool("legacy_networking");
+ // Orca: select network plugin version based on configured version string
+ std::string configured_version = app_config->get_network_plugin_version();
+ NetworkAgent::use_legacy_network = (configured_version == BAMBU_NETWORK_AGENT_VERSION_LEGACY);
+ BOOST_LOG_TRIVIAL(info) << "Network plugin mode: "
+ << (NetworkAgent::use_legacy_network ? ("legacy (version: " + std::string(BAMBU_NETWORK_AGENT_VERSION_LEGACY) + ")") : ("modern (version: " + configured_version + ")"));
// Force legacy network plugin if debugger attached
// See https://github.com/bambulab/BambuStudio/issues/6726
/* if (!NetworkAgent::use_legacy_network) {
@@ -2857,78 +3190,103 @@ void GUI_App::copy_network_if_available()
{
if (app_config->get("update_network_plugin") != "true")
return;
- std::string network_library, player_library, live555_library, network_library_dst, player_library_dst, live555_library_dst;
+
std::string data_dir_str = data_dir();
boost::filesystem::path data_dir_path(data_dir_str);
auto plugin_folder = data_dir_path / "plugins";
auto cache_folder = data_dir_path / "ota";
std::string changelog_file = cache_folder.string() + "/network_plugins.json";
+
+ std::string cached_version;
+ if (boost::filesystem::exists(changelog_file)) {
+ try {
+ boost::nowide::ifstream ifs(changelog_file);
+ json j;
+ ifs >> j;
+ if (j.contains("version"))
+ cached_version = j["version"];
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": cached_version = " << cached_version;
+ } catch (nlohmann::detail::parse_error& err) {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << changelog_file << " failed: " << err.what();
+ }
+ }
+
+ if (cached_version.empty()) {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": no version found in changelog, aborting copy";
+ app_config->set("update_network_plugin", "false");
+ return;
+ }
+
+ std::string network_library, player_library, live555_library, network_library_dst, player_library_dst, live555_library_dst;
#if defined(_MSC_VER) || defined(_WIN32)
network_library = cache_folder.string() + "/bambu_networking.dll";
- player_library = cache_folder.string() + "/BambuSource.dll";
- live555_library = cache_folder.string() + "/live555.dll";
- network_library_dst = plugin_folder.string() + "/bambu_networking.dll";
- player_library_dst = plugin_folder.string() + "/BambuSource.dll";
+ player_library = cache_folder.string() + "/BambuSource.dll";
+ live555_library = cache_folder.string() + "/live555.dll";
+ network_library_dst = plugin_folder.string() + "/" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".dll";
+ player_library_dst = plugin_folder.string() + "/BambuSource.dll";
live555_library_dst = plugin_folder.string() + "/live555.dll";
#elif defined(__WXMAC__)
network_library = cache_folder.string() + "/libbambu_networking.dylib";
player_library = cache_folder.string() + "/libBambuSource.dylib";
live555_library = cache_folder.string() + "/liblive555.dylib";
- network_library_dst = plugin_folder.string() + "/libbambu_networking.dylib";
+ network_library_dst = plugin_folder.string() + "/lib" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".dylib";
player_library_dst = plugin_folder.string() + "/libBambuSource.dylib";
live555_library_dst = plugin_folder.string() + "/liblive555.dylib";
#else
network_library = cache_folder.string() + "/libbambu_networking.so";
- player_library = cache_folder.string() + "/libBambuSource.so";
- live555_library = cache_folder.string() + "/liblive555.so";
- network_library_dst = plugin_folder.string() + "/libbambu_networking.so";
- player_library_dst = plugin_folder.string() + "/libBambuSource.so";
+ player_library = cache_folder.string() + "/libBambuSource.so";
+ live555_library = cache_folder.string() + "/liblive555.so";
+ network_library_dst = plugin_folder.string() + "/lib" + std::string(BAMBU_NETWORK_LIBRARY) + "_" + cached_version + ".so";
+ player_library_dst = plugin_folder.string() + "/libBambuSource.so";
live555_library_dst = plugin_folder.string() + "/liblive555.so";
#endif
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": checking network_library " << network_library << ", player_library " << player_library;
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": checking network_library " << network_library << ", player_library " << player_library;
if (!boost::filesystem::exists(plugin_folder)) {
- BOOST_LOG_TRIVIAL(info)<< __FUNCTION__ << ": create directory "<set(SETTING_NETWORK_PLUGIN_VERSION, cached_version);
+ app_config->save();
}
if (boost::filesystem::exists(player_library)) {
CopyFileResult cfr = copy_file(player_library, player_library_dst, error_message, false);
if (cfr != CopyFileResult::SUCCESS) {
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": Copying failed(" << cfr << "): " << error_message;
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Copying failed(" << cfr << "): " << error_message;
return;
}
static constexpr const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read;
fs::permissions(player_library_dst, perms);
fs::remove(player_library);
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": Copying player library from" << player_library << " to " << player_library_dst<<" successfully.";
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying player library from " << player_library << " to " << player_library_dst << " successfully.";
}
if (boost::filesystem::exists(live555_library)) {
CopyFileResult cfr = copy_file(live555_library, live555_library_dst, error_message, false);
if (cfr != CopyFileResult::SUCCESS) {
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": Copying failed(" << cfr << "): " << error_message;
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Copying failed(" << cfr << "): " << error_message;
return;
}
static constexpr const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read;
fs::permissions(live555_library_dst, perms);
fs::remove(live555_library);
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": Copying live555 library from" << live555_library << " to " << live555_library_dst<<" successfully.";
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying live555 library from " << live555_library << " to " << live555_library_dst << " successfully.";
}
if (boost::filesystem::exists(changelog_file))
fs::remove(changelog_file);
@@ -2939,13 +3297,39 @@ bool GUI_App::on_init_network(bool try_backup)
{
bool create_network_agent = false;
auto should_load_networking_plugin = app_config->get_bool("installed_networking");
+
+ std::string config_version = app_config->get_network_plugin_version();
+
if(!should_load_networking_plugin) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Don't load plugin as installed_networking is false";
} else {
- int load_agent_dll = Slic3r::NetworkAgent::initialize_network_module();
+ if (config_version.empty()) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": no version configured, need to download";
+ m_networking_need_update = true;
+
+ if (!m_device_manager)
+ m_device_manager = new Slic3r::DeviceManager();
+ if (!m_user_manager)
+ m_user_manager = new Slic3r::UserManager();
+
+ return false;
+ }
+ int load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(false, config_version);
__retry:
if (!load_agent_dll) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, load dll ok";
+
+ std::string loaded_version = Slic3r::NetworkAgent::get_version();
+ if (app_config && !loaded_version.empty() && loaded_version != "00.00.00.00") {
+ std::string config_version = app_config->get_network_plugin_version();
+ std::string config_base = BBL::extract_base_version(config_version);
+ if (config_base != loaded_version) {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": syncing config version from " << config_version << " to loaded " << loaded_version;
+ app_config->set(SETTING_NETWORK_PLUGIN_VERSION, loaded_version);
+ app_config->save();
+ }
+ }
+
if (check_networking_version()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, compatibility version";
auto bambu_source = Slic3r::NetworkAgent::get_bambu_source_entry();
@@ -2962,7 +3346,7 @@ __retry:
if (try_backup) {
int result = Slic3r::NetworkAgent::unload_network_module();
BOOST_LOG_TRIVIAL(info) << "on_init_network, version mismatch, unload_network_module, result = " << result;
- load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(true);
+ load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(true, config_version);
try_backup = false;
goto __retry;
}
@@ -3041,6 +3425,24 @@ __retry:
m_user_manager = new Slic3r::UserManager();
}
+ if (create_network_agent && m_networking_compatible && !NetworkAgent::use_legacy_network) {
+ app_config->clear_remind_network_update_later();
+
+ if (has_network_update_available()) {
+ std::string latest = get_latest_network_version();
+
+ bool should_prompt = !app_config->is_network_update_prompt_disabled()
+ && !app_config->is_network_version_skipped(latest)
+ && !app_config->should_remind_network_update_later();
+
+ if (should_prompt) {
+ CallAfter([this]() {
+ show_network_plugin_download_dialog(true);
+ });
+ }
+ }
+ }
+
return true;
}
@@ -3414,7 +3816,7 @@ void GUI_App::set_side_menu_popup_status(bool status)
m_side_popup_status = status;
}
-void GUI_App::link_to_network_check()
+std::string GUI_App::link_to_network_check()
{
std::string url;
std::string country_code = app_config->get_country_code();
@@ -3429,10 +3831,11 @@ void GUI_App::link_to_network_check()
else {
url = "https://status.bambulab.com";
}
- wxLaunchDefaultBrowser(url);
+ //wxLaunchDefaultBrowser(url);
+ return url; // ORCA
}
-void GUI_App::link_to_lan_only_wiki()
+std::string GUI_App::link_to_lan_only_wiki()
{
std::string url;
std::string country_code = app_config->get_country_code();
@@ -3446,7 +3849,8 @@ void GUI_App::link_to_lan_only_wiki()
else {
url = "https://wiki.bambulab.com/en/knowledge-sharing/enable-lan-mode";
}
- wxLaunchDefaultBrowser(url);
+ //wxLaunchDefaultBrowser(url);
+ return url; // ORCA
}
bool GUI_App::tabs_as_menu() const
@@ -4879,7 +5283,84 @@ void GUI_App::check_new_version_sf(bool show_tips, int by_user)
bool GUI_App::process_network_msg(std::string dev_id, std::string msg)
{
if (dev_id.empty()) {
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << msg;
+ if (msg == "wait_info") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, wait_info";
+ Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
+ if (!dev)
+ return true;
+ MachineObject* obj = dev->get_selected_machine();
+ if (obj && m_agent)
+ m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("Retrieving printer information, please try again later."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "update_studio") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_studio";
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("Please try updating OrcaSlicer and then try again."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "update_fixed_studio") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_fixed_studio";
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("Please try updating OrcaSlicer and then try again."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "cert_expired") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_expired";
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("The certificate has expired. Please check the time settings or update OrcaSlicer and try again."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "cert_revoked") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_revoked";
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("The certificate is no longer valid and the printing functions are unavailable."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "update_firmware_studio") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, firmware internal error";
+ if (!m_show_error_msgdlg) {
+ MessageDialog msg_dlg(nullptr, _L("Internal error. Please try upgrading the firmware and OrcaSlicer version. If the issue persists, contact support."), "", wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ }
+ return true;
+ }
+ else if (msg == "unsigned_studio") {
+ BOOST_LOG_TRIVIAL(info) << "process_network_msg, unsigned_studio";
+ MessageDialog msg_dlg(nullptr,
+ _L("Bambu Lab has implemented a signature verification check in their network plugin that restricts "
+ "third-party software from communicating with your printer.\n\n"
+ "As a result, some printing functions are unavailable in OrcaSlicer."),
+ _L("Network Plugin Restriction"), wxAPPLY | wxOK);
+ m_show_error_msgdlg = true;
+ msg_dlg.ShowModal();
+ m_show_error_msgdlg = false;
+ return true;
+ }
}
else if (msg == "device_cert_installed") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, device_cert_installed";
@@ -4888,7 +5369,6 @@ bool GUI_App::process_network_msg(std::string dev_id, std::string msg)
obj->update_device_cert_state(true);
}
}
-
return true;
}
else if (msg == "device_cert_uninstalled") {
@@ -4898,7 +5378,6 @@ bool GUI_App::process_network_msg(std::string dev_id, std::string msg)
obj->update_device_cert_state(false);
}
}
-
return true;
}
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index f3900f6128..b84dc97c54 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -312,6 +312,7 @@ private:
bool m_adding_script_handler { false };
bool m_side_popup_status{false};
bool m_show_http_errpr_msgdlg{false};
+ bool m_show_error_msgdlg{false};
wxString m_info_dialog_content;
HttpServer m_http_server;
bool m_show_gcode_window{true};
@@ -355,6 +356,9 @@ public:
bool show_3d_navigator() const { return app_config->get_bool("show_3d_navigator"); }
void toggle_show_3d_navigator() const { app_config->set_bool("show_3d_navigator", !show_3d_navigator()); }
+ bool show_canvas_zoom_button() const { return app_config->get_bool("show_canvas_zoom_button"); }
+ void toggle_canvas_zoom_button() const { app_config->set_bool("show_canvas_zoom_button", !show_canvas_zoom_button()); }
+
bool show_outline() const { return app_config->get_bool("show_outline"); }
void toggle_show_outline() const { app_config->set_bool("show_outline", !show_outline()); }
@@ -403,8 +407,8 @@ public:
//update side popup status
bool get_side_menu_popup_status();
void set_side_menu_popup_status(bool status);
- void link_to_network_check();
- void link_to_lan_only_wiki();
+ std::string link_to_network_check(); // ORCA
+ std::string link_to_lan_only_wiki(); // ORCA
const wxColour& get_label_clr_modified() { return m_color_label_modified; }
const wxColour& get_label_clr_sys() { return m_color_label_sys; }
@@ -686,6 +690,11 @@ public:
void restart_networking();
void check_config_updates_from_updater() { check_updates(false); }
+ void show_network_plugin_download_dialog(bool is_update = false);
+ bool hot_reload_network_plugin();
+ std::string get_latest_network_version() const;
+ bool has_network_update_available() const;
+
private:
int updating_bambu_networking();
bool on_init_inner();
@@ -694,6 +703,8 @@ private:
void init_networking_callbacks();
void init_app_config();
void remove_old_networking_plugins();
+ void drain_pending_events(int timeout_ms);
+ bool wait_for_network_idle(int timeout_ms);
//BBS set extra header for http request
std::map get_extra_header();
void init_http_extra_header();
@@ -712,6 +723,7 @@ private:
bool m_init_app_config_from_older { false };
bool m_datadir_redefined { false };
std::string m_older_data_dir_path;
+ bool m_unsigned_plugin_warning_shown { false };
boost::optional m_last_config_version;
bool m_config_corrupted { false };
std::string m_open_method;
diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp
index e7520b5b51..44dd7b8f6e 100644
--- a/src/slic3r/GUI/GUI_Factories.cpp
+++ b/src/slic3r/GUI/GUI_Factories.cpp
@@ -87,14 +87,14 @@ std::map> SettingsFactory::OBJECT_C
{"precise_z_height", "",10}
}},
- { L("Support"), {{"brim_type", "",1},{"brim_width", "",2},{"brim_object_gap", "",3},
- {"enable_support", "",4},{"support_type", "",5},{"support_threshold_angle", "",6}, {"support_threshold_overlap", "",6}, {"support_on_build_plate_only", "",7},
- {"support_filament", "",8},{"support_interface_filament", "",9},{"support_expansion", "",24},{"support_style", "",25},
- {"tree_support_brim_width", "",26}, {"tree_support_branch_angle", "",10},{"tree_support_branch_angle_organic","",10}, {"tree_support_wall_count", "",11},{"tree_support_branch_diameter_angle", "",11},//tree support
- {"support_top_z_distance", "",13},{"support_bottom_z_distance", "",12},{"support_base_pattern", "",14},{"support_base_pattern_spacing", "",15},
- {"support_interface_top_layers", "",16},{"support_interface_bottom_layers", "",17},{"support_interface_spacing", "",18},{"support_bottom_interface_spacing", "",19},
- {"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22},{"support_critical_regions_only", "",23},{"support_remove_small_overhang","",27},
- {"support_object_first_layer_gap","",28}
+ { L("Support"), {{"brim_type", "",1},{"brim_width", "",2},{"brim_object_gap", "",3},{"brim_use_efc_outline", "",4},
+ {"enable_support", "",5},{"support_type", "",6},{"support_threshold_angle", "",7}, {"support_threshold_overlap", "",8}, {"support_on_build_plate_only", "",9},
+ {"support_filament", "",10},{"support_interface_filament", "",11},{"support_expansion", "",12},{"support_style", "",13},
+ {"tree_support_brim_width", "",14}, {"tree_support_branch_angle", "",15},{"tree_support_branch_angle_organic","",16}, {"tree_support_wall_count", "",17},{"tree_support_branch_diameter_angle", "",18},//tree support
+ {"support_bottom_z_distance", "",19},{"support_top_z_distance", "",20},{"support_base_pattern", "",21},{"support_base_pattern_spacing", "",22},
+ {"support_interface_top_layers", "",23},{"support_interface_bottom_layers", "",24},{"support_interface_spacing", "",25},{"support_bottom_interface_spacing", "",26},
+ {"support_object_xy_distance", "",27}, {"bridge_no_support", "",28},{"max_bridge_length", "",29},{"support_critical_regions_only", "",30},{"support_remove_small_overhang","",31},
+ {"support_object_first_layer_gap","",32}
}},
{ L("Speed"), {{"support_speed", "",12}, {"support_interface_speed", "",13}
}}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 04e65fc88a..0ca62d849a 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -281,23 +281,43 @@ bool GLGizmosManager::init_icon_textures()
else
return false;
- if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle.svg", 64, 64, texture_id))
- icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE, texture_id));
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_menu.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_MENU, texture_id));
else
return false;
- if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_hover.svg", 64, 64, texture_id))
- icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_HOVER, texture_id));
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_menu_hover.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_MENU_HOVER, texture_id));
else
return false;
- if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_dark.svg", 64, 64, texture_id))
- icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_DARK, texture_id));
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_menu_dark.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_MENU_DARK, texture_id));
else
return false;
- if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_hover_dark.svg", 64, 64, texture_id))
- icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_DARK_HOVER, texture_id));
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_menu_dark_hover.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_MENU_DARK_HOVER, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_zoom.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_ZOOM, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_zoom_hover.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_ZOOM_HOVER, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_zoom_dark.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_ZOOM_DARK, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/canvas_zoom_dark_hover.svg", 72, 72, texture_id))
+ icon_list.insert(std::make_pair((int) IC_CANVAS_ZOOM_DARK_HOVER, texture_id));
else
return false;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index ba7d5afdb9..5897c2a512 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -170,10 +170,14 @@ public:
IC_TOOLBAR_TOOLTIP,
IC_TOOLBAR_TOOLTIP_HOVER,
IC_NAME_COUNT,
- IC_AXIS_TOGGLE,
- IC_AXIS_TOGGLE_HOVER,
- IC_AXIS_TOGGLE_DARK,
- IC_AXIS_TOGGLE_DARK_HOVER,
+ IC_CANVAS_MENU,
+ IC_CANVAS_MENU_HOVER,
+ IC_CANVAS_MENU_DARK,
+ IC_CANVAS_MENU_DARK_HOVER,
+ IC_CANVAS_ZOOM,
+ IC_CANVAS_ZOOM_HOVER,
+ IC_CANVAS_ZOOM_DARK,
+ IC_CANVAS_ZOOM_DARK_HOVER,
};
explicit GLGizmosManager(GLCanvas3D& parent);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 6d0023a0ba..b6d1a7b7d8 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -3113,7 +3113,7 @@ void MainFrame::init_menubar_as_editor()
// help
append_menu_item(m_topbar->GetCalibMenu(), wxID_ANY, _L("Tutorial"), _L("Calibration help"),
[this](wxCommandEvent&) {
- std::string url = "https://github.com/OrcaSlicer/OrcaSlicer/wiki/Calibration";
+ std::string url = "https://www.orcaslicer.com/wiki/Calibration";
if (const std::string country_code = wxGetApp().app_config->get_country_code(); country_code == "CN") {
// Use gitee mirror for China users
url = "https://gitee.com/n0isyfox/orca-slicer-docs/wikis/%E6%A0%A1%E5%87%86/%E6%89%93%E5%8D%B0%E5%8F%82%E6%95%B0%E6%A0%A1%E5%87%86";
@@ -3229,7 +3229,7 @@ void MainFrame::init_menubar_as_editor()
[this]() {return m_plater->is_view3D_shown();; }, this);
// help
append_menu_item(calib_menu, wxID_ANY, _L("Tutorial"), _L("Calibration help"),
- [this](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/OrcaSlicer/OrcaSlicer/wiki/Calibration", wxBROWSER_NEW_WINDOW); }, "", nullptr,
+ [this](wxCommandEvent&) { wxLaunchDefaultBrowser("https://www.orcaslicer.com/wiki/Calibration", wxBROWSER_NEW_WINDOW); }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this);
m_menubar->Append(calib_menu,wxString::Format("&%s", _L("Calibration")));
diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp
index 7869662d7c..c412b5585a 100644
--- a/src/slic3r/GUI/MediaPlayCtrl.cpp
+++ b/src/slic3r/GUI/MediaPlayCtrl.cpp
@@ -769,7 +769,7 @@ bool MediaPlayCtrl::start_stream_service(bool *need_install)
auto file_dll = tools_dir + dll;
auto file_dll2 = plugins_dir + dll;
if (!boost::filesystem::exists(file_dll) || boost::filesystem::last_write_time(file_dll) != boost::filesystem::last_write_time(file_dll2))
- boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_option::overwrite_if_exists);
+ boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_options::overwrite_existing);
}
boost::process::child process_source(file_source, file_url2.ToStdWstring(), boost::process::start_dir(tools_dir),
boost::process::windows::create_no_window,
diff --git a/src/slic3r/GUI/Monitor.cpp b/src/slic3r/GUI/Monitor.cpp
index aa1e3e2ea8..02b2306ff3 100644
--- a/src/slic3r/GUI/Monitor.cpp
+++ b/src/slic3r/GUI/Monitor.cpp
@@ -1,6 +1,8 @@
#include "Tab.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Model.hpp"
+#include "libslic3r/AppConfig.hpp"
+#include "slic3r/Utils/bambu_networking.hpp"
#include
#include
@@ -195,6 +197,11 @@ void MonitorPanel::init_tabpanel()
m_hms_panel = new HMSPanel(m_tabpanel);
m_tabpanel->AddPage(m_hms_panel, _L("Assistant(HMS)"), "", false);
+ std::string network_ver = Slic3r::NetworkAgent::get_version();
+ if (!network_ver.empty()) {
+ m_tabpanel->SetFooterText(wxString::Format("Network plugin v%s", network_ver));
+ }
+
m_initialized = true;
show_status((int)MonitorStatus::MONITOR_NO_PRINTER);
}
@@ -407,6 +414,7 @@ bool MonitorPanel::Show(bool show)
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (show) {
start_update();
+ update_network_version_footer();
m_refresh_timer->Stop();
m_refresh_timer->SetOwner(this);
@@ -517,5 +525,25 @@ void MonitorPanel::jump_to_LiveView()
m_status_info_panel->get_media_play_ctrl()->jump_to_play();
}
+void MonitorPanel::update_network_version_footer()
+{
+ std::string binary_version = Slic3r::NetworkAgent::get_version();
+ if (binary_version.empty())
+ return;
+
+ std::string configured_version = wxGetApp().app_config->get_network_plugin_version();
+ std::string suffix = BBL::extract_suffix(configured_version);
+ std::string configured_base = BBL::extract_base_version(configured_version);
+
+ wxString footer_text;
+ if (!suffix.empty() && configured_base == binary_version) {
+ footer_text = wxString::Format("Network plugin v%s (%s)", binary_version, suffix);
+ } else {
+ footer_text = wxString::Format("Network plugin v%s", binary_version);
+ }
+
+ m_tabpanel->SetFooterText(footer_text);
+}
+
} // GUI
} // Slic3r
diff --git a/src/slic3r/GUI/Monitor.hpp b/src/slic3r/GUI/Monitor.hpp
index a7f7126534..b7502b9d51 100644
--- a/src/slic3r/GUI/Monitor.hpp
+++ b/src/slic3r/GUI/Monitor.hpp
@@ -157,6 +157,7 @@ public:
void jump_to_HMS();
void jump_to_LiveView();
+ void update_network_version_footer();
};
diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp
index 0e6e1a324d..049a6b00f2 100644
--- a/src/slic3r/GUI/MsgDialog.cpp
+++ b/src/slic3r/GUI/MsgDialog.cpp
@@ -586,7 +586,8 @@ wxBoxSizer *Newer3mfVersionDialog::get_msg_sizer()
if (file_version_newer) {
text1 = new wxStaticText(this, wxID_ANY, _L("The 3MF file version is in Beta and it is newer than the current OrcaSlicer version."));
wxStaticText * text2 = new wxStaticText(this, wxID_ANY, _L("If you would like to try Orca Slicer Beta, you may click to"));
- wxHyperlinkCtrl *github_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Download Beta Version"), "https://github.com/bambulab/BambuStudio/releases");
+ // ORCA standardized HyperLink
+ HyperLink * github_link = new HyperLink(this, _L("Download Beta Version"), "https://github.com/SoftFever/OrcaSlicer/releases");
horizontal_sizer->Add(text2, 0, wxEXPAND, 0);
horizontal_sizer->Add(github_link, 0, wxEXPAND | wxLEFT, 5);
@@ -672,11 +673,9 @@ NetworkErrorDialog::NetworkErrorDialog(wxWindow* parent)
wxBoxSizer* sizer_link = new wxBoxSizer(wxVERTICAL);
- m_link_server_state = new wxHyperlinkCtrl(this, wxID_ANY, _L("Check the status of current system services"), "");
+ // ORCA standardized HyperLink
+ m_link_server_state = new HyperLink(this, _L("Check the status of current system services"), wxGetApp().link_to_network_check());
m_link_server_state->SetFont(::Label::Body_13);
- m_link_server_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); });
- m_link_server_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
- m_link_server_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
sizer_link->Add(m_link_server_state, 0, wxALL, 0);
@@ -690,11 +689,9 @@ NetworkErrorDialog::NetworkErrorDialog(wxWindow* parent)
m_text_proposal->SetFont(::Label::Body_14);
m_text_proposal->SetForegroundColour(0x323A3C);
- m_text_wiki = new wxHyperlinkCtrl(this, wxID_ANY, _L("How to use LAN only mode"), "");
+ // ORCA standardized HyperLink
+ m_text_wiki = new HyperLink(this, _L("How to use LAN only mode"), wxGetApp().link_to_lan_only_wiki());
m_text_wiki->SetFont(::Label::Body_13);
- m_text_wiki->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_lan_only_wiki(); });
- m_text_wiki->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_HAND); });
- m_text_wiki->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCURSOR_ARROW); });
sizer_help->Add(m_text_proposal, 0, wxEXPAND, 0);
sizer_help->Add(m_text_wiki, 0, wxALL, 0);
diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp
index 7b4eb71612..bb3abde75c 100644
--- a/src/slic3r/GUI/MsgDialog.hpp
+++ b/src/slic3r/GUI/MsgDialog.hpp
@@ -14,6 +14,7 @@
#include "Widgets/Button.hpp"
#include "Widgets/CheckBox.hpp"
#include "Widgets/TextInput.hpp"
+#include "Widgets/HyperLink.hpp"
#include "BBLStatusBar.hpp"
#include "BBLStatusBarSend.hpp"
#include "libslic3r/Semver.hpp"
@@ -424,9 +425,9 @@ public:
private:
Label* m_text_basic;
- wxHyperlinkCtrl* m_link_server_state;
+ HyperLink* m_link_server_state; // ORCA
Label* m_text_proposal;
- wxHyperlinkCtrl* m_text_wiki;
+ HyperLink* m_text_wiki; // ORCA
Button * m_button_confirm;
public:
diff --git a/src/slic3r/GUI/MultiMachineManagerPage.cpp b/src/slic3r/GUI/MultiMachineManagerPage.cpp
index 3956f89072..5b0ca791b7 100644
--- a/src/slic3r/GUI/MultiMachineManagerPage.cpp
+++ b/src/slic3r/GUI/MultiMachineManagerPage.cpp
@@ -653,7 +653,7 @@ void MultiMachineManagerPage::start_timer()
m_flipping_timer->SetOwner(this);
m_flipping_timer->Start(1000);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxTimerEvent(*m_flipping_timer));
}
void MultiMachineManagerPage::update_page_number()
diff --git a/src/slic3r/GUI/MultiMachinePage.cpp b/src/slic3r/GUI/MultiMachinePage.cpp
index f7cb05a80e..b9b71ad670 100644
--- a/src/slic3r/GUI/MultiMachinePage.cpp
+++ b/src/slic3r/GUI/MultiMachinePage.cpp
@@ -61,7 +61,7 @@ bool MultiMachinePage::Show(bool show)
m_refresh_timer->Stop();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(2000);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxTimerEvent(*m_refresh_timer));
}
else {
m_refresh_timer->Stop();
@@ -96,7 +96,7 @@ void MultiMachinePage::init_timer()
m_refresh_timer = new wxTimer();
//m_refresh_timer->SetOwner(this);
//m_refresh_timer->Start(8000);
- //wxPostEvent(this, wxTimerEvent());
+ //wxPostEvent(this, wxTimerEvent(*m_refresh_timer));
}
void MultiMachinePage::on_timer(wxTimerEvent& event)
@@ -482,7 +482,7 @@ bool MultiMachinePickPage::Show(bool show)
//m_refresh_timer->Stop();
//m_refresh_timer->SetOwner(this);
//m_refresh_timer->Start(4000);
- //wxPostEvent(this, wxTimerEvent());
+ //wxPostEvent(this, wxTimerEvent(*m_refresh_timer));
}
else {
//m_refresh_timer->Stop();
diff --git a/src/slic3r/GUI/MultiTaskManagerPage.cpp b/src/slic3r/GUI/MultiTaskManagerPage.cpp
index 37321063f8..0b0b422eb4 100644
--- a/src/slic3r/GUI/MultiTaskManagerPage.cpp
+++ b/src/slic3r/GUI/MultiTaskManagerPage.cpp
@@ -1402,7 +1402,7 @@ void CloudTaskManagerPage::start_timer()
m_flipping_timer->SetOwner(this);
m_flipping_timer->Start(1000);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxTimerEvent(*m_flipping_timer));
}
void CloudTaskManagerPage::on_timer(wxTimerEvent& event)
diff --git a/src/slic3r/GUI/NetworkPluginDialog.cpp b/src/slic3r/GUI/NetworkPluginDialog.cpp
new file mode 100644
index 0000000000..5c1e158748
--- /dev/null
+++ b/src/slic3r/GUI/NetworkPluginDialog.cpp
@@ -0,0 +1,377 @@
+#include "NetworkPluginDialog.hpp"
+#include "I18N.hpp"
+#include "GUI_App.hpp"
+#include "MainFrame.hpp"
+#include "MsgDialog.hpp"
+#include "Widgets/Label.hpp"
+#include "BitmapCache.hpp"
+#include "wxExtensions.hpp"
+#include "slic3r/Utils/bambu_networking.hpp"
+
+#include
+#include
+#include
+
+namespace Slic3r {
+namespace GUI {
+
+NetworkPluginDownloadDialog::NetworkPluginDownloadDialog(wxWindow* parent, Mode mode,
+ const std::string& current_version,
+ const std::string& error_message,
+ const std::string& error_details)
+ : DPIDialog(parent, wxID_ANY, mode == Mode::UpdateAvailable ?
+ _L("Network Plugin Update Available") : _L("Bambu Network Plugin Required"),
+ wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
+ , m_mode(mode)
+ , m_error_message(error_message)
+ , m_error_details(error_details)
+{
+ SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
+ m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
+ main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
+
+ SetSizer(main_sizer);
+
+ if (mode == Mode::UpdateAvailable) {
+ create_update_available_ui(current_version);
+ } else {
+ create_missing_plugin_ui();
+ }
+ Layout();
+ Fit();
+ CentreOnParent();
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+void NetworkPluginDownloadDialog::create_missing_plugin_ui()
+{
+ wxBoxSizer* main_sizer = static_cast(GetSizer());
+
+ auto* desc = new wxStaticText(this, wxID_ANY,
+ m_mode == Mode::CorruptedPlugin ?
+ _L("The Bambu Network Plugin is corrupted or incompatible. Please reinstall it.") :
+ _L("The Bambu Network Plugin is required for cloud features, printer discovery, and remote printing."));
+ desc->SetFont(::Label::Body_13);
+ desc->Wrap(FromDIP(400));
+ main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
+
+ if (!m_error_message.empty()) {
+ auto* error_label = new wxStaticText(this, wxID_ANY,
+ wxString::Format(_L("Error: %s"), wxString::FromUTF8(m_error_message)));
+ error_label->SetFont(::Label::Body_13);
+ error_label->SetForegroundColour(wxColour(208, 93, 93));
+ error_label->Wrap(FromDIP(400));
+ main_sizer->Add(error_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+
+ if (!m_error_details.empty()) {
+ m_details_pane = new wxCollapsiblePane(this, wxID_ANY, _L("Show details"));
+ auto* pane = m_details_pane->GetPane();
+ auto* pane_sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto* details_text = new wxStaticText(pane, wxID_ANY, wxString::FromUTF8(m_error_details));
+ details_text->SetFont(wxGetApp().code_font());
+ details_text->Wrap(FromDIP(380));
+ pane_sizer->Add(details_text, 0, wxALL, FromDIP(10));
+
+ pane->SetSizer(pane_sizer);
+ main_sizer->Add(m_details_pane, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+ }
+ }
+
+ auto* version_label = new wxStaticText(this, wxID_ANY, _L("Version to install:"));
+ version_label->SetFont(::Label::Body_13);
+ main_sizer->Add(version_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ setup_version_selector();
+ main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
+
+ auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(
+ std::pair(wxColour(0, 137, 123), StateColor::Pressed),
+ std::pair(wxColour(38, 166, 154), StateColor::Hovered),
+ std::pair(wxColour(0, 150, 136), StateColor::Normal));
+
+ StateColor btn_bg_white(
+ std::pair(wxColour(206, 206, 206), StateColor::Pressed),
+ std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ auto* btn_download = new Button(this, _L("Download and Install"));
+ btn_download->SetBackgroundColor(btn_bg_green);
+ btn_download->SetBorderColor(*wxWHITE);
+ btn_download->SetTextColor(*wxWHITE);
+ btn_download->SetFont(::Label::Body_12);
+ btn_download->SetMinSize(wxSize(FromDIP(120), FromDIP(24)));
+ btn_download->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
+ btn_sizer->Add(btn_download, 0, wxRIGHT, FromDIP(10));
+
+ auto* btn_skip = new Button(this, _L("Skip for Now"));
+ btn_skip->SetBackgroundColor(btn_bg_white);
+ btn_skip->SetBorderColor(wxColour(38, 46, 48));
+ btn_skip->SetFont(::Label::Body_12);
+ btn_skip->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_skip->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip, this);
+ btn_sizer->Add(btn_skip, 0, wxRIGHT, FromDIP(10));
+
+ main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
+ main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
+}
+
+void NetworkPluginDownloadDialog::create_update_available_ui(const std::string& current_version)
+{
+ wxBoxSizer* main_sizer = static_cast(GetSizer());
+
+ auto* desc = new wxStaticText(this, wxID_ANY,
+ _L("A new version of the Bambu Network Plugin is available."));
+ desc->SetFont(::Label::Body_13);
+ desc->Wrap(FromDIP(400));
+ main_sizer->Add(desc, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
+
+ auto* version_text = new wxStaticText(this, wxID_ANY,
+ wxString::Format(_L("Current version: %s"), wxString::FromUTF8(current_version)));
+ version_text->SetFont(::Label::Body_13);
+ main_sizer->Add(version_text, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+
+ auto* update_label = new wxStaticText(this, wxID_ANY, _L("Update to version:"));
+ update_label->SetFont(::Label::Body_13);
+ main_sizer->Add(update_label, 0, wxLEFT | wxRIGHT, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ setup_version_selector();
+ main_sizer->Add(m_version_combo, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(25));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
+
+ auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(
+ std::pair(wxColour(0, 137, 123), StateColor::Pressed),
+ std::pair(wxColour(38, 166, 154), StateColor::Hovered),
+ std::pair(wxColour(0, 150, 136), StateColor::Normal));
+
+ StateColor btn_bg_white(
+ std::pair(wxColour(206, 206, 206), StateColor::Pressed),
+ std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ auto* btn_download = new Button(this, _L("Update Now"));
+ btn_download->SetBackgroundColor(btn_bg_green);
+ btn_download->SetBorderColor(*wxWHITE);
+ btn_download->SetTextColor(*wxWHITE);
+ btn_download->SetFont(::Label::Body_12);
+ btn_download->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_download->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_download, this);
+ btn_sizer->Add(btn_download, 0, wxRIGHT, FromDIP(10));
+
+ auto* btn_remind = new Button(this, _L("Remind Later"));
+ btn_remind->SetBackgroundColor(btn_bg_white);
+ btn_remind->SetBorderColor(wxColour(38, 46, 48));
+ btn_remind->SetFont(::Label::Body_12);
+ btn_remind->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_remind->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_remind_later, this);
+ btn_sizer->Add(btn_remind, 0, wxRIGHT, FromDIP(10));
+
+ auto* btn_skip = new Button(this, _L("Skip Version"));
+ btn_skip->SetBackgroundColor(btn_bg_white);
+ btn_skip->SetBorderColor(wxColour(38, 46, 48));
+ btn_skip->SetFont(::Label::Body_12);
+ btn_skip->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_skip->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_skip_version, this);
+ btn_sizer->Add(btn_skip, 0, wxRIGHT, FromDIP(10));
+
+ auto* btn_dont_ask = new Button(this, _L("Don't Ask Again"));
+ btn_dont_ask->SetBackgroundColor(btn_bg_white);
+ btn_dont_ask->SetBorderColor(wxColour(38, 46, 48));
+ btn_dont_ask->SetFont(::Label::Body_12);
+ btn_dont_ask->SetMinSize(wxSize(FromDIP(110), FromDIP(24)));
+ btn_dont_ask->Bind(wxEVT_BUTTON, &NetworkPluginDownloadDialog::on_dont_ask, this);
+ btn_sizer->Add(btn_dont_ask, 0, wxRIGHT, FromDIP(10));
+
+ main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
+ main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
+}
+
+void NetworkPluginDownloadDialog::setup_version_selector()
+{
+ m_version_combo = new ComboBox(this, wxID_ANY, wxEmptyString,
+ wxDefaultPosition, wxSize(FromDIP(380), FromDIP(28)), 0, nullptr, wxCB_READONLY);
+ m_version_combo->SetFont(::Label::Body_13);
+
+ m_available_versions = BBL::get_all_available_versions();
+ for (size_t i = 0; i < m_available_versions.size(); ++i) {
+ const auto& ver = m_available_versions[i];
+ wxString label;
+ if (!ver.suffix.empty()) {
+ label = wxString::FromUTF8("\xE2\x94\x94 ") + wxString::FromUTF8(ver.display_name);
+ } else {
+ label = wxString::FromUTF8(ver.display_name);
+ if (ver.is_latest) {
+ label += wxString(" ") + _L("(Latest)");
+ }
+ }
+ m_version_combo->Append(label);
+ }
+
+ m_version_combo->SetSelection(0);
+}
+
+std::string NetworkPluginDownloadDialog::get_selected_version() const
+{
+ if (!m_version_combo) {
+ return "";
+ }
+
+ int selection = m_version_combo->GetSelection();
+ if (selection < 0 || selection >= static_cast(m_available_versions.size())) {
+ return "";
+ }
+
+ return m_available_versions[selection].version;
+}
+
+void NetworkPluginDownloadDialog::on_download(wxCommandEvent& evt)
+{
+ int selection = m_version_combo ? m_version_combo->GetSelection() : 0;
+ if (selection >= 0 && selection < static_cast(m_available_versions.size())) {
+ const std::string& warning = m_available_versions[selection].warning;
+ if (!warning.empty()) {
+ MessageDialog warn_dlg(this, wxString::FromUTF8(warning), _L("Warning"), wxOK | wxCANCEL | wxICON_WARNING);
+ if (warn_dlg.ShowModal() != wxID_OK) {
+ return;
+ }
+ }
+ }
+ EndModal(RESULT_DOWNLOAD);
+}
+
+void NetworkPluginDownloadDialog::on_skip(wxCommandEvent& evt)
+{
+ EndModal(RESULT_SKIP);
+}
+
+void NetworkPluginDownloadDialog::on_remind_later(wxCommandEvent& evt)
+{
+ EndModal(RESULT_REMIND_LATER);
+}
+
+void NetworkPluginDownloadDialog::on_skip_version(wxCommandEvent& evt)
+{
+ EndModal(RESULT_SKIP_VERSION);
+}
+
+void NetworkPluginDownloadDialog::on_dont_ask(wxCommandEvent& evt)
+{
+ EndModal(RESULT_DONT_ASK);
+}
+
+void NetworkPluginDownloadDialog::on_dpi_changed(const wxRect& suggested_rect)
+{
+ Layout();
+ Fit();
+}
+
+NetworkPluginRestartDialog::NetworkPluginRestartDialog(wxWindow* parent)
+ : DPIDialog(parent, wxID_ANY, _L("Restart Required"),
+ wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
+{
+ SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
+ m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
+ main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
+
+ auto* icon_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto* icon_bitmap = new wxStaticBitmap(this, wxID_ANY,
+ create_scaled_bitmap("info", nullptr, 64));
+ icon_sizer->Add(icon_bitmap, 0, wxALL, FromDIP(10));
+
+ auto* text_sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto* desc = new wxStaticText(this, wxID_ANY,
+ _L("The Bambu Network Plugin has been installed successfully."));
+ desc->SetFont(::Label::Body_14);
+ desc->Wrap(FromDIP(350));
+ text_sizer->Add(desc, 0, wxTOP, FromDIP(10));
+ text_sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
+
+ auto* restart_msg = new wxStaticText(this, wxID_ANY,
+ _L("A restart is required to load the new plugin. Would you like to restart now?"));
+ restart_msg->SetFont(::Label::Body_13);
+ restart_msg->Wrap(FromDIP(350));
+ text_sizer->Add(restart_msg, 0, wxBOTTOM, FromDIP(10));
+
+ icon_sizer->Add(text_sizer, 1, wxEXPAND | wxRIGHT, FromDIP(20));
+ main_sizer->Add(icon_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(15));
+ main_sizer->Add(0, 0, 0, wxTOP, FromDIP(20));
+
+ auto* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
+
+ StateColor btn_bg_green(
+ std::pair(wxColour(0, 137, 123), StateColor::Pressed),
+ std::pair(wxColour(38, 166, 154), StateColor::Hovered),
+ std::pair(wxColour(0, 150, 136), StateColor::Normal));
+
+ StateColor btn_bg_white(
+ std::pair(wxColour(206, 206, 206), StateColor::Pressed),
+ std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ auto* btn_restart = new Button(this, _L("Restart Now"));
+ btn_restart->SetBackgroundColor(btn_bg_green);
+ btn_restart->SetBorderColor(*wxWHITE);
+ btn_restart->SetTextColor(*wxWHITE);
+ btn_restart->SetFont(::Label::Body_12);
+ btn_restart->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_restart->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
+ m_restart_now = true;
+ EndModal(wxID_OK);
+ });
+ btn_sizer->Add(btn_restart, 0, wxRIGHT, FromDIP(10));
+
+ auto* btn_later = new Button(this, _L("Restart Later"));
+ btn_later->SetBackgroundColor(btn_bg_white);
+ btn_later->SetBorderColor(wxColour(38, 46, 48));
+ btn_later->SetFont(::Label::Body_12);
+ btn_later->SetMinSize(wxSize(FromDIP(100), FromDIP(24)));
+ btn_later->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
+ m_restart_now = false;
+ EndModal(wxID_CANCEL);
+ });
+ btn_sizer->Add(btn_later, 0, wxRIGHT, FromDIP(10));
+
+ main_sizer->Add(btn_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
+ main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(20));
+
+ SetSizer(main_sizer);
+ Layout();
+ Fit();
+ CentreOnParent();
+ wxGetApp().UpdateDlgDarkUI(this);
+}
+
+void NetworkPluginRestartDialog::on_dpi_changed(const wxRect& suggested_rect)
+{
+ Layout();
+ Fit();
+}
+
+}
+}
diff --git a/src/slic3r/GUI/NetworkPluginDialog.hpp b/src/slic3r/GUI/NetworkPluginDialog.hpp
new file mode 100644
index 0000000000..88d4a3813c
--- /dev/null
+++ b/src/slic3r/GUI/NetworkPluginDialog.hpp
@@ -0,0 +1,76 @@
+#ifndef slic3r_GUI_NetworkPluginDialog_hpp_
+#define slic3r_GUI_NetworkPluginDialog_hpp_
+
+#include "GUI_Utils.hpp"
+#include "MsgDialog.hpp"
+#include "Widgets/ComboBox.hpp"
+#include "Widgets/Button.hpp"
+#include "slic3r/Utils/bambu_networking.hpp"
+#include
+
+namespace Slic3r {
+namespace GUI {
+
+class NetworkPluginDownloadDialog : public DPIDialog
+{
+public:
+ enum class Mode {
+ MissingPlugin,
+ UpdateAvailable,
+ CorruptedPlugin
+ };
+
+ NetworkPluginDownloadDialog(wxWindow* parent, Mode mode,
+ const std::string& current_version = "",
+ const std::string& error_message = "",
+ const std::string& error_details = "");
+
+ std::string get_selected_version() const;
+
+ enum ResultCode {
+ RESULT_DOWNLOAD = wxID_OK,
+ RESULT_SKIP = wxID_CANCEL,
+ RESULT_REMIND_LATER = wxID_APPLY,
+ RESULT_SKIP_VERSION = wxID_IGNORE,
+ RESULT_DONT_ASK = wxID_ABORT
+ };
+
+protected:
+ void on_dpi_changed(const wxRect& suggested_rect) override;
+
+private:
+ void create_missing_plugin_ui();
+ void create_update_available_ui(const std::string& current_version);
+ void setup_version_selector();
+ void on_download(wxCommandEvent& evt);
+ void on_skip(wxCommandEvent& evt);
+ void on_remind_later(wxCommandEvent& evt);
+ void on_skip_version(wxCommandEvent& evt);
+ void on_dont_ask(wxCommandEvent& evt);
+
+ Mode m_mode;
+ ComboBox* m_version_combo{nullptr};
+ wxCollapsiblePane* m_details_pane{nullptr};
+ std::string m_error_message;
+ std::string m_error_details;
+ std::vector m_available_versions;
+};
+
+class NetworkPluginRestartDialog : public DPIDialog
+{
+public:
+ NetworkPluginRestartDialog(wxWindow* parent);
+
+ bool should_restart_now() const { return m_restart_now; }
+
+protected:
+ void on_dpi_changed(const wxRect& suggested_rect) override;
+
+private:
+ bool m_restart_now{false};
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GUI_NetworkPluginDialog_hpp_
diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp
index 9abf49323a..c9bb132f68 100644
--- a/src/slic3r/GUI/NotificationManager.hpp
+++ b/src/slic3r/GUI/NotificationManager.hpp
@@ -980,7 +980,7 @@ private:
NotificationData{NotificationType::BBLUserPresetExceedLimit, NotificationLevel::WarningNotificationLevel, BBL_NOTICE_MAX_INTERVAL,
_u8L("The number of user presets cached in the cloud has exceeded the upper limit, newly created user presets can only be used locally."),
- _u8L("Wiki"),
+ _u8L("Wiki Guide"),
[](wxEvtHandler* evnthndlr) {
wxLaunchDefaultBrowser("https://wiki.bambulab.com/en/software/bambu-studio/3rd-party-printer-profile#cloud-user-presets-limit");
return false;
diff --git a/src/slic3r/GUI/ObjColorDialog.cpp b/src/slic3r/GUI/ObjColorDialog.cpp
index 6d3b277c03..7575777507 100644
--- a/src/slic3r/GUI/ObjColorDialog.cpp
+++ b/src/slic3r/GUI/ObjColorDialog.cpp
@@ -47,14 +47,7 @@ wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error)
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
if (!exist_error) {
btn_sizer->AddSpacer(FromDIP(25));
- wxStaticText *tips = new wxStaticText(this, wxID_ANY, _L("Open Wiki for more information >"));
- /* wxFont font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false);
- font.SetUnderlined(true);
- tips->SetFont(font);*/
- auto font = tips->GetFont();
- font.SetUnderlined(true);
- tips->SetFont(font);
- tips->SetForegroundColour(wxColour("#009687"));
+ auto *tips = new HyperLink(this, _L("Wiki Guide")); // ORCA
tips->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
bool is_zh = wxGetApp().app_config->get("language") == "zh_CN";
if (is_zh) {
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 3d0318f663..5b4f9d3504 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -1312,7 +1312,7 @@ wxString OptionsGroup::get_url(const std::string& path_end)
str = str.Left(pos) + anchor;
}
// Orca: point to sf wiki for seam parameters
- return wxString::Format(L"https://github.com/OrcaSlicer/OrcaSlicer/wiki/%s", from_u8(path_end));
+ return wxString::Format(L"https://www.orcaslicer.com/wiki/%s", from_u8(path_end));
}
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index cc67ee11fd..059955a7cc 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -4670,7 +4670,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
"extruder_clearance_radius",
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
- "brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
+ "brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_enable_framework",
"prime_tower_infill_gap", "prime_volume",
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index db330f84c8..0dedacb9d0 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -14,6 +14,8 @@
#include "NetworkTestDialog.hpp"
#include "Widgets/StaticLine.hpp"
#include "Widgets/RadioGroup.hpp"
+#include "slic3r/Utils/bambu_networking.hpp"
+#include "DownloadProgressDialog.hpp"
#ifdef __WINDOWS__
#ifdef _MSW_DARK_MODE
@@ -78,7 +80,7 @@ std::tuple PreferencesDialog::create_item_combobox_base(
return {m_sizer_combox, combobox};
}
-wxBoxSizer* PreferencesDialog::create_item_combobox(wxString title, wxString tooltip, std::string param, std::vector vlist)
+wxBoxSizer* PreferencesDialog::create_item_combobox(wxString title, wxString tooltip, std::string param, std::vector vlist, std::function onchange)
{
unsigned int current_index = 0;
@@ -90,8 +92,10 @@ wxBoxSizer* PreferencesDialog::create_item_combobox(wxString title, wxString too
auto [sizer, combobox] = create_item_combobox_base(title, tooltip, param, vlist, current_index);
//// save config
- combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param](wxCommandEvent& e) {
+ combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param, onchange](wxCommandEvent& e) {
app_config->set(param, std::to_string(e.GetSelection()));
+ if (onchange)
+ onchange(std::to_string(e.GetSelection()));
e.Skip();
});
@@ -882,7 +886,6 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too
if (pbool) {
GUI::wxGetApp().CallAfter([] { GUI::wxGetApp().ShowDownNetPluginDlg(); });
}
- if (m_legacy_networking_ckeckbox != nullptr) { m_legacy_networking_ckeckbox->Enable(pbool); }
}
#endif // __WXMSW__
@@ -910,7 +913,7 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too
if (param == "enable_high_low_temp_mixed_printing") {
if (checkbox->GetValue()) {
const wxString warning_title = _L("Bed Temperature Difference Warning");
- const wxString warning_message =
+ const wxString warning_message =
_L("Using filaments with significantly different temperatures may cause:\n"
"• Extruder clogging\n"
"• Nozzle damage\n"
@@ -950,11 +953,6 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too
//// for debug mode
if (param == "developer_mode") { m_developer_mode_ckeckbox = checkbox; }
if (param == "internal_developer_mode") { m_internal_developer_mode_ckeckbox = checkbox; }
- if (param == "legacy_networking") {
- m_legacy_networking_ckeckbox = checkbox;
- bool pbool = app_config->get_bool("installed_networking");
- checkbox->Enable(pbool);
- }
return m_sizer_checkbox;
}
@@ -1289,6 +1287,10 @@ void PreferencesDialog::create_items()
auto item_remember_printer = create_item_checkbox(_L("Remember printer configuration"), _L("If enabled, Orca will remember and switch filament/process configuration for each printer automatically."), "remember_printer_config");
g_sizer->Add(item_remember_printer);
+ auto item_filament_preset_grouping = create_item_combobox(_L("Group user filament presets"), _L("Group user filament presets based on selection"),
+ "group_filament_presets", {_L("All"), _L("None"), _L("By type"), _L("By vendor")}, [](wxString value) {wxGetApp().plater()->sidebar().update_presets(Preset::TYPE_FILAMENT);});
+ g_sizer->Add(item_filament_preset_grouping);
+
//// GENERAL > Features
g_sizer->Add(create_item_title(_L("Features")), 1, wxEXPAND);
@@ -1414,9 +1416,113 @@ void PreferencesDialog::create_items()
auto item_enable_plugin = create_item_checkbox(_L("Enable network plugin"), "", "installed_networking");
g_sizer->Add(item_enable_plugin);
-
- auto item_legacy_network = create_item_checkbox(_L("Use legacy network plugin"), _L("Disable to use latest network plugin that supports new BambuLab firmwares."), "legacy_networking", _L("(Requires restart)"));
- g_sizer->Add(item_legacy_network);
+
+ m_network_version_sizer = new wxBoxSizer(wxHORIZONTAL);
+ m_network_version_sizer->AddSpacer(FromDIP(DESIGN_LEFT_MARGIN));
+
+ auto version_title = new wxStaticText(m_parent, wxID_ANY, _L("Network plugin version"), wxDefaultPosition, DESIGN_TITLE_SIZE, wxST_NO_AUTORESIZE);
+ version_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
+ version_title->SetFont(::Label::Body_14);
+ version_title->SetToolTip(_L("Select the network plugin version to use"));
+ version_title->Wrap(DESIGN_TITLE_SIZE.x);
+ m_network_version_sizer->Add(version_title, 0, wxALIGN_CENTER);
+
+ m_network_version_combo = new ::ComboBox(m_parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(180), -1), 0, nullptr, wxCB_READONLY);
+ m_network_version_combo->SetFont(::Label::Body_14);
+ m_network_version_combo->GetDropDown().SetFont(::Label::Body_14);
+
+ std::string current_version = app_config->get_network_plugin_version();
+ if (current_version.empty()) {
+ current_version = BBL::get_latest_network_version();
+ }
+ int current_selection = 0;
+
+ m_available_versions = BBL::get_all_available_versions();
+
+ for (size_t i = 0; i < m_available_versions.size(); i++) {
+ const auto& ver = m_available_versions[i];
+ wxString label;
+
+ if (!ver.suffix.empty()) {
+ label = wxString::FromUTF8("\xE2\x94\x94 ") + wxString::FromUTF8(ver.display_name);
+ } else {
+ label = wxString::FromUTF8(ver.display_name);
+ }
+
+ if (ver.is_latest) {
+ label += " " + _L("(Latest)");
+ }
+ m_network_version_combo->Append(label);
+ if (current_version == ver.version) {
+ current_selection = i;
+ }
+ }
+
+ m_network_version_combo->SetSelection(current_selection);
+ m_network_version_sizer->Add(m_network_version_combo, 0, wxALIGN_CENTER | wxLEFT, FromDIP(5));
+
+ m_network_version_combo->GetDropDown().Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& e) {
+ int selection = e.GetSelection();
+ if (selection >= 0 && selection < (int)m_available_versions.size()) {
+ const auto& selected_ver = m_available_versions[selection];
+ std::string new_version = selected_ver.version;
+ std::string old_version = app_config->get_network_plugin_version();
+ if (old_version.empty()) {
+ old_version = BBL::get_latest_network_version();
+ }
+
+ app_config->set(SETTING_NETWORK_PLUGIN_VERSION, new_version);
+ app_config->save();
+
+ if (new_version != old_version) {
+ BOOST_LOG_TRIVIAL(info) << "Network plugin version changed from " << old_version << " to " << new_version;
+
+ // Update the use_legacy_network flag immediately
+ bool is_legacy = (new_version == BAMBU_NETWORK_AGENT_VERSION_LEGACY);
+ bool was_legacy = (old_version == BAMBU_NETWORK_AGENT_VERSION_LEGACY);
+ if (is_legacy != was_legacy) {
+ Slic3r::NetworkAgent::use_legacy_network = is_legacy;
+ BOOST_LOG_TRIVIAL(info) << "Updated use_legacy_network flag to " << is_legacy;
+ }
+
+ if (!selected_ver.warning.empty()) {
+ MessageDialog warn_dlg(this, wxString::FromUTF8(selected_ver.warning), _L("Warning"), wxOK | wxCANCEL | wxICON_WARNING);
+ if (warn_dlg.ShowModal() != wxID_OK) {
+ app_config->set(SETTING_NETWORK_PLUGIN_VERSION, old_version);
+ app_config->save();
+ Slic3r::NetworkAgent::use_legacy_network = was_legacy;
+ e.Skip();
+ return;
+ }
+ }
+
+ // Check if the selected version already exists on disk
+ if (Slic3r::NetworkAgent::versioned_library_exists(new_version)) {
+ BOOST_LOG_TRIVIAL(info) << "Version " << new_version << " already exists on disk, triggering hot reload";
+ if (wxGetApp().hot_reload_network_plugin()) {
+ MessageDialog dlg(this, _L("Network plugin switched successfully."), _L("Success"), wxOK | wxICON_INFORMATION);
+ dlg.ShowModal();
+ } else {
+ MessageDialog dlg(this, _L("Failed to load network plugin. Please restart the application."), _L("Restart Required"), wxOK | wxICON_WARNING);
+ dlg.ShowModal();
+ }
+ } else {
+ wxString msg = wxString::Format(
+ _L("You've selected network plugin version %s.\n\nWould you like to download and install this version now?\n\nNote: The application may need to restart after installation."),
+ wxString::FromUTF8(new_version));
+
+ MessageDialog dlg(this, msg, _L("Download Network Plugin"), wxYES_NO | wxICON_QUESTION);
+ if (dlg.ShowModal() == wxID_YES) {
+ DownloadProgressDialog progress_dlg(_L("Downloading Network Plugin"));
+ progress_dlg.ShowModal();
+ }
+ }
+ }
+ }
+ e.Skip();
+ });
+
+ g_sizer->Add(m_network_version_sizer);
g_sizer->AddSpacer(FromDIP(10));
sizer_page->Add(g_sizer, 0, wxEXPAND);
@@ -1487,6 +1593,18 @@ void PreferencesDialog::create_items()
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), _L("Log Level"), log_level_list);
g_sizer->Add(loglevel_combox);
+ g_sizer->Add(create_item_title(_L("Network Plugin")), 1, wxEXPAND);
+ auto item_reload_plugin = create_item_button(_L("Network plugin"), _L("Reload"), _L("Reload the network plugin without restarting the application"), "", [this]() {
+ if (wxGetApp().hot_reload_network_plugin()) {
+ MessageDialog dlg(this, _L("Network plugin reloaded successfully."), _L("Reload"), wxOK | wxICON_INFORMATION);
+ dlg.ShowModal();
+ } else {
+ MessageDialog dlg(this, _L("Failed to reload network plugin. Please restart the application."), _L("Reload Failed"), wxOK | wxICON_ERROR);
+ dlg.ShowModal();
+ }
+ });
+ g_sizer->Add(item_reload_plugin);
+
//// DEVELOPER > Debug
#if !BBL_RELEASE_TO_PUBLIC
g_sizer->Add(create_item_title(_L("Debug")), 1, wxEXPAND);
@@ -1687,7 +1805,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
bSizer->Add(enable_ssl_for_mqtt, 0, wxTOP, FromDIP(3));
bSizer->Add(enable_ssl_for_ftp, 0, wxTOP, FromDIP(3));
bSizer->Add(item_internal_developer, 0, wxTOP, FromDIP(3));
- bSizer->Add(title_host, 0, wxEXPAND);
+ bSizer->Add(title_host, 0, wxEXPAND | wxTOP, FromDIP(10));
bSizer->Add(radio_group, 0, wxEXPAND | wxLEFT, FromDIP(DESIGN_LEFT_MARGIN));
bSizer->Add(debug_button, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(15));
diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp
index ecd591e089..892c1ec35c 100644
--- a/src/slic3r/GUI/Preferences.hpp
+++ b/src/slic3r/GUI/Preferences.hpp
@@ -13,6 +13,7 @@
#include "Widgets/CheckBox.hpp"
#include "Widgets/TextInput.hpp"
#include "Widgets/TabCtrl.hpp"
+#include "slic3r/Utils/bambu_networking.hpp"
namespace Slic3r { namespace GUI {
@@ -67,7 +68,9 @@ public:
::CheckBox * m_internal_developer_mode_ckeckbox = {nullptr};
::CheckBox * m_dark_mode_ckeckbox = {nullptr};
::TextInput *m_backup_interval_textinput = {nullptr};
- ::CheckBox * m_legacy_networking_ckeckbox = {nullptr};
+ ::ComboBox * m_network_version_combo = {nullptr};
+ wxBoxSizer * m_network_version_sizer = {nullptr};
+ std::vector m_available_versions;
wxString m_developer_mode_def;
wxString m_internal_developer_mode_def;
@@ -77,7 +80,7 @@ public:
std::vector f_sizers;
wxBoxSizer *create_item_title(wxString title);
- wxBoxSizer *create_item_combobox(wxString title, wxString tooltip, std::string param, std::vector vlist);
+ wxBoxSizer *create_item_combobox(wxString title, wxString tooltip, std::string param, std::vector vlist, std::function onchange = {});
wxBoxSizer *create_item_combobox(wxString title, wxString tooltip, std::string param, std::vector vlist, std::vector config_name_index);
wxBoxSizer *create_item_region_combobox(wxString title, wxString tooltip);
wxBoxSizer *create_item_language_combobox(wxString title, wxString tooltip);
diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp
index 5006c5eab0..2e5f83c211 100644
--- a/src/slic3r/GUI/PresetComboBoxes.cpp
+++ b/src/slic3r/GUI/PresetComboBoxes.cpp
@@ -1132,6 +1132,7 @@ void PlaterPresetComboBox::update()
std::map preset_descriptions;
std::map preset_filament_vendors;
std::map preset_filament_types;
+ std::map preset_filament_names; // ORCA
//BBS: move system to the end
wxString selected_system_preset;
wxString selected_user_preset;
@@ -1174,7 +1175,8 @@ void PlaterPresetComboBox::update()
bitmap_key += single_bar ? filament_rgb : filament_rgb + extruder_rgb;
#endif
- if (preset.is_system) {
+ // ORCA allow caching vendor and type values for all presets instead just system ones
+ // if (preset.is_system) {
if (!preset.is_compatible && preset_filament_vendors.count(name) > 0)
continue;
else if (preset.is_compatible && preset_filament_vendors.count(name) > 0)
@@ -1183,7 +1185,8 @@ void PlaterPresetComboBox::update()
if (preset_filament_vendors[name] == "Bambu Lab")
preset_filament_vendors[name] = "Bambu";
preset_filament_types[name] = preset.config.option("filament_type")->values.at(0);
- }
+ preset_filament_names[name] = name.ToStdString(); // ORCA
+ //}
}
wxBitmap* bmp = get_bmp(preset);
assert(bmp);
@@ -1251,7 +1254,7 @@ void PlaterPresetComboBox::update()
"Bambu PLA Galaxy", "Bambu PLA Metal", "Bambu PLA Marble", "Bambu PETG-CF", "Bambu PETG Translucent", "Bambu ABS-GF"};
std::vector first_vendors = {"", "Bambu", "Generic"}; // Empty vendor for non-system presets
std::vector first_types = {"PLA", "PETG", "ABS", "TPU"};
- auto add_presets = [this, &preset_descriptions, &filament_orders, &preset_filament_vendors, &first_vendors, &preset_filament_types, &first_types, &selected_in_ams]
+ auto add_presets = [this, &preset_descriptions, &filament_orders, &preset_filament_vendors, &first_vendors, &preset_filament_types, &preset_filament_names, &first_types, &selected_in_ams]
(std::map const &presets, wxString const &selected, std::string const &group, wxString const &groupName) {
if (!presets.empty()) {
set_label_marker(Append(_L(group), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM));
@@ -1285,9 +1288,31 @@ void PlaterPresetComboBox::update()
}
return l->first < r->first;
});
+ // ORCA add sorting support for vendor / type for user presets. also non grouped items
+ if (groupName == "by_vendor" || groupName == "by_type" || groupName == ""){
+ auto by = groupName == "by_vendor" ? preset_filament_vendors
+ : groupName == "by_type" ? preset_filament_types
+ : preset_filament_names;
+ std::sort(list.begin(), list.end(), [&by](auto *l, auto *r) {
+ auto get_key = [&](auto* item) -> std::pair {
+ std::string str = by.count(item->first) ? by.at(item->first) : "";
+ std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::tolower(c);});
+ return {!str.empty(), str}; // is_valid, lower_case
+ };
+ auto [l_valid, l_lower] = get_key(l);
+ auto [r_valid, r_lower] = get_key(r);
+ return (l_valid != r_valid) ? l_valid > r_valid
+ : (l_lower != r_lower) ? l_lower < r_lower
+ : l->first < r->first;
+ });
+ }
bool unsupported = group == "Unsupported presets";
for (auto it : list) {
- auto groupName2 = groupByGroup ? groupName : preset_filament_vendors[it->first];
+ // ORCA add sorting support for vendor / type for user presets
+ auto groupName2 = groupName == "by_type" ? (preset_filament_types[it->first].empty() ? _L("Unspecified") : preset_filament_types[it->first])
+ : groupName == "by_vendor" ? (preset_filament_vendors[it->first].empty() ? _L("Unspecified") : preset_filament_vendors[it->first])
+ : groupByGroup ? groupName
+ : preset_filament_vendors[it->first];
int index = Append(it->first, *it->second, groupName2, nullptr, unsupported ? DD_ITEM_STYLE_DISABLED : 0);
if (unsupported)
set_label_marker(index, LABEL_ITEM_DISABLED);
@@ -1311,7 +1336,13 @@ void PlaterPresetComboBox::update()
//BBS: add project embedded preset logic
add_presets(project_embedded_presets, selected_user_preset, L("Project-inside presets"), _L("Project") + " ");
- add_presets(nonsys_presets, selected_user_preset, L("User presets"), _L("Custom") + " ");
+ // ORCA add sorting support for vendor / type for user presets
+ auto group_filament_presets = wxGetApp().app_config->get("group_filament_presets");
+ auto group_filament_presets_by = group_filament_presets == "0" ? (_L("Custom") + " ") // Append all to "Custom" sub menu
+ : group_filament_presets == "2" ? "by_type" // Create sub menus with filament type
+ : group_filament_presets == "3" ? "by_vendor" // Create sub menus with filament vendor
+ : ""; // Use without sub menu
+ add_presets(nonsys_presets, selected_user_preset, L("User presets"), group_filament_presets_by);
// BBS: move system to the end
add_presets(system_presets, selected_system_preset, L("System presets"), _L("System"));
add_presets(uncompatible_presets, {}, L("Unsupported presets"), _L("Unsupported") + " ");
diff --git a/src/slic3r/GUI/PrintOptionsDialog.cpp b/src/slic3r/GUI/PrintOptionsDialog.cpp
index 02329a36b7..56cc764356 100644
--- a/src/slic3r/GUI/PrintOptionsDialog.cpp
+++ b/src/slic3r/GUI/PrintOptionsDialog.cpp
@@ -1153,11 +1153,8 @@ PrinterPartsDialog::PrinterPartsDialog(wxWindow* parent)
change_nozzle_tips->SetFont(Label::Body_13);
change_nozzle_tips->SetForegroundColour(STATIC_TEXT_CAPTION_COL);
- m_wiki_link = new Label(single_panel, _L("View wiki"));
+ m_wiki_link = new HyperLink(single_panel, _L("Wiki Guide")); // ORCA
m_wiki_link->SetFont(Label::Body_13);
- m_wiki_link->SetForegroundColour(wxColour("#009688"));
- m_wiki_link->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_HAND); });
- m_wiki_link->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_ARROW); });
m_wiki_link->Bind(wxEVT_LEFT_DOWN, &PrinterPartsDialog::OnWikiClicked, this);
h_tips_sizer->Add(change_nozzle_tips, 0, wxLEFT);
@@ -1267,11 +1264,8 @@ PrinterPartsDialog::PrinterPartsDialog(wxWindow* parent)
multiple_change_nozzle_tips->SetFont(Label::Body_13);
multiple_change_nozzle_tips->SetForegroundColour(STATIC_TEXT_CAPTION_COL);
- multiple_wiki_link = new Label(multiple_panel, _L("View wiki"));
+ multiple_wiki_link = new HyperLink(multiple_panel, _L("Wiki Guide")); // ORCA
multiple_wiki_link->SetFont(Label::Body_13);
- multiple_wiki_link->SetForegroundColour(wxColour("#009688"));
- multiple_wiki_link->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_HAND); });
- multiple_wiki_link->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_ARROW); });
multiple_wiki_link->Bind(wxEVT_LEFT_DOWN, &PrinterPartsDialog::OnWikiClicked, this);
wxSizer* multiple_change_tips_sizer = new wxBoxSizer(wxHORIZONTAL);
diff --git a/src/slic3r/GUI/PrintOptionsDialog.hpp b/src/slic3r/GUI/PrintOptionsDialog.hpp
index d555c8237b..9918cfb80e 100644
--- a/src/slic3r/GUI/PrintOptionsDialog.hpp
+++ b/src/slic3r/GUI/PrintOptionsDialog.hpp
@@ -16,6 +16,7 @@
#include "Widgets/CheckBox.hpp"
#include "Widgets/StaticLine.hpp"
#include "Widgets/ComboBox.hpp"
+#include "Widgets/HyperLink.hpp"
// Previous definitions
class SwitchBoard;
@@ -33,7 +34,7 @@ protected:
Label* nozzle_flow_type_label;
ComboBox* nozzle_flow_type_checkbox;
Label *change_nozzle_tips;
- Label* m_wiki_link;
+ HyperLink* m_wiki_link;
Button* m_single_update_nozzle_button;
Button* m_multiple_update_nozzle_button;
@@ -46,7 +47,7 @@ protected:
ComboBox *multiple_right_nozzle_flow_checkbox;
Label *multiple_change_nozzle_tips;
- Label* multiple_wiki_link;
+ HyperLink* multiple_wiki_link;
wxPanel *single_panel;
wxPanel *multiple_panel;
diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp
index 2dd0a7baf2..9b156c5228 100644
--- a/src/slic3r/GUI/ReleaseNote.cpp
+++ b/src/slic3r/GUI/ReleaseNote.cpp
@@ -1510,7 +1510,8 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow *parent)
m_tip4->SetMinSize(wxSize(FromDIP(355), -1));
m_tip4->SetMaxSize(wxSize(FromDIP(355), -1));
- m_trouble_shoot = new wxHyperlinkCtrl(this, wxID_ANY, "How to trouble shooting", "");
+ // ORCA standardized HyperLink
+ m_trouble_shoot = new HyperLink(this, "How to trouble shooting");
m_img_help = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("input_access_code_x1_en", this, 198), wxDefaultPosition, wxSize(FromDIP(355), -1), 0);
diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp
index 838df0efd5..37b7c58935 100644
--- a/src/slic3r/GUI/ReleaseNote.hpp
+++ b/src/slic3r/GUI/ReleaseNote.hpp
@@ -326,7 +326,7 @@ public:
wxStaticBitmap* m_img_step1{ nullptr };
wxStaticBitmap* m_img_step2{ nullptr };
wxStaticBitmap* m_img_step3{ nullptr };
- wxHyperlinkCtrl* m_trouble_shoot{ nullptr };
+ HyperLink* m_trouble_shoot{ nullptr }; // ORCA
wxTimer* closeTimer{ nullptr };
int closeCount{3};
bool m_show_access_code{ false };
diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp
index 56ecd56ce2..eeb472e98a 100644
--- a/src/slic3r/GUI/SelectMachine.cpp
+++ b/src/slic3r/GUI/SelectMachine.cpp
@@ -688,12 +688,9 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
sizer_extra_info->Add(st_title_extra_info_doc, 0, wxALL, 0);
sizer_extra_info->Add(m_st_txt_extra_info, 0, wxALL, 0);
-
- m_link_network_state = new wxHyperlinkCtrl(m_sw_print_failed_info, wxID_ANY,_L("Check the status of current system services"),"");
+ // ORCA standardized HyperLink
+ m_link_network_state = new HyperLink(m_sw_print_failed_info, _L("Check the status of current system services"), wxGetApp().link_to_network_check());
m_link_network_state->SetFont(::Label::Body_12);
- m_link_network_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check();});
- m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND);});
- m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW);});
sizer_print_failed_info->Add(m_link_network_state, 0, wxLEFT, 5);
sizer_print_failed_info->Add(sizer_error_code, 0, wxLEFT, 5);
diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp
index 42bf251b7c..302b37b553 100644
--- a/src/slic3r/GUI/SelectMachine.hpp
+++ b/src/slic3r/GUI/SelectMachine.hpp
@@ -42,6 +42,7 @@
#include "Widgets/ComboBox.hpp"
#include "Widgets/ScrolledWindow.hpp"
#include "Widgets/PopupWindow.hpp"
+#include "Widgets/HyperLink.hpp" // ORCA
#include
#include
@@ -371,7 +372,7 @@ protected:
Label* m_st_txt_error_desc{nullptr};
Label* m_st_txt_extra_info{nullptr};
Label* m_ams_backup_tip{nullptr};
- wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ HyperLink* m_link_network_state{ nullptr }; // ORCA
wxSimplebook* m_rename_switch_panel{nullptr};
wxSimplebook* m_simplebook{nullptr};
wxStaticText* m_rename_text{nullptr};
diff --git a/src/slic3r/GUI/SelectMachinePop.cpp b/src/slic3r/GUI/SelectMachinePop.cpp
index aef994d067..ddca6df8a7 100644
--- a/src/slic3r/GUI/SelectMachinePop.cpp
+++ b/src/slic3r/GUI/SelectMachinePop.cpp
@@ -596,8 +596,9 @@ void SelectMachinePopup::update_other_devices()
m_placeholder_panel = new wxWindow(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(-1,FromDIP(26)));
wxBoxSizer* placeholder_sizer = new wxBoxSizer(wxVERTICAL);
- m_hyperlink = new wxHyperlinkCtrl(m_placeholder_panel, wxID_ANY, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
- m_hyperlink->SetNormalColour(StateColor::darkModeColorFor("#009789"));
+ // ORCA standardized HyperLink
+ m_hyperlink = new HyperLink(m_placeholder_panel, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"));
+ m_hyperlink->SetFont(::Label::Body_12);
placeholder_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
diff --git a/src/slic3r/GUI/SelectMachinePop.hpp b/src/slic3r/GUI/SelectMachinePop.hpp
index d1a34f9b3a..757cb08ed5 100644
--- a/src/slic3r/GUI/SelectMachinePop.hpp
+++ b/src/slic3r/GUI/SelectMachinePop.hpp
@@ -180,7 +180,7 @@ private:
PinCodePanel* m_panel_ping_code{nullptr};
PinCodePanel* m_panel_direct_connection{nullptr};
wxWindow* m_placeholder_panel{nullptr};
- wxHyperlinkCtrl* m_hyperlink{nullptr};
+ HyperLink* m_hyperlink{nullptr}; // ORCA
Label* m_ping_code_text{nullptr};
wxStaticBitmap* m_img_ping_code{nullptr};
wxBoxSizer * m_sizer_body{nullptr};
diff --git a/src/slic3r/GUI/SendMultiMachinePage.cpp b/src/slic3r/GUI/SendMultiMachinePage.cpp
index 1060dc253c..3578e4047c 100644
--- a/src/slic3r/GUI/SendMultiMachinePage.cpp
+++ b/src/slic3r/GUI/SendMultiMachinePage.cpp
@@ -801,7 +801,7 @@ bool SendMultiMachinePage::Show(bool show)
m_refresh_timer->Stop();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(4000);
- wxPostEvent(this, wxTimerEvent());
+ wxPostEvent(this, wxTimerEvent(*m_refresh_timer));
}
else {
m_refresh_timer->Stop();
diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp
index 5f5cf9925e..670a8bcad4 100644
--- a/src/slic3r/GUI/SendToPrinter.cpp
+++ b/src/slic3r/GUI/SendToPrinter.cpp
@@ -446,11 +446,9 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater)
sizer_extra_info->Add(st_title_extra_info_doc, 0, wxALL, 0);
sizer_extra_info->Add(m_st_txt_extra_info, 0, wxALL, 0);
- m_link_network_state = new wxHyperlinkCtrl(m_sw_print_failed_info, wxID_ANY,_L("Check the status of current system services"),"");
+ // ORCA standardized HyperLink
+ m_link_network_state = new HyperLink(m_sw_print_failed_info, _L("Check the status of current system services"), wxGetApp().link_to_network_check());
m_link_network_state->SetFont(::Label::Body_12);
- m_link_network_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); });
- m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND); });
- m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW); });
sizer_print_failed_info->Add(m_link_network_state, 0, wxLEFT, 5);
sizer_print_failed_info->Add(sizer_error_code, 0, wxLEFT, 5);
diff --git a/src/slic3r/GUI/SendToPrinter.hpp b/src/slic3r/GUI/SendToPrinter.hpp
index de284e31d6..14493a1f20 100644
--- a/src/slic3r/GUI/SendToPrinter.hpp
+++ b/src/slic3r/GUI/SendToPrinter.hpp
@@ -110,7 +110,7 @@ private:
Label* m_st_txt_error_code{ nullptr };
Label* m_st_txt_error_desc{ nullptr };
Label* m_st_txt_extra_info{ nullptr };
- wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ HyperLink* m_link_network_state{ nullptr };
StateColor btn_bg_enable;
wxBoxSizer* rename_sizer_v{ nullptr };
wxBoxSizer* rename_sizer_h{ nullptr };
diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp
index dc717aca39..8a85e556de 100644
--- a/src/slic3r/GUI/StatusPanel.cpp
+++ b/src/slic3r/GUI/StatusPanel.cpp
@@ -2503,6 +2503,8 @@ StatusPanel::~StatusPanel()
void StatusPanel::init_scaled_buttons()
{
+ if (!m_project_task_panel) return;
+
m_project_task_panel->init_scaled_buttons();
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_10->SetCornerRadius(0);
diff --git a/src/slic3r/GUI/StepMeshDialog.cpp b/src/slic3r/GUI/StepMeshDialog.cpp
index db281a8ebf..196c0ff8e0 100644
--- a/src/slic3r/GUI/StepMeshDialog.cpp
+++ b/src/slic3r/GUI/StepMeshDialog.cpp
@@ -117,14 +117,11 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, Slic3r::Step& file, double line
wxBoxSizer* tips_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText* info = new wxStaticText(this, wxID_ANY, _L("Smaller linear and angular deflections result in higher-quality transformations but increase the processing time."));
info->SetForegroundColour(StateColor::darkModeColorFor(FONT_COLOR));
- wxStaticText *tips = new wxStaticText(this, wxID_ANY, _L("View Wiki for more information"));
- wxFont font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false);
- font.SetUnderlined(true);
- tips->SetForegroundColour(StateColor::darkModeColorFor(wxColour(0, 151, 137)));
- tips->SetFont(font);
- tips->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
- wxLaunchDefaultBrowser("https://github.com/OrcaSlicer/OrcaSlicer/wiki/stl-transformation");
- });
+
+ // ORCA standardized HyperLink
+ HyperLink *tips = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/stl-transformation");
+ tips->SetFont(::Label::Body_12);
+
info->Wrap(FromDIP(400));
tips_sizer->Add(info, 0, wxALIGN_LEFT);
tips_sizer->Add(tips, 0, wxALIGN_LEFT);
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index fd8ede92d2..d4d31a3573 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -2663,6 +2663,7 @@ void TabPrint::build()
optgroup->append_single_option_line("brim_type", "others_settings_brim#type");
optgroup->append_single_option_line("brim_width", "others_settings_brim#width");
optgroup->append_single_option_line("brim_object_gap", "others_settings_brim#brim-object-gap");
+ optgroup->append_single_option_line("brim_use_efc_outline", "others_settings_brim#brim-use-efc-outline");
optgroup->append_single_option_line("brim_ears_max_angle", "others_settings_brim#ear-max-angle");
optgroup->append_single_option_line("brim_ears_detection_length", "others_settings_brim#ear-detection-radius");
diff --git a/src/slic3r/GUI/Tabbook.cpp b/src/slic3r/GUI/Tabbook.cpp
index ce26f3c658..db8cd3ba10 100644
--- a/src/slic3r/GUI/Tabbook.cpp
+++ b/src/slic3r/GUI/Tabbook.cpp
@@ -197,6 +197,20 @@ void TabButtonsListCtrl::SetPaddingSize(const wxSize& size) {
}
}
+void TabButtonsListCtrl::SetFooterText(const wxString& text)
+{
+ if (!m_footer_text) {
+ m_footer_text = new wxStaticText(this, wxID_ANY, text);
+ m_footer_text->SetForegroundColour(wxColour(128, 128, 128));
+ m_footer_text->SetFont(Label::Body_10);
+ int em = em_unit(this);
+ m_sizer->Add(m_footer_text, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, em / 2);
+ } else {
+ m_footer_text->SetLabel(text);
+ }
+ m_sizer->Layout();
+}
+
//#endif // _WIN32
diff --git a/src/slic3r/GUI/Tabbook.hpp b/src/slic3r/GUI/Tabbook.hpp
index 7dd19389de..0cea1b8326 100644
--- a/src/slic3r/GUI/Tabbook.hpp
+++ b/src/slic3r/GUI/Tabbook.hpp
@@ -32,6 +32,7 @@ public:
wxString GetPageText(size_t n) const;
const wxSize& GetPaddingSize(size_t n);
void SetPaddingSize(const wxSize& size);
+ void SetFooterText(const wxString& text);
TabButton* pageButton;
private:
@@ -43,6 +44,7 @@ private:
int m_selection {-1};
int m_btn_margin;
int m_line_margin;
+ wxStaticText* m_footer_text {nullptr};
};
class Tabbook: public wxBookCtrlBase
@@ -261,6 +263,11 @@ public:
GetBtnsListCtrl()->Rescale();
}
+ void SetFooterText(const wxString& text)
+ {
+ GetBtnsListCtrl()->SetFooterText(text);
+ }
+
void OnNavigationKey(wxNavigationKeyEvent& event)
{
if (event.IsWindowChange()) {
diff --git a/src/slic3r/GUI/WebUserLoginDialog.cpp b/src/slic3r/GUI/WebUserLoginDialog.cpp
index fba6547f65..2522efbf4f 100644
--- a/src/slic3r/GUI/WebUserLoginDialog.cpp
+++ b/src/slic3r/GUI/WebUserLoginDialog.cpp
@@ -25,6 +25,7 @@
#include
#include
+#include // ORCA
using namespace std;
using namespace nlohmann;
@@ -57,11 +58,12 @@ ZUserLogin::ZUserLogin() : wxDialog((wxWindow *) (wxGetApp().mainframe), wxID_AN
m_message->SetForegroundColour(*wxBLACK);
m_message->Wrap(FromDIP(360));
- auto m_download_hyperlink = new wxHyperlinkCtrl(this, wxID_ANY, _L("Click here to download it."), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
- m_download_hyperlink->Bind(wxEVT_HYPERLINK, [this](wxCommandEvent& event) {
+ // ORCA standardized HyperLink
+ auto m_download_hyperlink = new HyperLink(this, _L("Click here to download it."));
+ m_download_hyperlink->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& event) {
this->Close();
wxGetApp().ShowDownNetPluginDlg();
- });
+ });
m_sizer_main->Add(m_message, 0, wxALIGN_CENTER | wxALL, FromDIP(15));
m_sizer_main->Add(m_download_hyperlink, 0, wxALIGN_CENTER | wxALL, FromDIP(10));
m_sizer_main->Add(0, 0, 1, wxBOTTOM, 10);
diff --git a/src/slic3r/GUI/Widgets/HyperLink.cpp b/src/slic3r/GUI/Widgets/HyperLink.cpp
new file mode 100644
index 0000000000..7fdb236199
--- /dev/null
+++ b/src/slic3r/GUI/Widgets/HyperLink.cpp
@@ -0,0 +1,49 @@
+#include "HyperLink.hpp"
+#include "Label.hpp"
+
+namespace Slic3r { namespace GUI {
+
+HyperLink::HyperLink(wxWindow* parent, const wxString& label, const wxString& url, long style)
+ : wxStaticText(parent, wxID_ANY, label)
+ , m_url(url)
+ , m_normalColor(wxColour("#009687")) // used slightly different color otherwise automatically uses ColorForDark that not visible enough
+ , m_hoverColor(wxColour("#26A69A"))
+{
+ SetForegroundColour(m_normalColor);
+ HyperLink::SetFont(Label::Head_14);
+ SetCursor(wxCursor(wxCURSOR_HAND));
+
+ if (!m_url.IsEmpty())
+ SetToolTip(m_url);
+
+ Bind(wxEVT_LEFT_DOWN, ([this](wxMouseEvent& e) {
+ if (!m_url.IsEmpty())
+ wxLaunchDefaultBrowser(m_url);
+ }));
+
+ Bind(wxEVT_ENTER_WINDOW, ([this](wxMouseEvent& e) {
+ SetForegroundColour(m_hoverColor);
+ Refresh();
+ }));
+ Bind(wxEVT_LEAVE_WINDOW, ([this](wxMouseEvent& e) {
+ SetForegroundColour(m_normalColor);
+ Refresh();
+ }));
+}
+
+bool HyperLink::SetFont(const wxFont& font)
+{ // ensure it stays underlined
+ wxFont f = font;
+ f.SetUnderlined(true);
+ return wxStaticText::SetFont(f);
+}
+
+void HyperLink::SetURL(const wxString& url)
+{
+ m_url = url;
+ SetToolTip(m_url);
+}
+
+wxString HyperLink::GetURL() const { return m_url; }
+
+}} // namespace Slic3r::GUI
diff --git a/src/slic3r/GUI/Widgets/HyperLink.hpp b/src/slic3r/GUI/Widgets/HyperLink.hpp
new file mode 100644
index 0000000000..48e2245e3b
--- /dev/null
+++ b/src/slic3r/GUI/Widgets/HyperLink.hpp
@@ -0,0 +1,26 @@
+#ifndef slic3r_GUI_HyperLink_hpp_
+#define slic3r_GUI_HyperLink_hpp_
+
+#include
+#include
+
+namespace Slic3r { namespace GUI {
+
+class HyperLink : public wxStaticText
+{
+public:
+ HyperLink(wxWindow* parent, const wxString& label = wxEmptyString, const wxString& url = wxEmptyString, const long style = 0);
+
+ void SetURL(const wxString& url);
+ wxString GetURL() const;
+
+ bool SetFont(const wxFont& font);
+
+private:
+ wxString m_url;
+ wxColour m_normalColor;
+ wxColour m_hoverColor;
+};
+
+}} // namespace Slic3r::GUI
+#endif // !slic3r_GUI_HyperLink_hpp_
diff --git a/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp b/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp
index 93e4596aa5..c8e054593f 100644
--- a/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp
+++ b/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp
@@ -160,7 +160,7 @@ void LabeledStaticBox::DrawBorderAndLabel(wxDC& dc)
wxSize wSz = GetSize();
dc.SetBrush(*wxTRANSPARENT_BRUSH);
- dc.SetPen(wxPen(border_color.colorForStates(state_handler.states()), m_border_width, wxSOLID));
+ dc.SetPen(wxPen(border_color.colorForStates(state_handler.states()), m_border_width, wxPENSTYLE_SOLID));
dc.DrawRoundedRectangle( // Border
std::max(0, m_pos.x),
std::max(0, m_pos.y) + m_label_height * .5,
diff --git a/src/slic3r/GUI/Widgets/SideTools.cpp b/src/slic3r/GUI/Widgets/SideTools.cpp
index 4288647e53..377253e707 100644
--- a/src/slic3r/GUI/Widgets/SideTools.cpp
+++ b/src/slic3r/GUI/Widgets/SideTools.cpp
@@ -274,8 +274,8 @@ SideTools::SideTools(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
wxBoxSizer* connection_sizer_V = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* connection_sizer_H = new wxBoxSizer(wxHORIZONTAL);
- m_hyperlink = new wxHyperlinkCtrl(m_connection_info, wxID_ANY, _L("Failed to connect to the server"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
- m_hyperlink->SetBackgroundColour(wxColour(255, 111, 0));
+ // ORCA standardized HyperLink
+ m_hyperlink = new HyperLink(m_connection_info, _L("Failed to connect to the server"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"));
m_more_err_open = ScalableBitmap(this, "monitir_err_open", 16);
m_more_err_close = ScalableBitmap(this, "monitir_err_close", 16);
@@ -328,13 +328,10 @@ SideTools::SideTools(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
wxBoxSizer* sizer_error_desc = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_extra_info = new wxBoxSizer(wxHORIZONTAL);
- m_link_network_state = new wxHyperlinkCtrl(m_side_error_panel, wxID_ANY,_L("Check the status of current system services"),"",wxDefaultPosition,wxDefaultSize, wxHL_ALIGN_CENTRE |wxST_ELLIPSIZE_END);
- m_link_network_state->SetMinSize(wxSize(FromDIP(220), -1));
+ // ORCA standardized HyperLink
+ m_link_network_state = new HyperLink(m_side_error_panel, _L("Check the status of current system services"), wxGetApp().link_to_network_check(), wxST_ELLIPSIZE_END);
m_link_network_state->SetMaxSize(wxSize(FromDIP(220), -1));
m_link_network_state->SetFont(::Label::Body_12);
- m_link_network_state->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {wxGetApp().link_to_network_check(); });
- m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND); });
- m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW); });
auto st_title_error_code = new wxStaticText(m_side_error_panel, wxID_ANY, _L("code"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
auto st_title_error_code_doc = new wxStaticText(m_side_error_panel, wxID_ANY, ": ");
diff --git a/src/slic3r/GUI/Widgets/SideTools.hpp b/src/slic3r/GUI/Widgets/SideTools.hpp
index 4f1cf7c667..24cbae4fd2 100644
--- a/src/slic3r/GUI/Widgets/SideTools.hpp
+++ b/src/slic3r/GUI/Widgets/SideTools.hpp
@@ -4,9 +4,9 @@
#include
#include
#include
-#include
#include "Button.hpp"
#include "Label.hpp"
+#include "HyperLink.hpp" // ORCA
#include "../GUI/Tabbook.hpp"
#include "../DeviceManager.hpp"
#include "../wxExtensions.hpp"
@@ -99,13 +99,13 @@ public:
private:
SideToolsPanel* m_side_tools{ nullptr };
Tabbook* m_tabpanel{ nullptr };
- wxHyperlinkCtrl* m_link_network_state{ nullptr };
+ HyperLink* m_link_network_state{ nullptr }; // ORCA
Label* m_st_txt_error_code{ nullptr };
Label* m_st_txt_error_desc{ nullptr };
Label* m_st_txt_extra_info{ nullptr };
wxWindow* m_side_error_panel{ nullptr };
Button* m_connection_info{ nullptr };
- wxHyperlinkCtrl* m_hyperlink{ nullptr };
+ HyperLink* m_hyperlink{ nullptr }; // ORCA
ScalableButton* m_more_button{ nullptr };
ScalableBitmap m_more_err_open;
ScalableBitmap m_more_err_close;
diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp
index 24eb46b4a5..79735f6901 100644
--- a/src/slic3r/GUI/calib_dlg.cpp
+++ b/src/slic3r/GUI/calib_dlg.cpp
@@ -5,6 +5,7 @@
#include
#include "MainFrame.hpp"
#include "Widgets/DialogButtons.hpp"
+#include "Widgets/HyperLink.hpp"
#include
#include
#include "libslic3r/PrintConfig.hpp"
@@ -173,22 +174,14 @@ PA_Calibration_Dlg::PA_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plater*
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- // Help links
- auto help_sizer = new wxBoxSizer(wxVERTICAL);
- auto help_link_pa = new wxHyperlinkCtrl(this, wxID_ANY, _L("Pressure Advance Guide"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/pressure-advance-calib");
- help_link_pa->SetForegroundColour(wxColour("#1890FF"));
- help_sizer->Add(help_link_pa, 0, wxALL, FromDIP(5));
-
- auto help_link_apa = new wxHyperlinkCtrl(this, wxID_ANY, _L("Adaptive Pressure Advance Guide"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/adaptive-pressure-advance-calib");
- help_link_apa->SetForegroundColour(wxColour("#1890FF"));
- help_sizer->Add(help_link_apa, 0, wxALL, FromDIP(5));
-
- v_sizer->Add(help_sizer, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/pressure-advance-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &PA_Calibration_Dlg::on_start, this);
@@ -399,13 +392,14 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Temperature Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/temp-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/temp-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Temp_Calibration_Dlg::on_start, this);
@@ -578,13 +572,14 @@ MaxVolumetricSpeed_Test_Dlg::MaxVolumetricSpeed_Test_Dlg(wxWindow* parent, wxWin
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Volumetric Speed Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/volumetric-speed-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/volumetric-speed-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &MaxVolumetricSpeed_Test_Dlg::on_start, this);
@@ -684,13 +679,14 @@ VFA_Test_Dlg::VFA_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater)
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: VFA"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/vfa-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/vfa-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &VFA_Test_Dlg::on_start, this);
@@ -791,13 +787,14 @@ Retraction_Test_Dlg::Retraction_Test_Dlg(wxWindow* parent, wxWindowID id, Plater
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Retraction Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/retraction-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/retraction-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Retraction_Test_Dlg::on_start, this);
@@ -968,13 +965,14 @@ Input_Shaping_Freq_Test_Dlg::Input_Shaping_Freq_Test_Dlg(wxWindow* parent, wxWin
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Input Shaping Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/input-shaping-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/input-shaping-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Input_Shaping_Freq_Test_Dlg::on_start, this);
@@ -1165,13 +1163,14 @@ Input_Shaping_Damp_Test_Dlg::Input_Shaping_Damp_Test_Dlg(wxWindow* parent, wxWin
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Input Shaping Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/input-shaping-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/input-shaping-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Input_Shaping_Damp_Test_Dlg::on_start, this);
@@ -1356,13 +1355,14 @@ Cornering_Test_Dlg::Cornering_Test_Dlg(wxWindow* parent, wxWindowID id, Plater*
v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10));
v_sizer->AddSpacer(FromDIP(5));
- auto help_link = new wxHyperlinkCtrl(this, wxID_ANY, _L("Wiki Guide: Cornering Calibration"),
- "https://github.com/OrcaSlicer/OrcaSlicer/wiki/cornering-calib");
- help_link->SetForegroundColour(wxColour("#1890FF"));
- v_sizer->Add(help_link, 0, wxALL, FromDIP(10));
-
auto dlg_btns = new DialogButtons(this, {"OK"});
- v_sizer->Add(dlg_btns , 0, wxEXPAND);
+
+ auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto wiki = new HyperLink(this, _L("Wiki Guide"), "https://www.orcaslicer.com/wiki/cornering-calib");
+ bottom_sizer->Add(wiki, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
+ bottom_sizer->AddStretchSpacer();
+ bottom_sizer->Add(dlg_btns, 0, wxEXPAND);
+ v_sizer->Add(bottom_sizer, 0, wxEXPAND);
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Cornering_Test_Dlg::on_start, this);
diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp
index 5f19e8f4e2..8220105f10 100644
--- a/src/slic3r/Utils/NetworkAgent.cpp
+++ b/src/slic3r/Utils/NetworkAgent.cpp
@@ -1,5 +1,7 @@
#include
#include
+#include