Compare commits
145 Commits
feature/te
...
ci-skip-ar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
895a5c8d6b | ||
|
|
33909a51cd | ||
|
|
979e56f1d0 | ||
|
|
f7145c9b37 | ||
|
|
a4d69962fc | ||
|
|
671277b381 | ||
|
|
6d1974a662 | ||
|
|
5e7ad1ad70 | ||
|
|
8d8e4c2835 | ||
|
|
e5106a23b6 | ||
|
|
c7558e978b | ||
|
|
a34310cbda | ||
|
|
0849c44ae0 | ||
|
|
d500ba4e9e | ||
|
|
f626382209 | ||
|
|
be165c97de | ||
|
|
84fa8d31f5 | ||
|
|
8ac478be26 | ||
|
|
691fd5892d | ||
|
|
d55e7834c8 | ||
|
|
1889ffb22a | ||
|
|
c84d5c7943 | ||
|
|
c3f78723fb | ||
|
|
f1fd49c12f | ||
|
|
50768e0716 | ||
|
|
0545750c1b | ||
|
|
591d1ac948 | ||
|
|
28bb05ac83 | ||
|
|
8fe7a33ae6 | ||
|
|
3c0338f462 | ||
|
|
246f2d32bf | ||
|
|
25216998b3 | ||
|
|
74813b401f | ||
|
|
df1e114b72 | ||
|
|
56f672ecbd | ||
|
|
9aa90fa6a8 | ||
|
|
ec96ca17b8 | ||
|
|
174f043f67 | ||
|
|
3395d87240 | ||
|
|
32216dc931 | ||
|
|
2268544a68 | ||
|
|
c41e685a69 | ||
|
|
35ffe49b17 | ||
|
|
88262ee504 | ||
|
|
4eb9a85a49 | ||
|
|
5a53d2eb88 | ||
|
|
49282858a4 | ||
|
|
72005959d4 | ||
|
|
113d488e6f | ||
|
|
64a321528d | ||
|
|
6a254c35d4 | ||
|
|
79aa0bd4a2 | ||
|
|
78692aa08f | ||
|
|
30aa7d9557 | ||
|
|
2fecfc291f | ||
|
|
b1e64dc69c | ||
|
|
3ae7bd04fa | ||
|
|
7e2047aa30 | ||
|
|
c4ea86041b | ||
|
|
bfbf591613 | ||
|
|
e98750e713 | ||
|
|
3ebd68d959 | ||
|
|
582017235c | ||
|
|
abbd420f2a | ||
|
|
c8db06b1d4 | ||
|
|
e1c0ea0cc4 | ||
|
|
780b2f1ebe | ||
|
|
c65b0540a3 | ||
|
|
93d5b65852 | ||
|
|
e717dea94b | ||
|
|
22e121f4e4 | ||
|
|
f5418415ac | ||
|
|
dacf26b06f | ||
|
|
4b7182b048 | ||
|
|
75c8d0775a | ||
|
|
21b46044d0 | ||
|
|
03a704df7c | ||
|
|
18b9279c26 | ||
|
|
13cd8d4864 | ||
|
|
7c8d086d9e | ||
|
|
c528d3a0bc | ||
|
|
83d2d4179d | ||
|
|
826e36fb1e | ||
|
|
b12aad6a8c | ||
|
|
93a81179a1 | ||
|
|
e56cdd707f | ||
|
|
b2eeed2622 | ||
|
|
9e8ac03476 | ||
|
|
b58dcf5978 | ||
|
|
79d51b31b5 | ||
|
|
00816968a2 | ||
|
|
05ed2e4dfa | ||
|
|
844c374798 | ||
|
|
f688a3e741 | ||
|
|
0d31325df0 | ||
|
|
6fda82476d | ||
|
|
26a0caff96 | ||
|
|
2194037d16 | ||
|
|
7d17400443 | ||
|
|
bc6ffcfb31 | ||
|
|
378843a4da | ||
|
|
20a66fa99b | ||
|
|
da149ee75a | ||
|
|
9810397546 | ||
|
|
28b7127150 | ||
|
|
a098b483f6 | ||
|
|
15412cd812 | ||
|
|
237ef41b06 | ||
|
|
781ecdc2c1 | ||
|
|
b58025575d | ||
|
|
b37fa41742 | ||
|
|
dec67345be | ||
|
|
cf86f20ae1 | ||
|
|
cab62070b5 | ||
|
|
12b63ebe36 | ||
|
|
40fd225308 | ||
|
|
696a94a1a6 | ||
|
|
7f67946dbf | ||
|
|
4227a192cd | ||
|
|
ae5d9c26fb | ||
|
|
c2f5a87e24 | ||
|
|
1b93f35565 | ||
|
|
f58a1f350a | ||
|
|
922af972c7 | ||
|
|
f713c7ae49 | ||
|
|
0e20f60712 | ||
|
|
23799e0210 | ||
|
|
668654da5f | ||
|
|
2524669139 | ||
|
|
044a113d54 | ||
|
|
b2827cb9fa | ||
|
|
08b08e09fc | ||
|
|
62e5cfed36 | ||
|
|
b2298855b0 | ||
|
|
ec913eaf30 | ||
|
|
22d9765348 | ||
|
|
dd5b755f60 | ||
|
|
9ee7e9aba4 | ||
|
|
1adfb5f242 | ||
|
|
c88535ce9e | ||
|
|
272e88a337 | ||
|
|
c983f60d00 | ||
|
|
e0d80ee953 | ||
|
|
885f14ed65 | ||
|
|
5b64e49c53 |
139
.github/workflows/build_all.yml
vendored
@@ -57,17 +57,13 @@ jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# Build both arches on every event (PRs included), through the same
|
||||
# build_check_cache -> build_deps -> build_orca chain (the AppImage).
|
||||
# aarch64 always uses the GitHub-hosted arm runner (there is no arm
|
||||
# self-hosted server). amd64's empty arch is load-bearing: it keeps the
|
||||
# historical 'linux-clang' deps cache key and the unsuffixed asset names.
|
||||
# SELF_HOSTED skips arm64 (no arm self-hosted server). amd64's empty arch
|
||||
# is load-bearing: it keeps the historical 'linux-clang' deps cache key and
|
||||
# the unsuffixed asset names.
|
||||
matrix:
|
||||
include:
|
||||
- arch: ""
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
|
||||
- arch: "aarch64"
|
||||
os: ubuntu-24.04-arm
|
||||
include: ${{ fromJSON(vars.SELF_HOSTED
|
||||
&& '[{"arch":"","os":"orca-lnx-server"}]'
|
||||
|| '[{"arch":"","os":"ubuntu-24.04"},{"arch":"aarch64","os":"ubuntu-24.04-arm"}]') }}
|
||||
# Don't run scheduled builds on forks:
|
||||
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
|
||||
uses: ./.github/workflows/build_check_cache.yml
|
||||
@@ -80,18 +76,16 @@ jobs:
|
||||
name: Build Windows ${{ matrix.arch }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# SELF_HOSTED skips arm64 (the self-hosted Windows server is x64-only).
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
os: windows-latest
|
||||
- arch: arm64
|
||||
os: windows-11-arm
|
||||
include: ${{ fromJSON(vars.SELF_HOSTED
|
||||
&& '[{"arch":"x64","os":"orca-win-server"}]'
|
||||
|| '[{"arch":"x64","os":"windows-latest"},{"arch":"arm64","os":"windows-11-arm"}]') }}
|
||||
# Don't run scheduled builds on forks:
|
||||
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
|
||||
uses: ./.github/workflows/build_check_cache.yml
|
||||
with:
|
||||
# Self-hosted runner is x64-only; ARM64 always uses the GitHub-hosted runner.
|
||||
os: ${{ (matrix.arch == 'x64' && vars.SELF_HOSTED) && 'orca-win-server' || matrix.os }}
|
||||
os: ${{ matrix.os }}
|
||||
arch: ${{ matrix.arch }}
|
||||
build-deps-only: ${{ inputs.build-deps-only || false }}
|
||||
force-build: ${{ github.event_name == 'schedule' }}
|
||||
@@ -122,54 +116,97 @@ jobs:
|
||||
arch: universal
|
||||
macos-combine-only: true
|
||||
secrets: inherit
|
||||
unit_tests:
|
||||
name: Unit Tests
|
||||
# Tests are built on the aarch64 leg by default (faster GitHub arm runner),
|
||||
# so run them there; self-hosted builds them on the amd64 server instead.
|
||||
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }}
|
||||
# One test job per built arch, on the runner that built it.
|
||||
unit_tests_linux_x86_64:
|
||||
name: Linux x86_64
|
||||
needs: build_linux
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
|
||||
artifact: ${{ github.sha }}-tests-linux-x86_64
|
||||
unit_tests_linux_aarch64:
|
||||
name: Linux aarch64
|
||||
needs: build_linux
|
||||
if: ${{ !cancelled() && success() && !vars.SELF_HOSTED }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ubuntu-24.04-arm
|
||||
artifact: ${{ github.sha }}-tests-linux-aarch64
|
||||
unit_tests_windows_x64:
|
||||
name: Windows x64
|
||||
needs: build_windows
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-win-server' || 'windows-latest' }}
|
||||
artifact: ${{ github.sha }}-tests-windows-x64
|
||||
unit_tests_windows_arm64:
|
||||
name: Windows arm64
|
||||
needs: build_windows
|
||||
if: ${{ !cancelled() && success() && !vars.SELF_HOSTED }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: windows-11-arm
|
||||
artifact: ${{ github.sha }}-tests-windows-arm64
|
||||
test-dir: build-arm64/tests
|
||||
unit_tests_macos_arm64:
|
||||
name: macOS arm64
|
||||
needs: build_macos_arch
|
||||
if: ${{ !cancelled() && success() }}
|
||||
uses: ./.github/workflows/unit_tests.yml
|
||||
with:
|
||||
os: ${{ vars.SELF_HOSTED && 'orca-macos-arm64' || 'macos-14' }}
|
||||
artifact: ${{ github.sha }}-tests-macos-arm64
|
||||
test-dir: build/arm64/tests
|
||||
# Slice a two-colour cube through every shipped printer so all custom g-code
|
||||
# (change_filament_gcode, machine start/end, etc.) is expanded - catches
|
||||
# slicing regressions the static profile checks and unit tests can't see.
|
||||
# Profile-only PRs are covered by check_profiles.yml's nightly binary; this
|
||||
# covers src/engine PRs with the PR-built binary.
|
||||
slice_check_linux:
|
||||
name: Slice check (Linux ${{ vars.SELF_HOSTED && 'x86_64' || 'aarch64' }})
|
||||
needs: build_linux
|
||||
if: ${{ !cancelled() && success() }}
|
||||
# Follows whichever Linux leg built the validator.
|
||||
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
scripts
|
||||
tests
|
||||
- name: Apt-Install Dependencies
|
||||
if: ${{ !vars.SELF_HOSTED }}
|
||||
uses: ./.github/actions/apt-install-deps
|
||||
- name: Restore Test Artifact
|
||||
- name: Download profile validator
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ github.sha }}-tests
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true # <--= Use the local cache (default is 'false').
|
||||
useCloudCache: true
|
||||
- name: Unpackage and Run Unit Tests
|
||||
timeout-minutes: 20
|
||||
name: ${{ github.sha }}-profile-validator-linux-${{ vars.SELF_HOSTED && 'x86_64' || 'aarch64' }}
|
||||
path: validator-bin
|
||||
- name: Validate slice (expand custom g-code)
|
||||
timeout-minutes: 60
|
||||
run: |
|
||||
tar -xvf build_tests.tar
|
||||
scripts/run_unit_tests.sh
|
||||
- name: Upload Test Logs
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ failure() }}
|
||||
chmod +x validator-bin/OrcaSlicer_profile_validator
|
||||
./validator-bin/OrcaSlicer_profile_validator -p "${{ github.workspace }}/resources/profiles" -s -l 2
|
||||
publish_test_results:
|
||||
name: Publish Test Results
|
||||
needs: [unit_tests_linux_x86_64, unit_tests_linux_aarch64, unit_tests_windows_x64, unit_tests_windows_arm64, unit_tests_macos_arm64]
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Test Results
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: unit-test-logs
|
||||
path: build/tests/**/*.log
|
||||
pattern: test-results-*
|
||||
path: test-results
|
||||
# Best-effort: a read-only token (e.g. fork PRs) can't write the check, so
|
||||
# don't let a publish failure fail the run. The test jobs gate correctness.
|
||||
- name: Publish Test Results
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||
with:
|
||||
files: "ctest_results.xml"
|
||||
- name: Delete Test Artifact
|
||||
files: "test-results/**/*.xml"
|
||||
- name: Delete Test Results
|
||||
if: success()
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: ${{ github.sha }}-tests
|
||||
name: test-results-*
|
||||
failOnError: false
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
container:
|
||||
|
||||
69
.github/workflows/build_orca.yml
vendored
@@ -141,8 +141,26 @@ jobs:
|
||||
- name: Build slicer mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only
|
||||
working-directory: ${{ github.workspace }}
|
||||
# arm64 only: build the tests here; the unit_tests_macos job runs them.
|
||||
env:
|
||||
ORCA_TESTS_BUILD_ONLY: ${{ inputs.arch == 'arm64' && '1' || '' }}
|
||||
run: |
|
||||
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15
|
||||
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 ${{ inputs.arch == 'arm64' && '-T' || '' }}
|
||||
|
||||
- name: Pack unit tests mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar -cvf build_tests.tar build/arm64/tests
|
||||
|
||||
- name: Upload Test Artifact mac
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests-macos-arm64
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Pack macOS app bundle ${{ inputs.arch }}
|
||||
if: runner.os == 'macOS' && !inputs.macos-combine-only
|
||||
@@ -335,11 +353,28 @@ jobs:
|
||||
# env:
|
||||
# WindowsSdkDir: 'C:\Program Files (x86)\Windows Kits\10\'
|
||||
# WindowsSDKVersion: '10.0.26100.0\'
|
||||
# "tests" builds the unit tests too; the unit_tests_windows_* jobs run them.
|
||||
run: |
|
||||
$arch = "${{ inputs.arch }}"
|
||||
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 } else { .\build_release_vs.bat slicer }
|
||||
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 tests } else { .\build_release_vs.bat slicer tests }
|
||||
shell: pwsh
|
||||
|
||||
- name: Pack unit tests Win
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ${{ github.workspace }}
|
||||
shell: pwsh
|
||||
run: tar -cvf build_tests.tar ${{ env.BUILD_DIR }}/tests
|
||||
|
||||
- name: Upload Test Artifact Win
|
||||
if: runner.os == 'Windows'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests-windows-${{ inputs.arch }}
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
# NSIS is x86-only; it runs (and the installer it emits runs) under ARM64's
|
||||
# x86 emulation, packaging the native arm64 payload from build-arm64.
|
||||
- name: Create installer Win
|
||||
@@ -452,31 +487,41 @@ jobs:
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
# Build + tar the unit tests (-t) only on the leg that runs them: the
|
||||
# aarch64 leg by default (faster GitHub arm runner), or amd64 when using
|
||||
# self-hosted runners (no arm self-hosted server). unit_tests downloads
|
||||
# this tarball. The profile validator is built with -s, so amd64 keeps it.
|
||||
tests=${{ (!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64') }}
|
||||
if $tests; then flags=-istrlL; else flags=-isrlL; fi
|
||||
./build_linux.sh "$flags"
|
||||
# Build + tar the unit tests (-t) on both Linux legs so each arch
|
||||
# (x86_64 + aarch64) gets tested by its own unit_tests_linux_* job.
|
||||
./build_linux.sh -istrlL
|
||||
./scripts/check_appimage_libs.sh ./build/package ./build/package/bin/orca-slicer
|
||||
appimage=./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
|
||||
mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage "$appimage"
|
||||
chmod +x "$appimage"
|
||||
if $tests; then tar -cvpf build_tests.tar build/tests; fi
|
||||
tar -cvf build_tests.tar build/tests
|
||||
|
||||
# Use tar because upload-artifacts won't always preserve directory structure
|
||||
# and doesn't preserve file permissions
|
||||
- name: Upload Test Artifact
|
||||
if: runner.os == 'Linux' && ((!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64'))
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-tests
|
||||
name: ${{ github.sha }}-tests-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }}
|
||||
overwrite: true
|
||||
path: build_tests.tar
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
# Ship the freshly-built validator so slice_check_linux (build_all.yml)
|
||||
# can slice-sweep the shipped profiles with this PR's engine. Taken from
|
||||
# the aarch64 leg so the sweep also exercises the arm build; x86_64 on
|
||||
# SELF_HOSTED, which skips arm64.
|
||||
- name: Upload profile validator (for slice check)
|
||||
if: ${{ runner.os == 'Linux' && (vars.SELF_HOSTED && inputs.arch != 'aarch64' || !vars.SELF_HOSTED && inputs.arch == 'aarch64') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ github.sha }}-profile-validator-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }}
|
||||
overwrite: true
|
||||
path: ./build/src/Release/OrcaSlicer_profile_validator
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Run external slicer regression tests
|
||||
if: runner.os == 'Linux' && inputs.arch != 'aarch64'
|
||||
timeout-minutes: 20
|
||||
|
||||
22
.github/workflows/check_profiles.yml
vendored
@@ -49,6 +49,15 @@ jobs:
|
||||
set +e
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 2>&1 | tee ${{ runner.temp }}/validate_system.log
|
||||
exit ${PIPESTATUS[0]}
|
||||
# Slice a two-colour cube through every printer so all custom g-code (incl. change_filament_gcode)
|
||||
# is expanded - catches undefined-placeholder / invalid-flow bugs the static checks above cannot see.
|
||||
- name: validate slice (expand custom g-code)
|
||||
id: validate_slice
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set +e
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -s -l 2 2>&1 | tee ${{ runner.temp }}/validate_slice.log
|
||||
exit ${PIPESTATUS[0]}
|
||||
# For now run filament subtype check only for BBL profiles until we fix other vendors' profiles.
|
||||
- name: validate filament subtype check for BBL profiles
|
||||
id: validate_filament_subtypes
|
||||
@@ -166,7 +175,7 @@ jobs:
|
||||
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
||||
|
||||
- name: Prepare comment artifact
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
{
|
||||
# Marker matched by check_profiles_comment.yml to delete prior comments.
|
||||
@@ -192,6 +201,15 @@ jobs:
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_slice.outcome }}" = "failure" ]; then
|
||||
echo "### Slice Validation Failed (custom g-code expansion)"
|
||||
echo ""
|
||||
echo '```'
|
||||
head -c 30000 ${{ runner.temp }}/validate_slice.log || echo "No output captured"
|
||||
echo '```'
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_filament_subtypes.outcome }}" = "failure" ]; then
|
||||
echo "### BBL Filament Subtype Validation Failed"
|
||||
echo ""
|
||||
@@ -223,7 +241,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: Fail if any check failed
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
echo "One or more profile checks failed. See above for details."
|
||||
exit 1
|
||||
|
||||
2
.github/workflows/dedupe-issues.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
with:
|
||||
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
claude_args: "--model claude-sonnet-4-5-20250929"
|
||||
model: "claude-sonnet-4-5-20250929"
|
||||
claude_env: |
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
86
.github/workflows/pr-label-bot.yml
vendored
@@ -79,6 +79,92 @@ jobs:
|
||||
throw error;
|
||||
}
|
||||
|
||||
localization-pr:
|
||||
if: github.event_name == 'pull_request_target'
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Auto-label and remind about the localization glossary
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
function isPermissionDenied(error) {
|
||||
return error && error.status === 403 && /Resource not accessible by integration/i.test(error.message || '');
|
||||
}
|
||||
|
||||
const pr = context.payload.pull_request;
|
||||
|
||||
// List changed files once (mirrors the `localization/**` paths filter in check_locale.yml)
|
||||
const files = await github.paginate(github.rest.pulls.listFiles, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number,
|
||||
per_page: 100
|
||||
});
|
||||
const touchesLocalization = files.some((file) => file.filename.startsWith('localization/'));
|
||||
const onlyPoFiles = files.length > 0 && files.every((file) => file.filename.endsWith('.po'));
|
||||
|
||||
// If the PR changes only .po files, automatically apply the Localization label
|
||||
if (onlyPoFiles) {
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: ['Localization']
|
||||
});
|
||||
core.info('Applied Localization label (PR changes only .po files).');
|
||||
} catch (error) {
|
||||
if (isPermissionDenied(error)) {
|
||||
core.warning('Cannot add Localization label because token cannot write.');
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!touchesLocalization) {
|
||||
core.info('No localization changes detected; skipping glossary reminder.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid posting the reminder twice (e.g. on reopen)
|
||||
const marker = '<!-- localization-glossary-reminder -->';
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
per_page: 100
|
||||
});
|
||||
if (comments.some((comment) => (comment.body || '').includes(marker))) {
|
||||
core.info('Glossary reminder already present; skipping.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
body:
|
||||
`${marker}\n` +
|
||||
`Hi @${pr.user.login}, this PR changes translations (\`localization/**\`).\n\n` +
|
||||
`Please make sure recurring terms follow the [Localization glossary](https://www.orcaslicer.com/wiki/localization_glossary), ` +
|
||||
`so the same English term is always rendered the same way within a language and terms that must stay in English ` +
|
||||
`(brand/product names, acronyms, file formats, G-code, macros/variables) are not translated.`
|
||||
});
|
||||
} catch (error) {
|
||||
if (isPermissionDenied(error)) {
|
||||
core.warning('Skipping glossary reminder because token cannot write comments.');
|
||||
return;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
apply-label:
|
||||
if: github.event_name == 'issue_comment'
|
||||
permissions:
|
||||
|
||||
77
.github/workflows/unit_tests.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: Unit Tests
|
||||
|
||||
# Download a platform's test artifact, run ctest, and upload the JUnit
|
||||
# results for aggregation. Called once per arch from build_all.yml.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
artifact:
|
||||
description: Test artifact uploaded by the build leg
|
||||
required: true
|
||||
type: string
|
||||
test-dir:
|
||||
description: Built tests dir; defaults to build/tests, override for arch-separated builds
|
||||
required: false
|
||||
type: string
|
||||
default: build/tests
|
||||
|
||||
jobs:
|
||||
unit_tests:
|
||||
# Static "Unit Tests"; the per-arch label is the caller's job name, so the
|
||||
# graph shows e.g. "Windows x64 / Unit Tests".
|
||||
name: Unit Tests
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
# Tests reach outside tests/ at runtime: tests/data (TEST_DATA_DIR) and
|
||||
# resources/profiles (PROFILES_DIR) by baked-in absolute path, plus
|
||||
# resources/info (nozzle data) via resources_dir() during a real slice.
|
||||
# Check out all of resources/ so no test hits a missing-file path.
|
||||
sparse-checkout: |
|
||||
.github
|
||||
scripts
|
||||
tests
|
||||
resources
|
||||
- name: Apt-Install Dependencies
|
||||
if: runner.os == 'Linux' && !vars.SELF_HOSTED
|
||||
uses: ./.github/actions/apt-install-deps
|
||||
- name: Restore Test Artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true
|
||||
useCloudCache: true
|
||||
- name: Unpackage and Run Unit Tests
|
||||
timeout-minutes: 20
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xvf build_tests.tar
|
||||
# Multi-config generators (Windows/macOS) need a config; Linux is single-config.
|
||||
scripts/run_unit_tests.sh "${{ inputs.test-dir }}" "${{ runner.os != 'Linux' && 'Release' || '' }}"
|
||||
- name: Upload Test Logs
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: unit-test-logs-${{ inputs.artifact }}
|
||||
path: ${{ inputs.test-dir }}/**/*.log
|
||||
- name: Upload Test Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: test-results-${{ inputs.artifact }}
|
||||
path: ctest_results.xml
|
||||
retention-days: 5
|
||||
if-no-files-found: warn
|
||||
- name: Delete Test Artifact
|
||||
if: success()
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
@@ -55,3 +55,11 @@ ctest --test-dir ./tests/fff_print
|
||||
- Add helper functions or utilities only when existing code cannot reasonably be reused. Avoid duplication.
|
||||
- Keep code concise and clear. Manually simplify AI generated bloated codes before review.
|
||||
- Include targeted tests or documented verification for behavior changes, especially in slicing logic, profiles, formats, and GUI defaults.
|
||||
- For translation changes (`localization/i18n/**/*.po`), check that recurring terms match the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) for that language.
|
||||
|
||||
## Localization & translations
|
||||
|
||||
- Translation catalogs live in `localization/i18n/<lang>/OrcaSlicer_<lang>.po`.
|
||||
- When creating or reviewing translations, use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language and terms that must stay in English (brand/product names, acronyms, file formats, G-code, macros/variables) are not translated.
|
||||
- If a term's established translation changes, update both the affected `.po` files and the glossary so they stay in sync.
|
||||
- Only edit `msgstr` (never `msgid`); keep placeholders (`%s`, `%1%`, `\n`), context (`msgctxt`), and file encoding/line endings intact.
|
||||
|
||||
@@ -1,604 +0,0 @@
|
||||
# Texture Displacement — Technical Notes
|
||||
|
||||
Branch: `feature/texture_displacement`. This document is a knowledge dump of the whole feature as
|
||||
it stands: architecture, file map, algorithms, known bugs found and fixed (with root causes worth
|
||||
remembering), and what's still deferred. Written so a fresh session (or a fresh pair of eyes) can
|
||||
pick this up without re-deriving everything from scratch.
|
||||
|
||||
## What it does
|
||||
|
||||
A paint-style gizmo (`GLGizmoTextureDisplacement`) that lets you:
|
||||
- Paint one or more "layers" onto a model's surface, each a height-map texture with its own
|
||||
depth/tiling/rotation/offset/invert/tile-mode/projection-mode/blend-mode.
|
||||
- Pick a texture from a shipped library (`resources/textures/displacement/`) or import your own
|
||||
(saved into `<data_dir>/textures/displacement/`, kept separate so app updates can't clobber it).
|
||||
- Combine overlapping layers with image-editor-style blend modes (Add/Subtract/Multiply/Divide).
|
||||
- Preview the true displaced result live, before baking (background job, not on the UI thread).
|
||||
- Optionally preview via a fast GPU bump-map shader instead (no real geometry movement, just
|
||||
shading) for a lighter-weight alternative.
|
||||
- Bake into real mesh geometry on demand, restricted to the painted area only.
|
||||
- Subdivide a low-poly model first so there are enough vertices to show fine detail.
|
||||
- Unwrap a painted patch with a real CGAL LSCM parameterization and view it in a dedicated,
|
||||
dockable 2D "UV Editor" pane.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Data model (per `ModelVolume`)
|
||||
|
||||
Each of up to `TEXTURE_DISPLACEMENT_MAX_LAYERS` (8) layers gets its **own independent
|
||||
`FacetsAnnotation`** paint mask — the exact same `TriangleSelector`/`FacetsAnnotation` machinery
|
||||
every other paint gizmo (FdmSupports, Seam, MMU, FuzzySkin) already uses, just one full instance
|
||||
per layer slot instead of one per volume. This is what makes "layered/blended" painting work for
|
||||
free: the same triangle can be `ENFORCER` in layer 2's mask and layer 5's mask simultaneously, and
|
||||
at bake/preview time each layer displaces the surface left by the previous one (image-editor-layer
|
||||
semantics).
|
||||
|
||||
**Important gotcha**: `ModelVolume` does **not** hold `std::array<FacetsAnnotation, 8>`. It holds
|
||||
8 individually-named fields (`texture_displacement_facets_0` .. `_7`) plus a
|
||||
`texture_displacement_facet(int slot)` accessor. Reason: `FacetsAnnotation`'s ctor is private,
|
||||
friended only to `ModelVolume`; `std::array`'s own implicitly-generated special member functions
|
||||
are generated with **`std::array`'s** access rights, not the enclosing class's, so friendship does
|
||||
not propagate through the array wrapper. This is a real MSVC C2280 if you try it — confirmed by
|
||||
attempting it. `TextureDisplacementFacetsData` (a `std::array<TriangleSelector::TriangleSplittingData, 8>`,
|
||||
used to carry paint-mask *data* around, e.g. into the bake job) is fine as a real `std::array`
|
||||
since `TriangleSplittingData` has an ordinary public ctor — only the `FacetsAnnotation` object
|
||||
itself has the friend-ctor problem.
|
||||
|
||||
Plus `std::vector<TextureDisplacementLayer> texture_displacement_layers;` — the plain-data layer
|
||||
definitions (texture bytes + params), ordinary public ctor, safe in a vector.
|
||||
|
||||
Touch points that had to mirror the existing `FacetsAnnotation` pattern (see `supported_facets` for
|
||||
the template): all constructors' asserts, copy ctors' init lists, the `-1`-id deserialization ctor,
|
||||
`set_new_unique_id()`, cereal `save`/`load`, `is_texture_displacement_painted()`, and
|
||||
`reset_extra_facets()` (called whenever a topology-changing op like Simplify or subdivision
|
||||
replaces the mesh — this is what drops any unbaked texture-displacement paint, since there's no
|
||||
remap-across-topology-change support for it yet, see Limitations).
|
||||
|
||||
### Bake algorithm (`libslic3r/TextureDisplacement.cpp`)
|
||||
|
||||
`build_texture_displacement(base_mesh, layers, facets_data)` is **accumulate-then-displace, and
|
||||
topology-preserving**: the returned mesh has exactly the input's vertices and triangles, in the same
|
||||
order — only the positions of displaced vertices differ.
|
||||
|
||||
1. `its_compactify_vertices()` on a copy of the input. In practice a no-op (it only drops
|
||||
*unreferenced* vertices, and preserves the order and indices of the rest). It is there to
|
||||
guarantee the index alignment step 3 depends on.
|
||||
2. Area-weighted vertex normals of the **undisplaced** mesh, computed once. Every layer both
|
||||
projects and displaces along these, so a vertex covered by several layers moves along one single
|
||||
well-defined direction.
|
||||
3. For each layer in slot order: deserialize its stored paint mask into a `TriangleSelector` against
|
||||
the **base mesh** (never against a previous layer's output), then
|
||||
`selector.get_facets_strict(ENFORCER)` → the painted patch. Two facts are exploited:
|
||||
- `get_facets_strict()` returns the mesh's **entire** referenced vertex array regardless of which
|
||||
state was asked for — only `.indices` is filtered by state. So `get_facets_strict(ENFORCER)`
|
||||
and `get_facets_strict(NONE)` share identical vertex indexing, which is what lets boundary
|
||||
detection be a plain index check instead of a position-hash lookup.
|
||||
- The selector's vertex array *starts with* the mesh's own vertices (extra ones created where a
|
||||
brush stroke split a triangle are appended after them), and `get_facets_strict()` emits the
|
||||
referenced ones in order. Combined with step 1, **selector vertex index `i` is our vertex `i`**.
|
||||
Split vertices live past the end of our array and are simply skipped — they sit on the paint
|
||||
boundary anyway (splitting only happens at partial coverage), so they would be pinned regardless.
|
||||
4. A vertex used by at least one **unpainted** triangle is a boundary vertex — pinned, never
|
||||
displaced (its final position is ambiguous, it belongs to both regions). Only vertices used
|
||||
exclusively by painted triangles get displaced. This is what keeps bakes seamless with zero
|
||||
remeshing/hole-filling at the seam.
|
||||
5. Per interior vertex: sample the height texture (`sample_layer_height()`, see Projection methods)
|
||||
and fold `height * depth_mm * (invert ? -1 : 1)` into that vertex's running total via the layer's
|
||||
`TextureBlendMode` (see Blend modes). A `visited` set makes each layer fold in exactly **once**
|
||||
per vertex, no matter how many of the patch's triangles share it — otherwise a Multiply/Subtract
|
||||
layer would apply two or three times over depending on local triangle fan-out.
|
||||
6. Finally, move each touched vertex along its (step 2) normal by its accumulated total.
|
||||
|
||||
**This replaced a sequential design** that re-meshed after each layer and carried the next layer's
|
||||
paint mask onto the result with `TriangleSelector::remap_painting()`. That was the root cause of the
|
||||
reported "the second texture is never applied" bug: remapping a mask onto a mesh whose vertices had
|
||||
just been displaced out from under it routinely produced an empty bitstream, and the layer was then
|
||||
silently `continue`d past. It was also what forced the per-layer vertex duplication and the final
|
||||
`its_compactify_vertices()` weld. The current formulation has neither problem, is substantially
|
||||
faster (no remap, no welding, one pass), makes blend modes possible at all (they need a shared
|
||||
per-vertex accumulator, which sequential re-meshing cannot provide), and — because the output keeps
|
||||
the input's exact vertex indexing — lets GUI code overlay a preview on the base mesh with no index
|
||||
translation.
|
||||
|
||||
### Blend modes
|
||||
|
||||
`TextureBlendMode` {Add, Subtract, Multiply, Divide}, per layer, applied per vertex against the
|
||||
total accumulated by the layers **below** it (lower slots). The quantity blended is a signed
|
||||
displacement in **mm**, not a pixel value.
|
||||
|
||||
Add/Subtract are self-explanatory. Multiply/Divide are *scaling* operations and so need a unit
|
||||
convention: they treat the layer's own value as a **factor relative to 1 mm**. That makes `depth_mm`
|
||||
a gain, and — the property that makes a Multiply layer usable as a mask — a layer with depth 1 mm
|
||||
sampling a white (1.0) texel multiplies by exactly 1, i.e. leaves the layers below unchanged.
|
||||
Divide floors its divisor's magnitude at 0.05 — a black texel samples to *exactly* zero, so the
|
||||
divisor really does hit zero in ordinary use, and an unbounded `1/0` would fling vertices thousands
|
||||
of mm away and poison the mesh's bounding box (and every plate/print-volume check downstream). The
|
||||
floor doubles as a cap on how far Divide can amplify the relief beneath it: at most 20×.
|
||||
|
||||
The **lowest painted layer ignores its blend mode**: it has nothing beneath it, and Multiply/Divide
|
||||
against an implicit zero base would annihilate (or blow up) it. Enforced in `build_texture_
|
||||
displacement()` (the first layer to reach a given vertex always folds in additively) and surfaced in
|
||||
the UI, which labels that layer "Base layer" instead of offering a control that silently does nothing.
|
||||
|
||||
### Projection methods
|
||||
|
||||
Four choices per layer (`TextureProjectionMethod`), all funneling through `apply_uv_transform()`
|
||||
(scale by `1/tiling_scale`, rotate by `rotation_deg`, add `offset`). They are dispatched by
|
||||
`sample_layer_height()`, which returns a **height**, not a UV — because Triplanar takes three
|
||||
texture samples per vertex and so has no single UV that represents it.
|
||||
|
||||
- **Triplanar** (default) — samples the texture on all three world planes (`(y,z)`, `(x,z)`, `(x,y)`)
|
||||
and blends the three by the vertex's own normal raised to `TRIPLANAR_BLEND_SHARPNESS` (4).
|
||||
This is the fix for a real, user-reported bug. The previous version *hard-picked* the single axis
|
||||
most aligned with the normal, which is discontinuous wherever that dominant axis flips: on a +X
|
||||
face the planar coordinate is `(y, z)`, on a −Y face it is `(x, z)`, so at the shared edge `u`
|
||||
jumps from `y_edge` to `x_edge`. On a box centred near the origin those two happen to **agree** at
|
||||
the (+,+) and (−,−) corners and **differ by the full corner width** at the (+,−) and (−,+) corners
|
||||
— which is exactly the "two bad corners, two good ones" symmetry that was observed. A weighted
|
||||
blend is continuous across the transition by construction, since the weight of the axis being left
|
||||
behind falls smoothly to zero. (Note this removes the hard *seam*; some cross-fade blurring in the
|
||||
band right at a 90° edge is inherent to triplanar mapping. A genuinely seam-free wrap around a box
|
||||
needs a real unwrap — that is what the LSCM mode is for.)
|
||||
- **Cylindrical** — wraps around an axis through the patch centroid, axis auto-picked as the world
|
||||
axis *least* aligned with the average normal (perpendicular to the outward radial normal, as a
|
||||
cylinder's own axis would be). `u = angle * local_radius` (arc length in mm), `v = distance along
|
||||
axis`. Approximation, not an exact fit for arbitrary geometry.
|
||||
- **Spherical** — longitude/latitude around the centroid, scaled by local radius. Same caveat.
|
||||
- **LSCM** — real UV unwrap via `MeshBoolean::cgal::parameterize_lscm()` (CGAL's
|
||||
`Surface_mesh_parameterization` package, LSCM algorithm). Computed **once per patch** (not
|
||||
per-vertex like the others — it's a single global least-squares solve), then each vertex looks up
|
||||
its precomputed UV. Requires the patch to be a single topological disk (one connected component,
|
||||
one boundary loop) — `compute_lscm_uvs()` returns empty and the layer silently falls back to
|
||||
Triplanar if not (e.g. multiple disconnected painted islands, or a fully closed patch).
|
||||
CGAL's parameterizer needs a mesh with no isolated/unreferenced vertices, but `get_facets_strict()`
|
||||
returns the *whole* mesh's vertex array — so there's a compaction step
|
||||
(`compact_patch_with_map()`) that builds a clean sub-mesh + an index map back to the original
|
||||
(uncompacted) vertex numbering, purely local to this file.
|
||||
- **ViewProjected** ("From view") — a flat projection along a fixed direction captured from the 3D
|
||||
camera, like a slide projector. `capture_view_projection()` takes the camera's right/up axes,
|
||||
transforms them into the volume's *local* frame (so the projection rides along if the part is later
|
||||
moved), and stores them as `TextureDisplacementLayer::view_project_right/up` (unit vectors, so the
|
||||
projected coordinate stays in mm and `tiling_scale` keeps meaning mm). `sample_layer_height()`
|
||||
projects `Vec2f(dot(pos, right), dot(pos, up))`. Single-valued per point, so — like LSCM but unlike
|
||||
blended Triplanar — the fast preview and UV-check overlay precompute it per vertex
|
||||
(`compute_layer_vertex_uvs()`) and drive the shader's `use_vertex_uv` path. Faces angled away from
|
||||
the projector smear; that is inherent to view projection, not a bug.
|
||||
|
||||
### Manual seams and island cutting
|
||||
|
||||
`TextureDisplacementLayer::lscm_seam_edges` — undirected mesh-vertex-index edge pairs the unwrap is
|
||||
forced to cut along, on top of the dihedral-angle seams. `segment_into_charts()` takes a set of these
|
||||
(translated from mesh → compacted-patch numbering inside `compute_patch_unwrap()`) and refuses to
|
||||
union two triangles across a marked edge whatever their angle. Both the unwrap cache key and the
|
||||
gizmo's `UVEditorState` include the seam list, so marking a seam (which leaves the paint mask
|
||||
untouched) still forces a re-solve. Like the paint masks, seams are mesh-index-space and so dropped on
|
||||
any topology change.
|
||||
|
||||
Two ways to write to it:
|
||||
- **Mark seam (manual, #9)** — a "Mark seams" click mode (`m_seam_edit_mode`) that suppresses
|
||||
painting. A click raycasts the volume (`m_c->raycaster()->raycasters()[idx]->unproject_on_mesh()`,
|
||||
`idx` = the volume's slot among model-part volumes), finds the facet's edge nearest the hit point,
|
||||
and toggles it. Marked edges render as a red overlay (`render_seam_overlay()`), pulled toward the
|
||||
camera so they read on top. This is the Blender mark-seam workflow.
|
||||
- **Cut island (auto, #17)** — `cut_island()` takes the selected chart's triangles (back-mapped from
|
||||
the unwrap via `source_vertex`), finds their 3D bounding box, and marks every edge that straddles
|
||||
the mid-plane perpendicular to the longest axis. The re-unwrap then splits the chart across its
|
||||
narrow waist — the "islands might be very long" case. Exposed as the UV pane's **Cut** button.
|
||||
|
||||
### UV-check overlays (checker / distortion)
|
||||
|
||||
`resources/shaders/{110,140}/texture_displacement_uvcheck.{vs,fs}`, one shader with a `mode` uniform,
|
||||
drawn over the painted patch (`rebuild_uvcheck_mesh()`/`render_uvcheck_mesh()`, P3N3T2: `normal.x` =
|
||||
distortion, `tex_coord` = uv), pulled forward with a polygon offset. **Checker** (#13) samples a
|
||||
procedural checkerboard at the layer's uv (per-vertex for LSCM/ViewProjected, in-shader triplanar
|
||||
otherwise) — squares that stay square mean low distortion. **Distortion** (#14) colours each triangle
|
||||
blue→green→red by `log2(uv_area / surface_area)` centred on the patch's *median* stretch (so a
|
||||
globally-scaled unwrap reads as uniformly ideal and only relative stretch shows), averaged to
|
||||
vertices. A separate **Show mesh wireframe** toggle (#8) draws the whole volume's triangle edges,
|
||||
rebuilt only when the vertex count changes (not per stroke).
|
||||
|
||||
### Tiling
|
||||
|
||||
`DecodedHeightTexture::sample(uv, tile_enabled, tile_method)`. Two tile methods when enabled
|
||||
(Repeat, MirroredRepeat). **When `tile_enabled` is false, sampling outside `[0,1)` returns `0`
|
||||
directly** — clamping the *coordinate* into range (what an earlier version did) instead smears the
|
||||
border row/column of pixels outward to infinity in every direction, which is a real bug that was
|
||||
reported and fixed (visually: streaky lines radiating out from the painted patch).
|
||||
|
||||
### Subdivision (`subdivide_mesh_uniform()`)
|
||||
|
||||
Deliberately **whole-mesh and uniform**, not limited to the painted patch. A patch-only /
|
||||
adaptive subdivision would create a classic T-junction/cracking problem where the denser
|
||||
(subdivided) and sparser (untouched) regions meet — the fine side has edge midpoints the coarse
|
||||
side doesn't know about, producing a real (non-manifold-looking) crack in the baked geometry. This
|
||||
was consciously scoped down from the original plan's "adaptive per-patch subdivider" idea to avoid
|
||||
that correctness risk (a subtly-cracked mesh is a much worse outcome than "not implemented yet").
|
||||
Algorithm: recursive 1-to-4 triangle split via edge midpoints, with a shared per-pass midpoint cache
|
||||
(keyed by sorted vertex-index pair) so triangles sharing an edge get the *same* new vertex — capped
|
||||
at `max_iterations` (default 6) passes to bound worst-case triangle-count explosion.
|
||||
|
||||
Wired as a "Subdivide model" button in the gizmo panel — a real, committed geometry change (like
|
||||
Bake), using the same `save_painting()`/`set_mesh()`/`restore_painting()` dance `GLGizmoSimplify`
|
||||
uses: supported/seam/mmu/fuzzy-skin masks get remapped onto the new triangles, texture-displacement
|
||||
paint does not (no remap support yet) and is dropped rather than left pointing at now-meaningless
|
||||
triangle indices.
|
||||
|
||||
### Preview pipeline (perf)
|
||||
|
||||
`rebuild_preview()` used to call `build_texture_displacement()` **synchronously on the UI thread**
|
||||
on every stroke-end and every slider release. With multiple painted layers this got slow (each
|
||||
layer's PNG sampling + vertex welding + `remap_painting()` stacks up). Fixed by moving the actual
|
||||
computation into `TextureDisplacementPreviewJob` (mirrors `TextureDisplacementBakeJob`'s
|
||||
process()/finalize() split), queued on the app's shared UI job worker via plain `queue_job()` (not
|
||||
`replace_job()` — that worker is shared app-wide, including with Bake; `replace_job()` would cancel
|
||||
an in-flight bake if one happened to be running). A `m_preview_generation` counter discards stale
|
||||
results if a burst of edits queues several jobs in a row and an older one finishes after a newer one.
|
||||
|
||||
Two other real perf fixes worth remembering:
|
||||
- Sliders in ImGui report "changed" continuously on every drag frame, not just once on release —
|
||||
gating the (then-synchronous) rebuild behind "mouse button not currently down" was necessary to
|
||||
stop dozens of rebuilds per drag.
|
||||
- `decode_height_texture()` used to re-decode the same PNG from scratch on every call. Now cached
|
||||
in `TextureDisplacement.cpp`, keyed by a `weak_ptr` to the layer's `image_data` (not just the raw
|
||||
pointer — a `weak_ptr` correctly detects a freed-then-reused address, where a raw-pointer key
|
||||
would alias a stale cache entry onto an unrelated later texture).
|
||||
|
||||
### Fast bump preview (GPU-only, no CPU meshing)
|
||||
|
||||
`resources/shaders/{110,140}/texture_displacement_bump.{vs,fs}`, registered as
|
||||
`"texture_displacement_bump"`. Perturbs the *shading* normal from the height texture's local
|
||||
gradient instead of moving geometry — active-layer-only, toggled via a "Fast preview (normal map)"
|
||||
checkbox. Vertex format is `GLModel::Geometry::EVertexLayout::P3N3T2`: `normal.x` carries the
|
||||
per-vertex paint weight (0/1) and `tex_coord` carries a precomputed texture UV, so it can use
|
||||
`GLModel` normally instead of needing a hand-rolled VBO/VAO manager. Weight buffer is
|
||||
rebuilt at the same cadence as the true-displacement preview (stroke-end/slider-release), using the
|
||||
**live** `TriangleSelector` state (not the flushed model facets), so it doesn't lag by a full model
|
||||
round-trip.
|
||||
|
||||
The perturbed normal is the analytic one for a height field `H = ±depth_mm · h(uv)` displaced along
|
||||
`N` over any orthonormal surface tangent pair `T`/`B`:
|
||||
|
||||
N' = normalize(N − (dH/da)·T − (dH/db)·B), a = dot(p,T), b = dot(p,B)
|
||||
|
||||
The two slopes have to be genuine **mm-per-mm** derivatives for the preview's apparent depth to
|
||||
match the bake's — see bug #13.
|
||||
|
||||
**Two projection paths (`use_vertex_uv` uniform):**
|
||||
- **Triplanar (`use_vertex_uv = 0`)** — `uv` and the `T`/`B` axes are both derived in-shader from
|
||||
the dominant normal component, mirroring `project_planar()`/`apply_uv_transform()`, and the slope is
|
||||
formed analytically. `T`/`B` are the projection's axis-aligned pair, exact only when the face is
|
||||
axis-aligned; the shader drops the along-normal component to keep the gradient in the surface. Here
|
||||
one `uv` unit is exactly `tiling_scale` mm, so the `1/tiling_scale` gradient factor is right.
|
||||
- **Precomputed UV (`use_vertex_uv = 1`, used for LSCM)** — `uv` comes per-vertex from the CPU
|
||||
(`compute_lscm_uvs(patch, layer)`, so island placement + tiling/rotation/offset are already folded
|
||||
in), and the perturbed normal is built with **Mikkelsen's method** ("Bump Mapping Unparametrized
|
||||
Surfaces on the GPU"): the surface gradient taken directly from the screen-space derivatives of the
|
||||
*sampled height* and position. **This makes no uv→mm scale assumption**, which is essential —
|
||||
the first cut used the same global `1/tiling_scale` factor as triplanar and the depth came out
|
||||
visibly wrong, because an LSCM map is **conformal, not isometric**: it is globally area-scaled but
|
||||
the *local* mm-per-uv varies across the chart. `dFdx(h)` captures the true on-screen rate of change
|
||||
however the chart is stretched. **This path is also what makes the fast preview follow the UV
|
||||
editor: move an island and its uv — hence its bump — moves with it** (the bump mesh rebuilds on
|
||||
drag-end, since `on_island_edited(finished)` → `rebuild_preview()` → `rebuild_bump_preview_mesh()`).
|
||||
The branch is uniform (`use_vertex_uv` is a uniform) and the paint weight gates by multiply, so the
|
||||
texture derivatives stay well defined. A triangle straddling a seam has a discontinuous uv → the
|
||||
`det≈0` guard skips it (a localised preview-only artifact, never in the bake).
|
||||
|
||||
Remaining deliberate approximation: the GPU sampler's wrap mode stands in for
|
||||
`tile_enabled`/`tile_method`, so with tiling *off* the GPU repeats where the CPU returns 0 outside
|
||||
`[0,1)`.
|
||||
|
||||
> **Known divergence from the CPU path (not yet reconciled).** The shader's `project_uv()` mirrors
|
||||
> the *hard-axis* `project_planar()`, but the CPU's Triplanar mode is now a **blended** three-plane
|
||||
> sample (see Projection methods — that change is what fixed the 90°-corner seam). The two therefore
|
||||
> still agree on any face that is roughly axis-aligned (one blend weight ≈ 1 there, so the blend
|
||||
> degenerates to exactly the hard-axis pick), and disagree in the cross-fade band around a sharp
|
||||
> edge — precisely where the fast preview will still show the old hard seam that the true preview and
|
||||
> the bake no longer have. Reconciling it means sampling all three planes in the shader and blending
|
||||
> the three gradients by `pow(abs(N), TRIPLANAR_BLEND_SHARPNESS)`, the same weights
|
||||
> `sample_layer_height()` uses. Also note the shader is still **active-layer-only** and knows nothing
|
||||
> about `TextureBlendMode`, so a multi-layer stack cannot match the true preview by construction.
|
||||
|
||||
### On-canvas "Adjust Texture" gizmo
|
||||
|
||||
A per-active-layer toggle ("Adjust placement (drag on model)") that disables painting and shows a
|
||||
flat pan panel (free 2D drag on both axes) plus two arrows along the patch's own U/V axes
|
||||
(constrained single-axis drag). Anchored to the painted patch's centroid/average-normal
|
||||
(`compute_layer_paint_anchor()`). Hit-testing is screen-space distance/point-to-segment (not real
|
||||
3D ray intersection against the handle geometry) — simple and good enough at this handle size.
|
||||
|
||||
Known unverified detail: the **offset-drag direction/sign** is reasoning-based (increasing `offset`
|
||||
shifts which texel is sampled at a fixed world position, which visually slides the pattern the
|
||||
*opposite* way — so the code subtracts), not visually confirmed, since this environment can't
|
||||
render pixels. May need a one-line sign flip once actually tested. The rotation-arrow-implied
|
||||
direction should be reliable (it follows directly from a self-consistent 2D basis, no such
|
||||
ambiguity).
|
||||
|
||||
### UV Editor pane
|
||||
|
||||
`UVEditorCanvas` (`src/slic3r/GUI/UVEditorCanvas.hpp/.cpp`) — a standalone `wxGLCanvas` rendering the
|
||||
flattened LSCM islands (per-island wireframe + outline + fill) over the height texture (background
|
||||
quad tiled across the whole unwrap), with mouse pan/zoom. It is wrapped in a **`UVEditorPanel`**
|
||||
(same file) that adds a button row (Frame / Snap / Average scale) and a Blender-style status line
|
||||
along the bottom naming the current gesture and the shortcuts in play. The *panel* is what is
|
||||
registered as a `wxAuiPaneInfo` pane on `Plater`'s `m_aui_mgr`; `Plater::show_uv_editor(bool)`
|
||||
shows/hides it (deferred via `CallAfter`, since the gizmo calls it mid-3D-frame), and
|
||||
`get_uv_editor_canvas()` returns the inner canvas the gizmo talks to.
|
||||
|
||||
Deliberately **shares the app's one real `wxGLContext`** (`wxGetApp().init_glcontext(*this)`, the
|
||||
same call `View3D`/`Preview`/`AssembleView` make) rather than creating an independent context like
|
||||
`SkipPartCanvas` does elsewhere in this codebase — this is what lets it reuse the already-registered
|
||||
`"flat"`/`"flat_texture"` shaders and `GLModel` as-is, instead of needing its own shader
|
||||
compilation/VBO management.
|
||||
|
||||
**Geometry is uploaded once, in the unwrap's own (raw, mm) coordinates**, one `GLModel` set per
|
||||
island; each island is then drawn through its own 2x3 affine (`island_transform_matrix()` composed
|
||||
with the layer's tiling/rotation/offset) passed as the `flat` shader's `view_model_matrix`. This is
|
||||
the fix for the ~200 ms-per-frame island-drag stall (#3): the old design pre-transformed every UV on
|
||||
the CPU and re-uploaded the entire wireframe on every mouse-move event, which on a million-triangle
|
||||
patch is exactly as slow as it sounds. Now a drag updates one matrix per island and touches no vertex
|
||||
buffer — `on_island_edited(!finished)` calls only `set_island_transforms()`, and the full
|
||||
`set_islands()` rebuild happens solely when the unwrap itself changes (`unwrap_changed` in
|
||||
`update_uv_editor()`).
|
||||
|
||||
**Gestures** (canvas-owned, reported to the gizmo as incremental deltas via `IslandEditFn`): left-drag
|
||||
= move, right-drag or **R** = rotate (hold **Shift** to snap to 15° steps — quantised on the
|
||||
*cumulative* rotation, not each delta, so it doesn't judder, and accumulated incrementally so it
|
||||
survives crossing ±180°), **S** = scale (R/S modal, click/Enter to confirm, Esc to cancel), wheel =
|
||||
zoom about the cursor, middle-drag = pan, **Home**/**F** = frame all. Scale writes
|
||||
`TextureIsland::scale`; "Average scale" (`average_island_scales()`) sets every island to the mean, so
|
||||
one island scaled by hand can be matched back to its neighbours' texel density. **Snap** (canvas-owned
|
||||
`m_snap_enabled`, toggled from the toolbar) sticks a dragged island's nearest boundary vertex onto a
|
||||
neighbouring island's at drag-*end* only — a magnet that re-applies mid-drag is very hard to pull out
|
||||
of. Toolbar commands the canvas can't service itself (Average scale) are forwarded to the gizmo via
|
||||
`CommandFn`; view-only ones (Frame, Snap) it handles directly.
|
||||
|
||||
## Bugs found and fixed this session (worth remembering)
|
||||
|
||||
These were all real, confirmed root causes (found by reading the actual code path, not guessed):
|
||||
|
||||
1. **Cross-face projection distortion** — see "Triplanar" above. Fixed by projecting each vertex
|
||||
with its own normal instead of one shared patch-average normal.
|
||||
2. **Disabled-tile smearing to infinity** — clamping the UV *coordinate* into `[0,1]` instead of
|
||||
returning 0 outside it, when tiling is off. Fixed in `DecodedHeightTexture::sample()`.
|
||||
3. **Invisible checkbox/radio "checked" state in light mode** — `ImGuiWrapper::push_toolbar_style()`
|
||||
sets `ImGuiCol_CheckMark` to white while the checkbox/radio frame background is fully transparent
|
||||
(alpha 0) over a light window background — a white checkmark on an effectively-white background
|
||||
is invisible by construction. This is a **pre-existing, general app-wide bug**, not specific to
|
||||
this feature (every panel using `push_toolbar_style()` in light mode has it) — fixed by changing
|
||||
just the light-mode branch's `CheckMark` color to the app's teal accent.
|
||||
4. **Distorted (non-aspect-correct) texture thumbnails** — was forcing a square `ImGui::Image` size
|
||||
regardless of the source image's actual aspect ratio.
|
||||
5. **`std::array<FacetsAnnotation, 8>` compile error** — see Data model above (MSVC C2280,
|
||||
`std::array`'s implicit special members don't inherit element-type friendship).
|
||||
6. **Eigen ternary expression-template type mismatch** (MSVC C2446) — `cond ? (n / len) :
|
||||
Vec3f::UnitZ()` fails because the two branches are different unevaluated Eigen expression
|
||||
*types* with no common type; fixed by wrapping the non-`UnitZ()` branch in an explicit
|
||||
`Vec3f(...)` to force a concrete common type.
|
||||
7. **Post-bake stale preview** — `GLGizmoPainterBase::data_changed()`'s change-detection only
|
||||
checks object id / volume count, neither of which changes when Bake replaces a volume's mesh
|
||||
(same object, same volume count, just a new mesh/id on the volume itself) — so the gizmo kept
|
||||
rendering/painting against the pre-bake `TriangleSelectorPatch` until manually deselected and
|
||||
reselected. Fixed by explicitly calling `update_from_model_object()` in the bake-completion
|
||||
callback.
|
||||
8. **Bake job / crash-report `resources` junction going stale** — unrelated to this feature's code,
|
||||
but hit during testing: `build/src/Release/resources` was a leftover **empty plain directory**
|
||||
instead of the junction CMake's post-build step creates (`if not exist` skipped it because the
|
||||
empty folder already "existed"), so the built exe couldn't find `resources/data/hints.ini`,
|
||||
leaving `HintDatabase`'s hint list empty → `rand() % 0` divide-by-zero crash before the UI ever
|
||||
opened. Fixed by deleting the empty folder and manually recreating the `mklink /J` junction.
|
||||
9. **Fast bump preview showing a solid black object** — `GLModel::render()` **unconditionally**
|
||||
re-sets the shader's `"uniform_color"` uniform from its own internal `Geometry::color` field
|
||||
(defaulting to `ColorRGBA::BLACK()`) right before every draw call — so a manual
|
||||
`shader->set_uniform("uniform_color", ...)` call made just before `.render()` gets silently
|
||||
clobbered. Any `GLModel` that needs a specific flat color **must** call `.set_color(...)` on the
|
||||
model itself, not set the shader uniform directly. Found by reading `GLModel::render()`'s actual
|
||||
source rather than guessing at shader/lighting math.
|
||||
10. **UV editor canvas rendering nothing / showing stale content on resize** — the canvas requested
|
||||
a generic `wxGLAttributes().Defaults()` pixel format while sharing the app's one real
|
||||
`wxGLContext` (which was originally created against `View3D`'s canvas, itself requesting a
|
||||
specific RGBA/24-bit-depth/8-bit-stencil format). `wxGLCanvas::SetCurrent()` on WGL/GLX
|
||||
generally requires the target window's pixel format to be compatible with the one the context
|
||||
was created against; a mismatch can make `SetCurrent()` silently fail, leaving the canvas
|
||||
showing whatever was last in its backbuffer (looks exactly like "blank" or "stale image on
|
||||
resize"). Fixed by requesting the same explicit attribute list
|
||||
`OpenGLManager::create_wxglcanvas()` uses for the main view canvases — but see bug #14: the
|
||||
first attempt at this copied only *part* of that list and the symptom therefore survived.
|
||||
11. **`<glad/gl.h>` / `<wx/glcanvas.h>` include-order conflict** — `wx/glcanvas.h` pulls in the
|
||||
platform's real `GL/gl.h`; if that happens before `<glad/gl.h>` is processed in the same
|
||||
translation unit, glad's own header errors out (`OpenGL (gl.h) header already included`).
|
||||
Fixed by including `<glad/gl.h>` first in `UVEditorCanvas.hpp`, before `<wx/glcanvas.h>` — any
|
||||
file that includes this header (including `Plater.cpp`, transitively) needs glad to win that
|
||||
race.
|
||||
12. **Fast preview hidden behind the paint-highlight overlay** — `render_painter_gizmo()` always
|
||||
drew the selection-highlight overlay on top with a depth-bias trick (`glPolygonOffset`) that
|
||||
only makes sense for the *true*-displacement preview: real geometry moves in the painted area,
|
||||
so the depth-biased overlay only wins the depth test in the *unpainted* (coincident) region.
|
||||
The bump preview never moves geometry — its depth is identical to the overlay's *everywhere* —
|
||||
so the overlay was winning the depth test across the whole surface and hiding the bump shading
|
||||
entirely. Fixed by skipping the overlay draw entirely when the bump-preview path is active.
|
||||
13. **Fast preview's apparent depth not matching the true preview's** — the bump shader built its
|
||||
perturbed normal as `normalize(N + depth_mm * vec3(hL-hR, hD-hU, 0))`. Two things wrong with
|
||||
that. (a) `hL-hR` is a height difference across *one texel step*, i.e. `dh/du` already scaled by
|
||||
`2·texel`, and `du` is in uv units, not mm — the real surface slope needs the full chain rule
|
||||
back through `uv = R(rotation) · planar_mm / tiling_scale`, i.e. a further `1/tiling_scale` and
|
||||
a rotation of the gradient by `−rotation`. The missing `1/(2·texel·tiling_scale)` factor is
|
||||
~26× at a 1024px texture and a 20mm tile size, all in the flattening direction — which is
|
||||
exactly what "fast preview has a different height from the real preview" looks like. (b) the
|
||||
gradient was added to model-space `xy`, but the two axes the planar projection actually runs
|
||||
along are `yz`/`xz`/`xy` depending on the dominant normal component, so on any face not
|
||||
dominated by `z` the perturbation was applied to the wrong axes. Fixed by computing the real
|
||||
mm-per-mm slope and rotating it into the projection's own `T`/`B` axes (see "Fast bump preview"
|
||||
above for the derivation).
|
||||
14. **UV editor pane still blank after bug #10** — three separate causes, all of them live at once:
|
||||
- The bug-#10 fix copied `OpenGLManager::create_wxglcanvas()`'s attribute list but **dropped its
|
||||
multisampling attributes** (`WX_GL_SAMPLE_BUFFERS`/`WX_GL_SAMPLES`, 4 samples by default), on
|
||||
the reasoning that a flat 2D wireframe view doesn't need AA. But a differing sample count *is*
|
||||
a differing pixel format, so this left exactly the `wglMakeCurrent()` mismatch bug #10 set out
|
||||
to fix. It now mirrors the full list, AA included, reading `OpenGLManager::can_multisample()`
|
||||
(already resolved by then — `View3D` is constructed first).
|
||||
- `set_mesh()`/`set_background_texture()` each called `render()` **inline**, and both are reached
|
||||
from `update_uv_editor()` → `rebuild_preview()` → the gizmo's ImGui panel — i.e. from the
|
||||
middle of the *3D* canvas's GL frame, and (since `show_uv_editor(true)` is the last line of
|
||||
`update_uv_editor()`) while this pane was still **hidden**. `wxGLCanvas::SetCurrent()` returns
|
||||
false outright on a canvas that isn't shown on screen, and the old code ignored the return
|
||||
value — so every GL call in `render()`, `glViewport`/`glClear` included, silently landed on the
|
||||
3D canvas instead. These now only mark dirty + `Refresh()`; `render()` bails unless
|
||||
`IsShownOnScreen()` *and* `SetCurrent()` succeeds; and `Plater::show_uv_editor()` defers its
|
||||
AUI relayout via `CallAfter` so the pane's first size/paint can't be delivered mid-frame either.
|
||||
- Even once drawing, nothing would have been *visible*: the background quad spanned `[-1,1]²`
|
||||
while LSCM UVs land around `[0,1]²`, and the view was centered on the origin at a half-extent
|
||||
of 0.6. The quad is now the unit square in the same UV space the wireframe uses (which is also
|
||||
where `sample()` maps the texture, regardless of its pixel aspect), the projection's Y is
|
||||
negated so `v` runs down-screen (putting the texture's first pixel row at the top rather than
|
||||
upside down), and the view auto-fits to the unwrap ∪ unit square the first time a patch shows up.
|
||||
15. **A second texture layer was silently never applied** — the reported "multiple textures don't
|
||||
work reliably". Root cause was the old sequential bake: layer N's paint mask was stored against
|
||||
the volume's original mesh, so before layer N+1 could be deserialized the mask had to be carried
|
||||
onto the mesh layer N had *just displaced*, via `TriangleSelector::remap_painting()`. Remapping a
|
||||
mask onto geometry that has moved out from under it routinely returned an empty bitstream, and
|
||||
the code then did `if (data.bitstream.empty()) continue;` — i.e. dropped the layer **without any
|
||||
diagnostic**. Fixed structurally rather than patched: every layer is now evaluated against the
|
||||
base mesh and merged per vertex (see Bake algorithm), so no remap happens at all. Covered by a
|
||||
regression test.
|
||||
16. **Hard-axis triplanar seam at exactly two of a box's four vertical corners** — see "Triplanar"
|
||||
under Projection methods. Worth recording the *diagnostic* here, because the asymmetry is what
|
||||
pinned it down: the user reported the seam at the (X+,Y−) and (X−,Y+) corners with the other two
|
||||
clean. That is precisely what a dominant-axis switch predicts (`u = y` on an X face, `u = x` on a
|
||||
Y face; those agree where `x == y` and differ by the corner width where `x == −y`) and it ruled
|
||||
out every "the texture is wrong" hypothesis, since the texture itself is fine — the *mapping* is
|
||||
discontinuous. Fixed by blending the three axis projections instead of picking one.
|
||||
17. **Use-after-free when removing a texture layer** (latent, pre-existing — found while touching the
|
||||
panel, not caused by it). The layer list's "Remove" button called `remove_texture_layer()` *in
|
||||
the middle of rendering that layer's row*. That erases the layer from
|
||||
`mv->texture_displacement_layers`, shifting every later element down — after which the loop
|
||||
happily carried on dereferencing `layer` for the rest of the row's widgets (depth/tiling sliders,
|
||||
`PopID`) and kept iterating `ordered`, a vector of pointers into the storage that had just moved.
|
||||
Never crashed loudly because `vector::erase` doesn't reallocate, so the reads landed on a *valid*
|
||||
but *wrong* (shifted) layer. Fixed by recording the slot and doing the removal after the loop.
|
||||
18. **Every LSCM island collapsed to a point** (the UV editor was empty; the Tile-size slider did
|
||||
nothing; an LSCM bake came out as a flat "single-face extrude"). One line in
|
||||
`compute_patch_unwrap()`: `chart.indices = std::move(chart_mesh.indices);` ran *before*
|
||||
`area_3d(chart_mesh)` was taken. `area_3d()` iterates those indices, so on the moved-from
|
||||
(emptied) mesh it returned `0`, giving `scale = sqrt(0 / uv_area) = 0` — **every chart's UVs
|
||||
multiplied by zero**. That one zero explained all three symptoms at once (no island extent to
|
||||
draw; a zero-size unwrap is still zero after any tiling divide; the bake sampled ~one constant
|
||||
texel per chart). Fixed by measuring the 3D area before the move. Found only by instrumenting the
|
||||
actual island bbox into the panel — three rounds of reasoning from screenshots had each guessed
|
||||
wrong, because a collapsed-to-a-point unwrap and an off-screen-framed one look identical.
|
||||
|
||||
## Known limitations / deferred work
|
||||
|
||||
- **No `.3mf` serialization** for texture-displacement paint data or texture assets. A background
|
||||
agent attempted this in an earlier session, hit its own usage limit mid-edit, and left
|
||||
`bbs_3mf.cpp` with an undefined forward-declared function; that partial edit was reverted rather
|
||||
than shipped broken. Practical impact: **baked** geometry round-trips fine (it's just an ordinary
|
||||
part of the mesh via the existing mesh serialization path) — what does *not* survive a project
|
||||
save/reload is any *unbaked* paint stroke and texture layer definition.
|
||||
- **No remap-across-topology-change** for texture-displacement paint (`ModelObject::split()`, mesh
|
||||
boolean ops, Simplify, and now `subdivide_mesh_uniform()` all drop it via `reset_extra_facets()`).
|
||||
The other four paint channels (supported/seam/mmu/fuzzy) do get remapped in these cases.
|
||||
- **Cylindrical/Spherical axis/center are auto-picked heuristically**, not user-controllable — no
|
||||
UI to override the auto-detected wrap axis if it picks the "wrong" one for an odd shape.
|
||||
- **Fast preview covers the active layer only**, while the true preview stacks every painted layer —
|
||||
so with more than one layer painted the two will legitimately not agree, independently of bug #13.
|
||||
- **Bump preview and true preview both only refresh at stroke-end**, not continuously during an
|
||||
active drag (a deliberate scope cut for simplicity/consistency — the original plan's "instant
|
||||
update mid-stroke" idea for the bump shader specifically was not carried through).
|
||||
- **On-canvas Adjust-Texture gizmo's offset-drag direction is unverified** (see above).
|
||||
- **The bump shader still uses hard-axis, single-layer projection** while the CPU path is now
|
||||
blended-triplanar and blend-mode aware — see the callout under "Fast bump preview".
|
||||
- **Displacement resolution is capped by the mesh's own vertex density.** Baking only ever *moves*
|
||||
existing vertices (it never inserts any), so a coarse patch cannot show fine texture detail no
|
||||
matter how high-resolution the height map is — that is what the "Subdivide model" button is for.
|
||||
Since the rewrite the bake is topology-preserving, so this is now a hard, explicit property rather
|
||||
than something partly papered over by the old per-layer re-meshing.
|
||||
- **Placeholder toolbar icon** — reuses `toolbar_fuzzy_skin_paint.svg`, noted as a TODO in code.
|
||||
- **Textures are matched to the picker by absolute path** (`TextureDisplacementLayer::path`), so the
|
||||
picker's "which entry is selected" highlight goes blank if a project is moved between machines.
|
||||
Harmless — the layer keeps its own embedded `image_data` and still bakes correctly.
|
||||
|
||||
### Requested UV-editing features — status
|
||||
|
||||
A user working through the feature end-to-end asked for a batch of UV-editing features. All of the
|
||||
functional ones are now implemented (see the sections above): checker (#13), distortion heatmap
|
||||
(#14), mesh wireframe overlay (#8), cut island (#17), project-from-view (#6), and Blender-style mark
|
||||
seam (#9), plus per-island fills, the fast preview honouring the LSCM unwrap and island moves (#1),
|
||||
the UV pane toolbar + status line (#18), Shift-snap rotation, midlevel/bidirectional displacement
|
||||
(#19), and island scale/average/padding/snap (#15/#16/#2).
|
||||
|
||||
Remaining cosmetic / known gaps:
|
||||
- The UV pane toolbar has **text buttons, not icons** — no existing SVG reads cleanly as "average
|
||||
island scale" / "snap islands", so real icons are deferred rather than mis-assigned.
|
||||
- **Mark-seam edge picking** snaps to the nearest edge of the *hit facet* only; it does not
|
||||
highlight the candidate edge on hover before you click (a hover-preview would be a nice refinement).
|
||||
- **Cut island** always halves along the longest 3D axis; there is no UI to pick the cut line.
|
||||
|
||||
## File map
|
||||
|
||||
**libslic3r (core, no GUI dependency):**
|
||||
- `src/libslic3r/TextureDisplacement.hpp/.cpp` — data model, bake algorithm, projection methods,
|
||||
tiling, subdivision. See doc comments throughout, they're kept accurate and up to date.
|
||||
- `src/libslic3r/MeshBoolean.hpp/.cpp` — added `parameterize_lscm()` in the `cgal` sub-namespace,
|
||||
reusing the existing `CGALMesh`/`_EpicMesh`/conversion-helper infrastructure already there for
|
||||
mesh boolean ops. New CGAL includes: `Polygon_mesh_processing/border.h`,
|
||||
`Polygon_mesh_processing/connected_components.h`, `Surface_mesh_parameterization/{Error_code,
|
||||
LSCM_parameterizer_3, parameterize}.h`. No new dependency — CGAL 5.6.3 is already vendored and
|
||||
the `Surface_mesh_parameterization` package headers were already present, just unused before now.
|
||||
- `src/libslic3r/Model.hpp/.cpp` — the 8 named `FacetsAnnotation` fields + accessor,
|
||||
`texture_displacement_layers`, and all the mirrored touch points (see Data model above).
|
||||
|
||||
**GUI:**
|
||||
- `src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp/.cpp` — the gizmo. Panel controls: dock/
|
||||
undock toggle, brush/face/connected-area selection mode + "select whole model" button, per-layer
|
||||
texture picker + depth/tiling/rotation/invert/tile-mode/projection-mode/blend-mode controls,
|
||||
"Adjust placement" toggle (on-canvas gizmo), "Fast preview (normal map)" toggle, "Subdivide model"
|
||||
button, Add layer/Erase all/Bake.
|
||||
- `src/slic3r/GUI/TextureLibrary.hpp/.cpp` — scans the shipped + user texture folders, imports an
|
||||
arbitrary image into the user folder (converting it to the 8-bit grayscale PNG libslic3r decodes),
|
||||
and loads a library file's bytes for a layer. The image→grayscale-PNG conversion lives here, on the
|
||||
GUI side, because libslic3r has no image toolkit; both the import path and the "pick a shipped
|
||||
texture" path go through the same one function.
|
||||
- `resources/textures/displacement/*.png` — the 10 shipped height maps (Bricks, Grid, Hexagons,
|
||||
Knurl, Noise, Quilt, Studs, Waves, Weave, Wood Grain). All 512×512 8-bit grayscale and **seamless**
|
||||
(each is periodic over the full image in both axes, so tiling shows no seam). Generated
|
||||
procedurally; the whole `resources/` tree is installed recursively by CMake, so a new folder under
|
||||
it ships with no build-system change.
|
||||
- `src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp/.cpp` — background bake commit.
|
||||
- `src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp/.cpp` — background preview compute
|
||||
(mirrors the bake job's shape but commits nothing to the Model).
|
||||
- `src/slic3r/GUI/UVEditorCanvas.hpp/.cpp` — the 2D UV unwrap viewer widget.
|
||||
- `src/slic3r/GUI/Plater.hpp/.cpp` — `uv_editor_canvas` member, AUI pane registration,
|
||||
`get_uv_editor_canvas()`/`show_uv_editor()`.
|
||||
- `src/slic3r/GUI/GLShadersManager.cpp` — registers `"texture_displacement_bump"`.
|
||||
- `resources/shaders/{110,140}/texture_displacement_bump.{vs,fs}` — the bump-preview shader.
|
||||
- `src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp` — `PainterGizmoType::TEXTURE_DISPLACEMENT`.
|
||||
- `src/slic3r/GUI/Gizmos/GLGizmosManager.hpp/.cpp` — `EType::TextureDisplacement` registration.
|
||||
- `src/slic3r/GUI/ImGuiWrapper.cpp` — the light-mode checkmark-color fix (bug #3 above; a
|
||||
pre-existing, general bug, not scoped to this feature).
|
||||
|
||||
**CMake:** all new source files added to `src/libslic3r/CMakeLists.txt`,
|
||||
`src/slic3r/CMakeLists.txt` (in roughly-alphabetical position matching each list's existing
|
||||
convention), and `tests/libslic3r/CMakeLists.txt` for the unit test file.
|
||||
|
||||
**Tests:** `tests/libslic3r/test_texture_displacement.cpp` — **run and passing** (7 cases, 116
|
||||
assertions). Covers `decode_height_texture` round-trip, empty-layer no-op, full-cube uniform
|
||||
displacement, boundary-vertex pinning on a hand-built fan mesh, and — added with the bake rewrite —
|
||||
a regression test that a **second layer over the same area actually contributes** (the bug that
|
||||
rewrite fixed), a table-driven check of all four blend modes, and that the lowest layer ignores its
|
||||
blend mode. `BUILD_TESTS` is `OFF` in the checked-in build cache; flip it on to run them:
|
||||
|
||||
cmake -S . -B build -DBUILD_TESTS=ON
|
||||
cmake --build build --config Release --target libslic3r_tests -- -m
|
||||
./build/tests/libslic3r/Release/libslic3r_tests.exe "[TextureDisplacement]" --order rand
|
||||
|
||||
## Build notes
|
||||
|
||||
- Everything here lives in `libslic3r`/`libslic3r_gui`/`libslic3r_cgal` — no new external
|
||||
dependency, no `deps/` rebuild needed. CGAL's parameterization package was already vendored.
|
||||
- To build just this feature's code path fastest: `cmake --build build --config Release --target
|
||||
libslic3r_gui -- -m` (pulls in `libslic3r` and `libslic3r_cgal` as needed). The full app target
|
||||
is `OrcaSlicer_app_gui` (produces `build/src/Release/orca-slicer.exe`) — only needed to actually
|
||||
run and visually test, not to verify compilation.
|
||||
- `BUILD_TESTS` is `OFF` in the existing build cache; flip it on to actually run
|
||||
`test_texture_displacement.cpp`.
|
||||
@@ -1,326 +0,0 @@
|
||||
# Texture Displacement — Feature & Controls Guide
|
||||
|
||||
Texture Displacement is a paint-style gizmo that stamps height-map textures onto a model's surface
|
||||
and turns them into real relief — engraved or embossed detail — either as a live preview or baked
|
||||
into actual mesh geometry. You paint where the texture applies, stack multiple textures as blended
|
||||
layers, choose how each is projected onto the surface, and (for the unwrap projection) lay the result
|
||||
out by hand in a dedicated 2D **UV Editor** pane.
|
||||
|
||||
This document describes every feature and control. For the internal architecture and algorithms, see
|
||||
`TEXTURE_DISPLACEMENT.md`.
|
||||
|
||||
---
|
||||
|
||||
## Table of contents
|
||||
|
||||
1. [Quick start](#quick-start)
|
||||
2. [Entering the tool](#entering-the-tool)
|
||||
3. [Selection modes](#selection-modes)
|
||||
4. [View modes](#view-modes)
|
||||
5. [Auto update](#auto-update)
|
||||
6. [Texture layers](#texture-layers)
|
||||
7. [Per-layer settings](#per-layer-settings)
|
||||
8. [Projection methods](#projection-methods)
|
||||
9. [The UV Editor](#the-uv-editor)
|
||||
10. [Seams](#seams)
|
||||
11. [Adjust placement (on-model)](#adjust-placement-on-model)
|
||||
12. [Preparing the mesh: Subdivide & Remesh](#preparing-the-mesh-subdivide--remesh)
|
||||
13. [Baking & resetting](#baking--resetting)
|
||||
14. [Controls reference](#controls-reference)
|
||||
15. [Tips & limitations](#tips--limitations)
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Select an object and open the **Texture displacement** gizmo from the left toolbar.
|
||||
2. A texture layer is added automatically. Pick a texture from the layer's picker, or import your own.
|
||||
3. **Paint** the area you want the texture to affect (or press **Select whole model**).
|
||||
4. The relief appears live on the model. Tune **Depth**, **Tile size**, **Rotation**, etc.
|
||||
5. If the model is low-poly, use **Subdivide** or **Remesh** so there are enough vertices for detail.
|
||||
6. Press **Bake** to convert the preview into real geometry, or leave it as a live preview.
|
||||
|
||||
> The tool only ever affects the **painted** area. Everything you don't paint keeps its original
|
||||
> surface, and bake blends the relief seamlessly into it.
|
||||
|
||||
---
|
||||
|
||||
## Entering the tool
|
||||
|
||||
The gizmo lives on the left gizmo toolbar (icon: `toolbar_texture_displacement.svg`). Its settings
|
||||
panel opens beside the toolbar. You can **Dock panel / Undock panel** (top of the panel) to pin it or
|
||||
float it freely over the 3D view, and **Close** at the bottom exits the gizmo.
|
||||
|
||||
When you first open the tool on a never-textured object it starts with **one texture layer already
|
||||
added**, so you can paint straight away.
|
||||
|
||||
---
|
||||
|
||||
## Selection modes
|
||||
|
||||
Choose *how* you paint. All three write into the **active layer's** mask.
|
||||
|
||||
| Mode | What it does |
|
||||
|------|--------------|
|
||||
| **Brush** | Free-hand painting with a round brush. Shows a **Brush size** slider and a **Circle / Sphere** choice (circle = surface disc, sphere = 3D ball that also paints around curves). |
|
||||
| **Face** | Click a single triangle to paint it. |
|
||||
| **Connected area** | Click to flood-fill a region; the **Angle threshold** slider limits how far the fill spreads across changes in surface angle. |
|
||||
|
||||
- **Select whole model** — marks the entire model as painted for the active layer, instead of
|
||||
brushing it by hand.
|
||||
|
||||
---
|
||||
|
||||
## View modes
|
||||
|
||||
A row of icon buttons labelled **View** controls how the painted area is shown. The first four are a
|
||||
radio group; **Wireframe** is an independent toggle. Hover any icon for its tooltip.
|
||||
|
||||
| View | Meaning |
|
||||
|------|---------|
|
||||
| **Normal** | The true displaced geometry — exactly what **Bake** produces. Rebuilt in the background. |
|
||||
| **Fast** | A GPU bump-shaded approximation of the *active layer only*. No real geometry movement — quick to update, not exact. Best while tuning or dragging islands. |
|
||||
| **Checker** | A test grid painted over the unwrap so you can see stretching (squares stay square where the map isn't distorted). |
|
||||
| **Distortion** | A blue→green→red heatmap of how much each area is compressed or stretched in UV space. Needs the **Unwrap (LSCM)** projection. |
|
||||
| **Wireframe** | Overlays the mesh edges (white). Independent of the view above; in **Normal** view it sits on the displaced surface. |
|
||||
|
||||
---
|
||||
|
||||
## Auto update
|
||||
|
||||
**Auto update** (on by default) rebuilds the true displaced geometry as soon as *anything* changes —
|
||||
painting, swapping textures, moving sliders. Turn it off on very heavy models to only rebuild when you
|
||||
release a slider (painting still updates on stroke end).
|
||||
|
||||
---
|
||||
|
||||
## Texture layers
|
||||
|
||||
You can stack up to **8** texture layers. Each has its own independent paint mask, its own texture,
|
||||
and its own parameters, and they combine in slot order like layers in an image editor.
|
||||
|
||||
- **Add a layer** — the **+ icon** to the right of the *Texture layers* heading (reuses the tool icon
|
||||
for now).
|
||||
- **Remove** — the button on each layer's header row.
|
||||
- **Active layer** — click a layer's header (or anywhere in its block) to make it active. The active
|
||||
layer is the one you paint into and the one whose block is tinted. Only one layer is active at a time.
|
||||
- **Erase all** — clears the active layer's paint.
|
||||
|
||||
Each layer shows a texture **picker** (large preview + name). Open it to choose from the shipped
|
||||
library or import your own image (any png/jpg/bmp; it's converted to an 8-bit grayscale height map and
|
||||
copied into your user texture folder so app updates can't overwrite it).
|
||||
|
||||
---
|
||||
|
||||
## Per-layer settings
|
||||
|
||||
| Control | Range / options | What it does |
|
||||
|---------|-----------------|--------------|
|
||||
| **Depth (mm)** | 0.01–10 (log) | Maximum displacement along the surface normal. |
|
||||
| **Tile size (mm)** | 0.2–200 (log) | Physical size of one texture tile on the surface. |
|
||||
| **Rotation** | 0–360° | Rotates the texture on the surface. |
|
||||
| **Midlevel** | 0–10 | The grey level that means "don't move". At 0 the texture only pushes outward; raise it and darker texels cut *inward* (one map both embosses and engraves). 0.5 makes mid-grey neutral. |
|
||||
| **Smoothing** | 0–1 | Blurs the height texture before it displaces — rounds hard edges and removes speckle without needing a softer source image. |
|
||||
| **Edge smoothing** | checkbox + **Edge amount** 0–1 | Fades the relief to flat toward the *edge of the painted area*, so it blends into the surrounding surface. A small amount softens only a thin band at the very edge; the maximum flattens the whole painted face. |
|
||||
| **Invert** | checkbox | Flips the height map (peaks become valleys). |
|
||||
| **Blend** | Add / Subtract / Multiply / Divide | How this layer combines with the layers **below** it where they overlap. Add/Subtract pile relief on or carve it away; Multiply/Divide scale the relief underneath (a mask). The lowest painted layer is the **Base** and always behaves additively. |
|
||||
| **Tile** | checkbox + **Repeat / Mirrored repeat** | When off, the texture is placed once (a decal) instead of repeating. Mirrored repeat flips every other tile to hide seams. |
|
||||
| **Projection** | see below | How the texture is mapped onto the painted surface. |
|
||||
|
||||
> **Midlevel warning:** cutting inward can fold the surface through itself in sharp concave corners or
|
||||
> thin walls. Keep Depth small relative to the feature you're cutting into; the panel warns when a deep
|
||||
> inward setting is risky.
|
||||
|
||||
---
|
||||
|
||||
## Projection methods
|
||||
|
||||
How the 2D texture is wrapped onto the 3D painted area.
|
||||
|
||||
| Method | Best for | Notes |
|
||||
|--------|----------|-------|
|
||||
| **Triplanar (blended)** | Patches wrapping around edges | Projects from all three axes at once and blends, so there's no seam across a sharp edge. |
|
||||
| **Cylindrical** | Round, tube-like selections | Wraps the texture around the patch's own centre/axis. |
|
||||
| **Spherical** | Ball-like selections | Longitude/latitude wrap around the patch centre. |
|
||||
| **Unwrap (LSCM)** | Flat, controlled layout | A real conformal unwrap. Cuts the area into pieces at sharp edges (see **Seam angle**), flattens each, and lets you lay them out by hand in the **UV Editor**. Unlocks Checker/Distortion, seams, and island editing. |
|
||||
| **From view** | Decals / slide-projector look | Projects straight onto the surface from the current camera direction. Use **Capture current view** to re-lay it from wherever you're looking. |
|
||||
|
||||
### LSCM-only controls
|
||||
|
||||
These appear when a layer uses **Unwrap (LSCM)**:
|
||||
|
||||
- **Seam angle** (5–90°) — edges sharper than this are cut so each piece lies flat. Lower cuts more
|
||||
(less stretching, more seams); raise to keep more in one piece. A box's 90° corners are cut by
|
||||
default. *Ignored once you've marked any seam by hand* (your seams then define the pieces).
|
||||
- **Connect islands** (on by default) — lays the unwrap out as a **connected net**: pieces that share
|
||||
an edge are unfolded next to each other (a cube becomes a joined net instead of six loose squares).
|
||||
They stay separate islands, so you can still move any of them by hand. Turn off for the classic
|
||||
packed-grid layout.
|
||||
- **Open UV editor** — shows the flattened unwrap in a side pane (see below). Opens *only* when you
|
||||
turn this on — it never pops up on its own.
|
||||
- **Mark seams** / **Path** / **Clear seams** — see [Seams](#seams).
|
||||
- An **Unwrap: N islands, F faces, V verts** read-out tells you what the unwrap actually produced.
|
||||
|
||||
---
|
||||
|
||||
## The UV Editor
|
||||
|
||||
A dockable 2D pane (enable **Open UV editor** on an LSCM layer) showing the flattened unwrap over the
|
||||
height texture. Islands are the flattened pieces; you can rearrange them freely — nothing re-packs them
|
||||
behind your back. Moving an island updates the model **live** (in Fast view it tracks the cursor
|
||||
smoothly, via a shader uniform — no rebuild until you release).
|
||||
|
||||
### Navigation
|
||||
|
||||
| Action | Control |
|
||||
|--------|---------|
|
||||
| Pan | Middle-drag |
|
||||
| Zoom | Mouse wheel (zooms about the cursor) |
|
||||
| Frame everything | **Home** or **F**, or the **Frame** toolbar button |
|
||||
|
||||
### Editing an island
|
||||
|
||||
| Action | Control |
|
||||
|--------|---------|
|
||||
| Select | Left-click an island |
|
||||
| Move | Left-drag |
|
||||
| Rotate | Right-drag, or press **R** then move the mouse (click/Enter to confirm, Esc to cancel) |
|
||||
| Rotate snapped | Hold **Shift** while rotating — snaps to **global** 15° marks (0/15/30…). A protractor dial with tick marks and the current angle is shown. |
|
||||
| Scale | Press **S** then move the mouse (click/Enter to confirm, Esc to cancel) |
|
||||
| Undo / Redo | **Ctrl+Z** / **Ctrl+Shift+Z** or **Ctrl+Y** |
|
||||
|
||||
The **selected** island gets a bold light-green outline and a brighter wireframe; unselected islands
|
||||
are a translucent light-green wash. The texture underneath repeats exactly as it will when baked.
|
||||
A **status line** along the bottom always names the current gesture and the shortcuts in play.
|
||||
|
||||
### Toolbar
|
||||
|
||||
| Button | Action |
|
||||
|--------|--------|
|
||||
| **Frame** | Frame all islands (same as Home). |
|
||||
| **Snap** | Toggle magnetic snapping — a dragged island sticks its boundary to a neighbour's when they come close. |
|
||||
| **Avg scale** | Give every island the same texel density (Blender's "Average Islands Scale"). |
|
||||
| **Cut** | Split the selected island across its long axis (useful for very long islands). |
|
||||
| **Join** | Unfold the selected island onto its nearest neighbour along their shared edge — keeps both as separate islands with their own borders. |
|
||||
| **Unjoin** | Send the selected island back to its own packed position. |
|
||||
|
||||
> **Checker / Distortion in the UV editor:** selecting those View modes also colours the UV pane — a
|
||||
> checker background, or a per-island distortion heatmap — so you can judge stretch in 2D as well as
|
||||
> on the model.
|
||||
|
||||
---
|
||||
|
||||
## Seams
|
||||
|
||||
Seams are edges the unwrap is forced to cut along, on top of whatever the Seam angle cuts — the
|
||||
Blender "mark seam" workflow. They let you control exactly where the unwrap splits.
|
||||
|
||||
Enable **Mark seams** on an active LSCM layer, then:
|
||||
|
||||
- **Click an edge** on the model to mark it (it turns **red**); click a red edge again to unmark it.
|
||||
The edge under the cursor is highlighted **yellow** so you can see what a click will toggle.
|
||||
- **Path mode** (the **Path** checkbox) — for dense meshes where clicking each edge is tedious: click a
|
||||
start point, then an end point, and the whole **shortest path** between them is seamed at once. It
|
||||
chains (each click extends from the last point); the start vertex is shown in **green**.
|
||||
- **Ctrl+drag** rotates/pans the camera while in seam mode.
|
||||
- **Clear seams** removes them all.
|
||||
|
||||
Once any seam is marked, the automatic Seam-angle cutting is disabled so *your* seams define the
|
||||
islands — pieces you leave un-seamed merge together.
|
||||
|
||||
---
|
||||
|
||||
## Adjust placement (on-model)
|
||||
|
||||
**Adjust placement** (on an active layer) lets you position the texture by dragging a handle on the
|
||||
model instead of nudging the Rotation/offset numbers. The handle is a flat panel in the patch's
|
||||
tangent plane (drag anywhere on it to move freely) plus U/V arrows for single-axis nudges. It's
|
||||
anchored to the painted patch, so paint something first.
|
||||
|
||||
---
|
||||
|
||||
## Preparing the mesh: Subdivide & Remesh
|
||||
|
||||
Displacement can only move vertices that exist, so a coarse model needs more of them first.
|
||||
|
||||
### Subdivide
|
||||
|
||||
Splits every triangle into four, **1–5 times** (each step roughly quadruples the triangle count).
|
||||
|
||||
- **Subdivide steps** (1–5) — how many times to split.
|
||||
- **Preview subdivision** — shows the result as a **cyan wireframe** without changing the model.
|
||||
- **Apply** — commits the subdivision to the geometry.
|
||||
- **Done** — ends the preview and leaves the model as it is.
|
||||
|
||||
### Remesh
|
||||
|
||||
Rebuilds the whole model with triangles close to a target edge length — evens out a mesh with wildly
|
||||
varying triangle sizes (CGAL isotropic remeshing).
|
||||
|
||||
- **Target edge (mm)** — desired triangle edge length (seeded to the model's current average).
|
||||
- **Remesh** — splits the big triangles and merges the small ones to that size.
|
||||
|
||||
> Both Subdivide-Apply and Remesh **replace the geometry** and clear any *not-yet-baked* paint on it
|
||||
> (already-baked relief is kept). If you had the mesh **Wireframe** on before, it stays on afterward.
|
||||
|
||||
---
|
||||
|
||||
## Baking & resetting
|
||||
|
||||
- **Bake** — converts the current preview into real, permanent mesh geometry, restricted to the
|
||||
painted area. Runs in the background; the button shows *Baking…* while it works.
|
||||
- **Erase all** — clears the active layer's paint.
|
||||
|
||||
Baking is the exact same algorithm as the **Normal** preview, so what you see is what you get.
|
||||
|
||||
---
|
||||
|
||||
## Controls reference
|
||||
|
||||
### Mouse — 3D view (while painting)
|
||||
|
||||
| Input | Action |
|
||||
|-------|--------|
|
||||
| Left-drag | Paint the active layer |
|
||||
| Ctrl + drag | Rotate / pan the camera (works in seam mode too) |
|
||||
| Wheel | Zoom |
|
||||
|
||||
### Mouse & keys — UV Editor
|
||||
|
||||
| Input | Action |
|
||||
|-------|--------|
|
||||
| Left-click | Select island |
|
||||
| Left-drag | Move island |
|
||||
| Right-drag | Rotate island |
|
||||
| **R** / **S** | Modal rotate / scale (mouse drives it, click or Enter confirms, Esc cancels) |
|
||||
| **Shift** (while rotating) | Snap to global 15° marks |
|
||||
| Middle-drag | Pan |
|
||||
| Wheel | Zoom about cursor |
|
||||
| **Home** / **F** | Frame all islands |
|
||||
| **Ctrl+Z** / **Ctrl+Shift+Z** / **Ctrl+Y** | Undo / redo |
|
||||
|
||||
### Seam mode
|
||||
|
||||
| Input | Action |
|
||||
|-------|--------|
|
||||
| Click edge | Mark / unmark a seam (yellow = hover, red = marked) |
|
||||
| Click (Path mode) | Set start, then seam the shortest path to the next click |
|
||||
| Ctrl + drag | Rotate / pan camera |
|
||||
|
||||
---
|
||||
|
||||
## Tips & limitations
|
||||
|
||||
- **Paint first, then bake.** The preview is free to explore; only Bake changes the real mesh.
|
||||
- **Not enough detail?** Subdivide or Remesh before painting fine textures.
|
||||
- **Inward cuts** (high Midlevel + big Depth) can self-intersect on thin walls or sharp concave
|
||||
corners — keep Depth modest there.
|
||||
- **Fast vs Normal:** Fast preview shades a bump and shows only the active layer; use it for quick
|
||||
tuning and smooth UV dragging, but trust **Normal**/**Bake** for the exact result.
|
||||
- **Topology changes drop unbaked paint.** Subdivide-Apply, Remesh, and Simplify replace the mesh, and
|
||||
texture-displacement paint isn't remapped across that change (already-baked relief is unaffected).
|
||||
- **Island placements** are tied to the current unwrap. Re-painting or changing the Seam angle can
|
||||
re-segment the charts and renumber them, so a re-unwrap re-lays the connected net and discards
|
||||
hand placements made before it.
|
||||
- **Connect islands** is on by default; turn it off (per layer) for the classic packed-grid layout, or
|
||||
if an unfold looks wrong on an unusual mesh.
|
||||
@@ -59,7 +59,7 @@ while getopts ":dpa:snt:xbc:i:1Tuh" opt; do
|
||||
echo " -c: Set CMake build configuration, default is Release"
|
||||
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
|
||||
echo " -1: Use single job for building"
|
||||
echo " -T: Build and run tests"
|
||||
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
@@ -209,13 +209,10 @@ function build_slicer() {
|
||||
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
|
||||
)
|
||||
# -T also runs the tests; ORCA_TESTS_BUILD_ONLY=1 builds them without
|
||||
# running, so CI can build here and run them in a dedicated job.
|
||||
if [ "1." == "$BUILD_TESTS". ] && [ "1." != "$ORCA_TESTS_BUILD_ONLY". ]; then
|
||||
"$PROJECT_DIR/scripts/run_unit_tests.sh" "build/$_ARCH/tests" "$BUILD_CONFIG"
|
||||
fi
|
||||
|
||||
echo "Verify localization with gettext..."
|
||||
|
||||
@@ -20,6 +20,12 @@ for %%a in (%*) do (
|
||||
if "%%a"=="-x" set USE_NINJA=1
|
||||
)
|
||||
|
||||
@REM Check for unit-tests option ("tests")
|
||||
set BUILD_TESTS=OFF
|
||||
for %%a in (%*) do (
|
||||
if /I "%%a"=="tests" set BUILD_TESTS=ON
|
||||
)
|
||||
|
||||
if "%USE_NINJA%"=="1" (
|
||||
echo Using Ninja Multi-Config generator
|
||||
set CMAKE_GENERATOR="Ninja Multi-Config"
|
||||
@@ -145,10 +151,10 @@ cd %build_dir%
|
||||
echo on
|
||||
set CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
if "%USE_NINJA%"=="1" (
|
||||
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target ALL_BUILD
|
||||
) else (
|
||||
cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target ALL_BUILD -- -m
|
||||
)
|
||||
@echo off
|
||||
|
||||
@@ -41,12 +41,23 @@ src/slic3r/GUI/DeviceCore/DevMapping.h
|
||||
src/slic3r/GUI/DeviceCore/DevMapping.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRack.h
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp
|
||||
src/slic3r/GUI/DeviceCore/DevUtil.h
|
||||
src/slic3r/GUI/DeviceCore/DevUtil.cpp
|
||||
src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h
|
||||
src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp
|
||||
src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h
|
||||
src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h
|
||||
src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
|
||||
@@ -97,6 +108,8 @@ src/slic3r/GUI/Widgets/FilamentLoad.cpp
|
||||
src/slic3r/GUI/Widgets/TempInput.cpp
|
||||
src/slic3r/GUI/Widgets/CheckList.cpp
|
||||
src/slic3r/GUI/Widgets/SwitchButton.cpp
|
||||
src/slic3r/GUI/Widgets/MultiNozzleSync.cpp
|
||||
src/slic3r/GUI/Widgets/ProgressDialog.cpp
|
||||
src/slic3r/GUI/ImGuiWrapper.cpp
|
||||
src/slic3r/GUI/Jobs/ArrangeJob.cpp
|
||||
src/slic3r/GUI/Jobs/OrientJob.cpp
|
||||
@@ -274,4 +287,6 @@ src/slic3r/GUI/DownloaderFileGet.cpp
|
||||
src/slic3r/GUI/FileArchiveDialog.cpp
|
||||
src/slic3r/GUI/PrinterCloudAuthDialog.cpp
|
||||
src/slic3r/GUI/PrinterWebViewHandler.cpp
|
||||
src/slic3r/GUI/AMSDryControl.cpp
|
||||
src/slic3r/GUI/AMSDryControl.hpp
|
||||
src/libslic3r/PresetBundle.cpp
|
||||
|
||||
BIN
resources/images/Big_Nozzle_HH_01_04.png
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
resources/images/Big_Nozzle_HH_01_06.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
resources/images/Big_Nozzle_HH_01_08.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
resources/images/Big_Nozzle_HS_01_02.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
resources/images/Big_Nozzle_HS_01_04.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
resources/images/Big_Nozzle_HS_01_06.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
resources/images/Big_Nozzle_HS_01_08.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
resources/images/Nozzle_HH_01_04.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HH_01_06.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HH_01_08.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HS_01_02.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HS_01_04.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HS_01_06.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/images/Nozzle_HS_01_08.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg width="19" height="20" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.9742 9.65669C13.2353 9.91782 13.2353 10.3401 12.9742 10.5984L7.64038 15.935C7.37924 16.1961 6.95698 16.1961 6.69863 15.935C6.44027 15.6739 6.43749 15.2516 6.69863 14.9933L11.5602 10.1317L6.69585 5.26742C6.43472 5.00628 6.43472 4.58403 6.69585 4.32567C6.95698 4.06731 7.37924 4.06454 7.6376 4.32567L12.9742 9.65669Z" fill="#009688"/>
|
||||
<path d="M12.9742 9.65669C13.2353 9.91782 13.2353 10.3401 12.9742 10.5984L7.64038 15.935C7.37924 16.1961 6.95698 16.1961 6.69863 15.935C6.44027 15.6739 6.43749 15.2516 6.69863 14.9933L11.5602 10.1317L6.69585 5.26742C6.43472 5.00628 6.43472 4.58403 6.69585 4.32567C6.95698 4.06731 7.37924 4.06454 7.6376 4.32567L12.9742 9.65669Z" fill="#949494"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5084 13.1962C10.2472 13.4574 9.82496 13.4574 9.5666 13.1962L4.23003 7.86242C3.9689 7.60129 3.9689 7.17903 4.23003 6.92068C4.49116 6.66232 4.91342 6.65954 5.17178 6.92068L10.0333 11.7822L14.8976 6.9179C15.1588 6.65676 15.581 6.65676 15.8394 6.9179C16.0977 7.17903 16.1005 7.60129 15.8394 7.85965L10.5084 13.1962Z" fill="#009688"/>
|
||||
<path d="M10.5084 13.1962C10.2472 13.4574 9.82496 13.4574 9.5666 13.1962L4.23003 7.86242C3.9689 7.60129 3.9689 7.17903 4.23003 6.92068C4.49116 6.66232 4.91342 6.65954 5.17178 6.92068L10.0333 11.7822L14.8976 6.9179C15.1588 6.65676 15.581 6.65676 15.8394 6.9179C16.0977 7.17903 16.1005 7.60129 15.8394 7.85965L10.5084 13.1962Z" fill="#949494"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 446 B |
4
resources/images/completed_2.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="20" rx="10" fill="#00AF42" fill-opacity="0.2"/>
|
||||
<path d="M14.0828 8.14395L9.08284 13.144C9.0393 13.1877 8.98755 13.2223 8.93057 13.246C8.87359 13.2696 8.81251 13.2818 8.75081 13.2818C8.68912 13.2818 8.62803 13.2696 8.57105 13.246C8.51408 13.2223 8.46233 13.1877 8.41878 13.144L6.23128 10.9565C6.18768 10.9129 6.15309 10.8611 6.12949 10.8041C6.1059 10.7471 6.09375 10.6861 6.09375 10.6244C6.09375 10.5628 6.1059 10.5017 6.12949 10.4447C6.15309 10.3878 6.18768 10.336 6.23128 10.2924C6.27488 10.2488 6.32665 10.2142 6.38362 10.1906C6.44059 10.167 6.50165 10.1549 6.56331 10.1549C6.62498 10.1549 6.68604 10.167 6.74301 10.1906C6.79998 10.2142 6.85174 10.2488 6.89534 10.2924L8.7512 12.1482L13.4196 7.48067C13.5076 7.39261 13.6271 7.34314 13.7516 7.34314C13.8761 7.34314 13.9956 7.39261 14.0836 7.48067C14.1717 7.56873 14.2212 7.68817 14.2212 7.8127C14.2212 7.93724 14.1717 8.05667 14.0836 8.14473L14.0828 8.14395Z" fill="#00AF42" stroke="#00AF42" stroke-width="0.833333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
5
resources/images/dev_ams_dry_ctr_disable.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="9.35422" fill="#E14747" stroke="#E14747" stroke-width="1.29157"/>
|
||||
<rect x="11" y="6" width="2" height="9" rx="1" fill="white"/>
|
||||
<rect x="11" y="16" width="2" height="2" rx="1" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 321 B |
4
resources/images/dev_ams_dry_ctr_enable.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.80005 12.3C1.80005 6.83238 6.23243 2.4 11.7 2.4C17.1677 2.4 21.6 6.83238 21.6 12.3C21.6 17.7676 17.1677 22.2 11.7 22.2C6.23243 22.2 1.80005 17.7676 1.80005 12.3Z" fill="#009688"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.7742 8.66235C18.0746 8.9415 18.0918 9.41131 17.8126 9.7117L12.2128 15.7376C11.5275 16.4751 10.36 16.4751 9.67461 15.7376L6.82482 12.6709C6.54567 12.3706 6.56289 11.9007 6.86328 11.6216C7.16367 11.3424 7.63348 11.3597 7.91263 11.66L10.7624 14.7267C10.8603 14.832 11.0271 14.832 11.125 14.7267L16.7248 8.70081C17.004 8.40042 17.4738 8.3832 17.7742 8.66235Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 759 B |
BIN
resources/images/dev_ams_dry_ctr_filament_in_chamber.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
3
resources/images/dev_ams_dry_ctr_heating_icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.3125 0.7125V2.6125C8.3125 3.00734 7.99484 3.325 7.6 3.325C7.20516 3.325 6.8875 3.00734 6.8875 2.6125V0.7125C6.8875 0.317656 7.20516 0 7.6 0C7.99484 0 8.3125 0.317656 8.3125 0.7125ZM12.9734 3.23297L11.6286 4.57781C11.3495 4.85687 10.8983 4.85687 10.6222 4.57781C10.3461 4.29875 10.3431 3.8475 10.6222 3.57141L11.967 2.22656C12.2461 1.9475 12.6973 1.9475 12.9734 2.22656C13.2495 2.50562 13.2525 2.95688 12.9734 3.23297ZM3.23297 2.22656L4.57781 3.57141C4.85687 3.85047 4.85687 4.30172 4.57781 4.57781C4.29875 4.85391 3.8475 4.85687 3.57141 4.57781L2.22656 3.23297C1.9475 2.95391 1.9475 2.50266 2.22656 2.22656C2.50562 1.95047 2.95688 1.9475 3.23297 2.22656ZM0.7125 6.8875H2.6125C3.00734 6.8875 3.325 7.20516 3.325 7.6C3.325 7.99484 3.00734 8.3125 2.6125 8.3125H0.7125C0.317656 8.3125 0 7.99484 0 7.6C0 7.20516 0.317656 6.8875 0.7125 6.8875ZM12.5875 6.8875H14.4875C14.8823 6.8875 15.2 7.20516 15.2 7.6C15.2 7.99484 14.8823 8.3125 14.4875 8.3125H12.5875C12.1927 8.3125 11.875 7.99484 11.875 7.6C11.875 7.20516 12.1927 6.8875 12.5875 6.8875ZM4.57781 11.6316L3.23297 12.9734C2.95391 13.2525 2.50266 13.2525 2.22656 12.9734C1.95047 12.6944 1.9475 12.2431 2.22656 11.967L3.57141 10.6222C3.85047 10.3431 4.30172 10.3431 4.57781 10.6222C4.85391 10.9012 4.85687 11.3525 4.57781 11.6286V11.6316ZM11.6316 10.6252L12.9734 11.967C13.2525 12.2461 13.2525 12.6973 12.9734 12.9734C12.6944 13.2495 12.2431 13.2525 11.967 12.9734L10.6222 11.6286C10.3431 11.3495 10.3431 10.8983 10.6222 10.6222C10.9012 10.3461 11.3525 10.3431 11.6286 10.6222L11.6316 10.6252ZM8.3125 12.5875V14.4875C8.3125 14.8823 7.99484 15.2 7.6 15.2C7.20516 15.2 6.8875 14.8823 6.8875 14.4875V12.5875C6.8875 12.1927 7.20516 11.875 7.6 11.875C7.99484 11.875 8.3125 12.1927 8.3125 12.5875ZM9.5 7.6C9.5 7.09609 9.29982 6.61282 8.9435 6.2565C8.58718 5.90018 8.10391 5.7 7.6 5.7C7.09609 5.7 6.61282 5.90018 6.2565 6.2565C5.90018 6.61282 5.7 7.09609 5.7 7.6C5.7 8.10391 5.90018 8.58718 6.2565 8.9435C6.61282 9.29982 7.09609 9.5 7.6 9.5C8.10391 9.5 8.58718 9.29982 8.9435 8.9435C9.29982 8.58718 9.5 8.10391 9.5 7.6ZM4.275 7.6C4.275 6.71815 4.62531 5.87243 5.24887 5.24887C5.87243 4.62531 6.71815 4.275 7.6 4.275C8.48184 4.275 9.32757 4.62531 9.95113 5.24887C10.5747 5.87243 10.925 6.71815 10.925 7.6C10.925 8.48184 10.5747 9.32757 9.95113 9.95113C9.32757 10.5747 8.48184 10.925 7.6 10.925C6.71815 10.925 5.87243 10.5747 5.24887 9.95113C4.62531 9.32757 4.275 8.48184 4.275 7.6Z" fill="#F09A17"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3f_cooling.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3f_dehumidifying.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3f_error.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3f_heating.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3s_cooling.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3s_dehumidifying.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3s_error.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
resources/images/dev_ams_dry_ctr_n3s_heating.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
3
resources/images/dev_rack_home.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28.0424 15.4264C28.6059 15.3044 28.7112 14.8962 28.2789 14.5156L16.5815 4.28496C16.1473 3.90625 15.438 3.9044 15.0038 4.28311L3.26759 14.5156C2.83346 14.8943 2.93876 15.3026 3.5022 15.4245L4.90989 15.7275C5.47333 15.8494 5.93332 16.4202 5.93332 16.9966V26.5216C5.93332 27.0979 6.4044 27.569 6.98077 27.569H11.9354C12.5117 27.569 12.9828 27.0979 12.9828 26.5216V21.9512C12.9828 21.3748 13.4539 20.9038 14.0303 20.9038H17.3721C17.9485 20.9038 18.4196 21.3748 18.4196 21.9512V26.5216C18.4196 27.0979 18.8907 27.569 19.467 27.569H24.5657C25.1421 27.569 25.6132 27.0979 25.6132 26.5216V16.9966C25.6132 16.4202 26.0732 15.8494 26.6366 15.7293L28.0424 15.4264Z" fill="#00AE42" fill-opacity="0.2" stroke="#00AE42" stroke-width="0.784708" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 891 B |
16
resources/images/dev_rack_nozzle_empty.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg width="20" height="46" viewBox="0 0 20 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.3">
|
||||
<rect width="20" height="14.6081" fill="#C2C2C2"/>
|
||||
<rect y="7.45947" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="5.28381" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="9.63513" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="11.8108" width="20" height="0.621621" fill="#858585"/>
|
||||
<rect y="13.9865" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="5.71429" y="14.6081" width="8.57143" height="20.8243" fill="#A3A3A3"/>
|
||||
<rect x="4.57144" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<rect x="13.1429" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<path d="M8.85715 43.2027H11.1429L10.4812 45.6892L9.57895 45.6892L8.85715 43.2027Z" fill="#5C5C5C"/>
|
||||
<path d="M4.57144 39.7838H15.4286L14.2857 35.4325H5.7143L4.57144 39.7838Z" fill="#D9D9D9"/>
|
||||
<path d="M4.57144 39.7838H15.4286L12.2857 43.2027L8.00001 43.2027L4.57144 39.7838Z" fill="#C2C2C2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
14
resources/images/dev_rack_nozzle_error.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="20" height="46" viewBox="0 0 20 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="14.6081" fill="#C2C2C2"/>
|
||||
<rect y="7.45947" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="5.28381" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="9.63513" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="11.8108" width="20" height="0.621621" fill="#858585"/>
|
||||
<rect y="13.9865" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="5.71429" y="14.6081" width="8.57143" height="20.8243" fill="#A3A3A3"/>
|
||||
<rect x="4.57141" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<rect x="13.1429" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<path d="M8.85712 43.2027H11.1428L10.4812 45.6892L9.57892 45.6892L8.85712 43.2027Z" fill="#5C5C5C"/>
|
||||
<path d="M4.57141 39.7838H15.4286L14.2857 35.4325H5.71427L4.57141 39.7838Z" fill="#D9D9D9"/>
|
||||
<path d="M4.57141 39.7838H15.4286L12.2857 43.2027L7.99998 43.2027L4.57141 39.7838Z" fill="#C2C2C2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1009 B |
3
resources/images/dev_rack_nozzle_error_icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.99998 2.58331C9.43657 2.58331 10.8143 3.154 11.8301 4.16982C12.846 5.18564 13.4166 6.56339 13.4166 7.99998C13.4166 9.43657 12.846 10.8143 11.8301 11.8301C10.8143 12.846 9.43657 13.4166 7.99998 13.4166C6.56339 13.4166 5.18564 12.846 4.16982 11.8301C3.154 10.8143 2.58331 9.43657 2.58331 7.99998C2.58331 6.56339 3.154 5.18564 4.16982 4.16982C5.18564 3.154 6.56339 2.58331 7.99998 2.58331ZM7.99998 14.6666C9.76809 14.6666 11.4638 13.9643 12.714 12.714C13.9643 11.4638 14.6666 9.76809 14.6666 7.99998C14.6666 6.23187 13.9643 4.53618 12.714 3.28593C11.4638 2.03569 9.76809 1.33331 7.99998 1.33331C6.23187 1.33331 4.53618 2.03569 3.28593 3.28593C2.03569 4.53618 1.33331 6.23187 1.33331 7.99998C1.33331 9.76809 2.03569 11.4638 3.28593 12.714C4.53618 13.9643 6.23187 14.6666 7.99998 14.6666ZM7.99998 4.66665C7.65363 4.66665 7.37498 4.94529 7.37498 5.29165V8.20831C7.37498 8.55467 7.65363 8.83331 7.99998 8.83331C8.34633 8.83331 8.62498 8.55467 8.62498 8.20831V5.29165C8.62498 4.94529 8.34633 4.66665 7.99998 4.66665ZM8.83331 10.5C8.83331 10.279 8.74552 10.067 8.58924 9.91072C8.43295 9.75444 8.22099 9.66665 7.99998 9.66665C7.77897 9.66665 7.567 9.75444 7.41072 9.91072C7.25444 10.067 7.16665 10.279 7.16665 10.5C7.16665 10.721 7.25444 10.933 7.41072 11.0892C7.567 11.2455 7.77897 11.3333 7.99998 11.3333C8.22099 11.3333 8.43295 11.2455 8.58924 11.0892C8.74552 10.933 8.83331 10.721 8.83331 10.5Z" fill="#E14747"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
15
resources/images/dev_rack_nozzle_normal.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg width="20" height="46" viewBox="0 0 20 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="14.6081" fill="#C2C2C2"/>
|
||||
<rect y="7.45947" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="5.28381" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="9.63513" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="11.8108" width="20" height="0.621621" fill="#858585"/>
|
||||
<rect y="13.9865" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="5.71429" y="14.6081" width="8.57143" height="20.8243" fill="#A3A3A3"/>
|
||||
<rect x="9.14285" y="14.6081" width="1.71428" height="20.8243" fill="#FFF735"/>
|
||||
<rect x="4.57144" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<rect x="13.1429" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<path d="M8.85715 43.2027H11.1429L10.4812 45.6892L9.57895 45.6892L8.85715 43.2027Z" fill="#5C5C5C"/>
|
||||
<path d="M4.57144 39.7838H15.4286L14.2857 35.4325H5.7143L4.57144 39.7838Z" fill="#D9D9D9"/>
|
||||
<path d="M4.57144 39.7838H15.4286L12.2857 43.2027L8.00001 43.2027L4.57144 39.7838Z" fill="#C2C2C2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
11
resources/images/dev_rack_nozzle_print_job.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="14" height="22" viewBox="0 0 14 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.400024" width="13.2" height="9.9" fill="#C2C2C2"/>
|
||||
<rect x="0.400024" y="4.3999" width="13.2" height="1.1" fill="#858585"/>
|
||||
<rect x="0.400024" y="6.6001" width="13.2" height="1.1" fill="#858585"/>
|
||||
<rect x="3.70001" y="9.8999" width="6.6" height="6.6" fill="#A3A3A3"/>
|
||||
<rect x="2.60004" y="1.1001" width="2.2" height="2.2" fill="#DBDBDB"/>
|
||||
<rect x="9.20001" y="1.1001" width="2.2" height="2.2" fill="#DBDBDB"/>
|
||||
<path d="M5.90002 19.7998H8.10002L7.46318 21.9998L6.59476 21.9998L5.90002 19.7998Z" fill="#A3A3A3"/>
|
||||
<path d="M2.60004 17.6001H11.4L10.4737 15.4001H3.52635L2.60004 17.6001Z" fill="#D9D9D9"/>
|
||||
<path d="M2.60004 17.6001H11.4L8.85267 19.8001L5.37898 19.8001L2.60004 17.6001Z" fill="#C2C2C2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 813 B |
4
resources/images/dev_rack_nozzle_selected.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 7C20 3.13401 16.866 0 13 0H0L20 20V7Z" fill="#1F1F1F"/>
|
||||
<path d="M12.8252 8.44141L17.4922 3.77441L18.1817 4.46384L12.8252 9.82027L9.48071 6.47575L10.1701 5.78632L12.8252 8.44141Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 311 B |
14
resources/images/dev_rack_nozzle_unknown.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="20" height="46" viewBox="0 0 20 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="14.6081" fill="#C2C2C2"/>
|
||||
<rect y="7.45947" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="5.28381" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="9.63513" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect y="11.8108" width="20" height="0.621621" fill="#858585"/>
|
||||
<rect y="13.9865" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="5.71429" y="14.6081" width="8.57143" height="20.8243" fill="#A3A3A3"/>
|
||||
<rect x="4.57141" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<rect x="13.1429" y="1.86487" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<path d="M8.85712 43.2027H11.1428L10.4812 45.6892L9.57892 45.6892L8.85712 43.2027Z" fill="#5C5C5C"/>
|
||||
<path d="M4.57141 39.7838H15.4286L14.2857 35.4325H5.71427L4.57141 39.7838Z" fill="#D9D9D9"/>
|
||||
<path d="M4.57141 39.7838H15.4286L12.2857 43.2027L7.99998 43.2027L4.57141 39.7838Z" fill="#C2C2C2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1009 B |
3
resources/images/dev_rack_row_up.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 3.875C14.1549 3.875 16.2215 4.73102 17.7452 6.25476C19.269 7.77849 20.125 9.84512 20.125 12C20.125 14.1549 19.269 16.2215 17.7452 17.7452C16.2215 19.269 14.1549 20.125 12 20.125C9.84512 20.125 7.77849 19.269 6.25476 17.7452C4.73102 16.2215 3.875 14.1549 3.875 12C3.875 9.84512 4.73102 7.77849 6.25476 6.25476C7.77849 4.73102 9.84512 3.875 12 3.875ZM12 22C14.6522 22 17.1957 20.9464 19.0711 19.0711C20.9464 17.1957 22 14.6522 22 12C22 9.34784 20.9464 6.8043 19.0711 4.92893C17.1957 3.05357 14.6522 2 12 2C9.34784 2 6.8043 3.05357 4.92893 4.92893C3.05357 6.8043 2 9.34784 2 12C2 14.6522 3.05357 17.1957 4.92893 19.0711C6.8043 20.9464 9.34784 22 12 22ZM16.1016 10.7109L12.6641 7.27344C12.2969 6.90625 11.7031 6.90625 11.3398 7.27344L7.90234 10.7109C7.53516 11.0781 7.53516 11.6719 7.90234 12.0352C8.26953 12.3984 8.86328 12.4023 9.22656 12.0352L11.0625 10.1992V16.0625C11.0625 16.582 11.4805 17 12 17C12.5195 17 12.9375 16.582 12.9375 16.0625V10.1992L14.7734 12.0352C15.1406 12.4023 15.7344 12.4023 16.0977 12.0352C16.4609 11.668 16.4648 11.0742 16.0977 10.7109H16.1016Z" fill="#1F1F1F"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
28
resources/images/dev_rack_toolhead_empty.svg
Normal file
@@ -0,0 +1,28 @@
|
||||
<svg width="98" height="92" viewBox="0 0 98 92" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0H85.4128V76.8716C85.4128 83.0784 80.3812 88.1101 74.1743 88.1101H11.2385C5.03166 88.1101 0 83.0784 0 76.8716V0Z" fill="url(#paint0_linear_1430_186)"/>
|
||||
<path d="M4.04587 0.449524H81.8165V75.9725C81.8165 80.938 77.7912 84.9633 72.8257 84.9633H13.0367C8.0712 84.9633 4.04587 80.938 4.04587 75.9725V0.449524Z" fill="url(#paint1_linear_1430_186)"/>
|
||||
<g opacity="0.3">
|
||||
<path d="M20.6789 54.8441H42.2569V70.4609H20.6789V54.8441Z" fill="#333333"/>
|
||||
<path d="M20.6789 54.8441H42.2569V55.4447H20.6789V54.8441Z" fill="#858585"/>
|
||||
<path d="M20.6789 57.4472H42.2569V58.0479H20.6789V57.4472Z" fill="#858585"/>
|
||||
<path d="M20.6789 60.0494H42.2569V60.6501H20.6789V60.0494Z" fill="#858585"/>
|
||||
<path d="M20.6789 62.6526H42.2569V63.2532H20.6789V62.6526Z" fill="#858585"/>
|
||||
<path d="M20.6789 65.2558H42.2569V65.8564H20.6789V65.2558Z" fill="#858585"/>
|
||||
<path d="M20.6789 67.8589H42.2569V68.4596H20.6789V67.8589Z" fill="#858585"/>
|
||||
<path d="M20.6789 70.4612H42.2569V71.0618H20.6789V70.4612Z" fill="#858585"/>
|
||||
<path d="M29.6258 88.9632H33.0467L32.0965 91.2569H30.6711L29.6258 88.9632Z" fill="#323A3D"/>
|
||||
<path d="M23.5735 71.2891H39.3623V82.4478H23.5735V71.2891Z" fill="#333333"/>
|
||||
<path d="M25.6787 82.4475H36.994V89.2015H25.6787V82.4475Z" fill="#333333"/>
|
||||
</g>
|
||||
<path d="M85.4128 62.9358H98V78.6697H85.4128V62.9358Z" fill="#A5A5A5"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_1430_186" x1="42.7064" y1="0" x2="42.7064" y2="88.1101" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A4A4A4" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#A4A4A4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1430_186" x1="42.9312" y1="0.449524" x2="42.9312" y2="84.9633" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BABABA" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#BABABA"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
42
resources/images/dev_rack_toolhead_normal.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<svg width="98" height="102" viewBox="0 0 98 102" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0H85.4128V77.4975C85.4128 83.7549 80.3812 88.8276 74.1743 88.8276H11.2385C5.03166 88.8276 0 83.7549 0 77.4975V0Z" fill="url(#paint0_linear_4100_4174)"/>
|
||||
<path d="M4.0459 0.453125H81.8166V76.591C81.8166 81.597 77.7912 85.6551 72.8257 85.6551H13.0367C8.07123 85.6551 4.0459 81.597 4.0459 76.591V0.453125Z" fill="url(#paint1_linear_4100_4174)"/>
|
||||
<g opacity="0.1">
|
||||
<path d="M20 56H42V71.4398H20V56Z" fill="#333333"/>
|
||||
<path d="M20 56H42V56.5938H20V56Z" fill="#858585"/>
|
||||
<path d="M20 58.5736H42V59.1674H20V58.5736Z" fill="#858585"/>
|
||||
<path d="M20 61.1464H42V61.7402H20V61.1464Z" fill="#858585"/>
|
||||
<path d="M20 63.72H42V64.3138H20V63.72Z" fill="#858585"/>
|
||||
<path d="M20 66.2937H42V66.8875H20V66.2937Z" fill="#858585"/>
|
||||
<path d="M20 68.8673H42V69.4611H20V68.8673Z" fill="#858585"/>
|
||||
<path d="M20 71.4401H42V72.0339H20V71.4401Z" fill="#858585"/>
|
||||
<path d="M29.1218 89.7323H32.6096L31.6408 92H30.1875L29.1218 89.7323Z" fill="#323A3D"/>
|
||||
<path d="M22.9512 72.2585H39.0487V83.2908H22.9512V72.2585Z" fill="#333333"/>
|
||||
<path d="M25.0977 83.2905H36.6342V89.9679H25.0977V83.2905Z" fill="#333333"/>
|
||||
</g>
|
||||
<path d="M85.4128 63.4482H98V79.3103H85.4128V63.4482Z" fill="#C2C2C2"/>
|
||||
<rect x="47" y="56" width="20" height="14.6081" fill="#C2C2C2"/>
|
||||
<rect x="47" y="63.4595" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="47" y="61.2838" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="47" y="65.6351" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="47" y="67.8108" width="20" height="0.621621" fill="#858585"/>
|
||||
<rect x="47" y="69.9865" width="20" height="0.621622" fill="#858585"/>
|
||||
<rect x="52.7142" y="70.6082" width="8.57143" height="20.8243" fill="#A3A3A3"/>
|
||||
<rect x="56.1428" y="70.6082" width="1.71428" height="20.8243" fill="#FFF735"/>
|
||||
<rect x="51.5714" y="57.8649" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<rect x="60.1428" y="57.8649" width="2.28571" height="2.48649" fill="#DBDBDB"/>
|
||||
<path d="M55.8572 99.2028H58.1429L57.4812 101.689L56.579 101.689L55.8572 99.2028Z" fill="#5C5C5C"/>
|
||||
<path d="M51.5714 95.7838H62.4286L61.2857 91.4325H52.7143L51.5714 95.7838Z" fill="#D9D9D9"/>
|
||||
<path d="M51.5714 95.7838H62.4286L59.2857 99.2027L55 99.2027L51.5714 95.7838Z" fill="#C2C2C2"/>
|
||||
<path d="M54.2189 51V42.2727H57.1678C57.8496 42.2727 58.4093 42.3892 58.8468 42.6222C59.2843 42.8523 59.6081 43.169 59.8184 43.5724C60.0286 43.9759 60.1337 44.4347 60.1337 44.9489C60.1337 45.4631 60.0286 45.919 59.8184 46.3168C59.6081 46.7145 59.2857 47.027 58.851 47.2543C58.4164 47.4787 57.861 47.5909 57.1848 47.5909H54.7985V46.6364H57.1507C57.6167 46.6364 57.9917 46.5682 58.2757 46.4318C58.5627 46.2955 58.7701 46.1023 58.8979 45.8523C59.0286 45.5994 59.0939 45.2983 59.0939 44.9489C59.0939 44.5994 59.0286 44.294 58.8979 44.0327C58.7672 43.7713 58.5584 43.5696 58.2715 43.4276C57.9846 43.2827 57.6053 43.2102 57.1337 43.2102H55.2757V51H54.2189ZM58.3269 47.0795L60.4746 51H59.2473L57.1337 47.0795H58.3269Z" fill="black"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4100_4174" x1="42.7064" y1="0" x2="42.7064" y2="88.8276" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BAB7B7" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#BAB7B7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4100_4174" x1="42.9312" y1="0.453125" x2="42.9312" y2="85.6551" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D7D5D5" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#D7D5D5"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
3
resources/images/error.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.23759 3.02832C9.67418 3.02832 11.0519 3.599 12.0678 4.61483C13.0836 5.63065 13.6543 7.0084 13.6543 8.44499C13.6543 9.88158 13.0836 11.2593 12.0678 12.2751C11.0519 13.291 9.67418 13.8617 8.23759 13.8617C6.801 13.8617 5.42325 13.291 4.40743 12.2751C3.39161 11.2593 2.82092 9.88158 2.82092 8.44499C2.82092 7.0084 3.39161 5.63065 4.40743 4.61483C5.42325 3.599 6.801 3.02832 8.23759 3.02832ZM8.23759 15.1117C10.0057 15.1117 11.7014 14.4093 12.9516 13.159C14.2019 11.9088 14.9043 10.2131 14.9043 8.44499C14.9043 6.67688 14.2019 4.98118 12.9516 3.73094C11.7014 2.4807 10.0057 1.77832 8.23759 1.77832C6.46948 1.77832 4.77379 2.4807 3.52354 3.73094C2.2733 4.98118 1.57092 6.67688 1.57092 8.44499C1.57092 10.2131 2.2733 11.9088 3.52354 13.159C4.77379 14.4093 6.46948 15.1117 8.23759 15.1117ZM8.23759 5.11165C7.89124 5.11165 7.61259 5.3903 7.61259 5.73665V8.65332C7.61259 8.99967 7.89124 9.27832 8.23759 9.27832C8.58394 9.27832 8.86259 8.99967 8.86259 8.65332V5.73665C8.86259 5.3903 8.58394 5.11165 8.23759 5.11165ZM9.07092 10.945C9.07092 10.724 8.98313 10.512 8.82685 10.3557C8.67056 10.1995 8.4586 10.1117 8.23759 10.1117C8.01658 10.1117 7.80461 10.1995 7.64833 10.3557C7.49205 10.512 7.40426 10.724 7.40426 10.945C7.40426 11.166 7.49205 11.378 7.64833 11.5342C7.80461 11.6905 8.01658 11.7783 8.23759 11.7783C8.4586 11.7783 8.67056 11.6905 8.82685 11.5342C8.98313 11.378 9.07092 11.166 9.07092 10.945Z" fill="#D01B1B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
47
resources/images/extruder_badge_both_selected.svg
Normal file
@@ -0,0 +1,47 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652832H101.727V92.8972C101.727 99.8008 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8008 0.625977 92.8972V0.652832Z" fill="url(#paint0_linear_3544_2531)"/>
|
||||
<path d="M5.41504 1.18701H97.4703V91.6561C97.4703 97.179 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.179 5.41504 91.6561V1.18701Z" fill="url(#paint1_linear_3544_2531)"/>
|
||||
<rect x="101.727" y="75.4702" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<rect x="64.6074" y="81.0449" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="64.6074" y="89.335" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.6074" y="86.917" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.6074" y="91.7529" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.6074" y="94.1714" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.6074" y="96.5894" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="71.0664" y="97.2803" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.9414" y="97.2803" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="69.7744" y="83.1172" width="2.58372" height="2.76346" fill="#DBDBDB"/>
|
||||
<rect x="79.4629" y="83.1172" width="2.58372" height="2.76346" fill="#DBDBDB"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824L75.4351 131.824L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#D9D9D9"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06L73.65 129.06L69.7744 125.26Z" fill="#C2C2C2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M88.2139 98.248H81.7539V120.259L83.1562 125.507L82.7773 125.911L78.9277 130.027H77.9688L77.4199 132.053L77.2207 132.791H74.6875L73.8711 130.027H73.2422L68.6572 125.534L68.8086 124.971L70.0654 120.266V98.248H63.6064V80.0127H88.2139V98.248ZM75.4346 131.791H76.4551L77.2031 129.028H74.6191L75.4346 131.791ZM69.7744 125.229L73.6504 129.027H78.4941L82.0469 125.229L80.7549 120.393H71.0664L69.7744 125.229ZM64.6064 97.248H71.0654V120.392H80.7539V97.248H87.2139V81.0127H64.6064V97.248Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6042C67.9434 85.2044 71.5101 81.6033 75.9098 81.6033C80.3096 81.6033 83.8763 85.2044 83.8763 89.6042C83.8763 94.004 80.3096 97.6051 75.9098 97.6051C71.5101 97.6051 67.9434 94.004 67.9434 89.6042Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6042C67.9434 85.2044 71.5101 81.6033 75.9098 81.6033C80.3096 81.6033 83.8763 85.2044 83.8763 89.6042C83.8763 94.004 80.3096 97.6051 75.9098 97.6051C71.5101 97.6051 67.9434 94.004 67.9434 89.6042Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M74.7449 92.9745L71.9268 90.1442L73.3308 88.734L74.7349 90.1442L78.2601 86.6038L79.6642 88.0139L74.7449 92.9745Z" fill="white"/>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#C2C2C2"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#858585"/>
|
||||
<path d="M18.5156 83.1068H44.057V83.8208H18.5156V83.1068Z" fill="#858585"/>
|
||||
<path d="M18.5156 86.2004H44.057V86.9144H18.5156V86.2004Z" fill="#858585"/>
|
||||
<path d="M18.5156 89.2955H44.057V90.0094H18.5156V89.2955Z" fill="#858585"/>
|
||||
<path d="M18.5156 92.3901H44.057V93.104H18.5156V92.3901Z" fill="#858585"/>
|
||||
<path d="M18.5156 95.4851H44.057V96.1991H18.5156V95.4851Z" fill="#858585"/>
|
||||
<path d="M18.5156 98.5779H44.057V99.2922H18.5156V98.5779Z" fill="#858585"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#D9D9D9"/>
|
||||
<path d="M21.9424 99.5618H40.6312V112.827H21.9424V99.5618Z" fill="#A3A3A3"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#A3A3A3"/>
|
||||
<path d="M18.5156 80.0127V99.292H21.9424V112.827H24.4355V120.856H29.2354L30.3438 123.3H32.0312L33.0381 120.856H37.8291V112.827H40.6309V99.292H44.0566V80.0127H18.5156ZM45.0566 100.292H41.6309V113.827H38.8291V121.856H33.708L32.7012 124.3H29.6992L28.5908 121.856H23.4355V113.827H20.9424V100.292H17.5156V79.0127H45.0566V100.292Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9478C22.9863 84.548 26.553 80.9469 30.9528 80.9469C35.3526 80.9469 38.9193 84.548 38.9193 88.9478C38.9193 93.3475 35.3526 96.9486 30.9528 96.9486C26.553 96.9486 22.9863 93.3475 22.9863 88.9478Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9478C22.9863 84.548 26.553 80.9469 30.9528 80.9469C35.3526 80.9469 38.9193 84.548 38.9193 88.9478C38.9193 93.3475 35.3526 96.9486 30.9528 96.9486C26.553 96.9486 22.9863 93.3475 22.9863 88.9478Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M29.7877 92.3181L26.9696 89.4878L28.3737 88.0777L29.7777 89.4878L33.3029 85.9474L34.707 87.3576L29.7877 92.3181Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3544_2531" x1="51.1766" y1="0.652832" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3544_2531" x1="51.4427" y1="1.18701" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
47
resources/images/extruder_badge_both_selected_dark.svg
Normal file
@@ -0,0 +1,47 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_4627_4051)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_4627_4051)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M88.2139 98.248H81.7539V120.259L83.1562 125.507L82.7773 125.911L78.9277 130.027H77.9688L77.4199 132.053L77.2207 132.791H74.6875L73.8711 130.027H73.2422L68.6572 125.534L68.8086 124.971L70.0654 120.266V98.248H63.6064V80.0127H88.2139V98.248ZM75.4346 131.791H76.4551L77.2031 129.028H74.6191L75.4346 131.791ZM69.7744 125.229L73.6504 129.027H78.4941L82.0469 125.229L80.7549 120.393H71.0664L69.7744 125.229ZM64.6064 97.248H71.0654V120.392H80.7539V97.248H87.2139V81.0127H64.6064V97.248Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6044C67.9434 85.2046 71.5101 81.6035 75.9098 81.6035C80.3096 81.6035 83.8763 85.2046 83.8763 89.6044C83.8763 94.0042 80.3096 97.6053 75.9098 97.6053C71.5101 97.6053 67.9434 94.0042 67.9434 89.6044Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6044C67.9434 85.2046 71.5101 81.6035 75.9098 81.6035C80.3096 81.6035 83.8763 85.2046 83.8763 89.6044C83.8763 94.0042 80.3096 97.6053 75.9098 97.6053C71.5101 97.6053 67.9434 94.0042 67.9434 89.6044Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M74.7449 92.9742L71.9268 90.1439L73.3308 88.7337L74.7349 90.1439L78.2601 86.6035L79.6642 88.0136L74.7449 92.9742Z" fill="white"/>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<path d="M18.5156 80.0127V99.292H21.9424V112.827H24.4355V120.856H29.2354L30.3438 123.3H32.0312L33.0381 120.856H37.8291V112.827H40.6309V99.292H44.0566V80.0127H18.5156ZM45.0566 100.292H41.6309V113.827H38.8291V121.856H33.708L32.7012 124.3H29.6992L28.5908 121.856H23.4355V113.827H20.9424V100.292H17.5156V79.0127H45.0566V100.292Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M29.7878 92.318L26.9697 89.4877L28.3738 88.0776L29.7778 89.4877L33.303 85.9473L34.7071 87.3575L29.7878 92.318Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4627_4051" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4627_4051" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.0 KiB |
43
resources/images/extruder_badge_left_selected.svg
Normal file
@@ -0,0 +1,43 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.15332 0.652832H101.255V92.8972C101.255 99.8008 95.6581 105.397 88.7545 105.397H12.6533C5.74977 105.397 0.15332 99.8008 0.15332 92.8972V0.652832Z" fill="url(#paint0_linear_3544_2528)"/>
|
||||
<path d="M4.94238 1.18701H96.9977V91.6561C96.9977 97.179 92.5205 101.656 86.9977 101.656H14.9424C9.41955 101.656 4.94238 97.179 4.94238 91.6561V1.18701Z" fill="url(#paint1_linear_3544_2528)"/>
|
||||
<path d="M17.0439 80.0127H42.5853V98.5779H17.0439V80.0127Z" fill="#C2C2C2"/>
|
||||
<path d="M17.0439 80.0127H42.5853V80.7267H17.0439V80.0127Z" fill="#858585"/>
|
||||
<path d="M17.0439 83.1068H42.5853V83.8208H17.0439V83.1068Z" fill="#858585"/>
|
||||
<path d="M17.0439 86.2004H42.5853V86.9144H17.0439V86.2004Z" fill="#858585"/>
|
||||
<path d="M17.0439 89.2955H42.5853V90.0094H17.0439V89.2955Z" fill="#858585"/>
|
||||
<path d="M17.0439 92.3901H42.5853V93.104H17.0439V92.3901Z" fill="#858585"/>
|
||||
<path d="M17.0439 95.4851H42.5853V96.1991H17.0439V95.4851Z" fill="#858585"/>
|
||||
<path d="M17.0439 98.5779H42.5853V99.2922H17.0439V98.5779Z" fill="#858585"/>
|
||||
<path d="M27.6348 120.573H31.684L30.5592 123.299H28.872L27.6348 120.573Z" fill="#D9D9D9"/>
|
||||
<path d="M20.4707 99.5618H39.1595V112.827H20.4707V99.5618Z" fill="#A3A3A3"/>
|
||||
<path d="M22.9639 112.827H36.3575V120.856H22.9639V112.827Z" fill="#A3A3A3"/>
|
||||
<path d="M17.0439 80.0127V99.292H20.4707V112.827H22.9639V120.856H27.7637L28.8721 123.3H30.5596L31.5664 120.856H36.3574V112.827H39.1592V99.292H42.585V80.0127H17.0439ZM43.585 100.292H40.1592V113.827H37.3574V121.856H32.2363L31.2295 124.3H28.2275L27.1191 121.856H21.9639V113.827H19.4707V100.292H16.0439V79.0127H43.585V100.292Z" fill="#009688"/>
|
||||
<path d="M21.5146 88.9478C21.5146 84.548 25.0814 80.9469 29.4811 80.9469C33.8809 80.9469 37.4476 84.548 37.4476 88.9478C37.4476 93.3475 33.8809 96.9486 29.4811 96.9486C25.0814 96.9486 21.5146 93.3475 21.5146 88.9478Z" fill="#009688"/>
|
||||
<path d="M21.5146 88.9478C21.5146 84.548 25.0814 80.9469 29.4811 80.9469C33.8809 80.9469 37.4476 84.548 37.4476 88.9478C37.4476 93.3475 33.8809 96.9486 29.4811 96.9486C25.0814 96.9486 21.5146 93.3475 21.5146 88.9478Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M28.316 92.3181L25.4979 89.4878L26.902 88.0777L28.3061 89.4878L31.8312 85.9474L33.2353 87.3576L28.316 92.3181Z" fill="white"/>
|
||||
<rect x="63.7783" y="80.8379" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="63.7783" y="89.1284" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="86.71" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="91.5464" width="22.6076" height="0.690789" fill="#858585"/>
|
||||
<rect x="63.7783" y="93.9644" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="96.3823" width="22.6076" height="0.690788" fill="#858585"/>
|
||||
<rect x="70.2383" y="97.0732" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.1133" y="97.0732" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="68.9463" y="82.9106" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<rect x="78.6348" y="82.9106" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<path d="M73.791 128.853H76.3747L75.6268 131.616L74.6069 131.616L73.791 128.853Z" fill="#5C5C5C"/>
|
||||
<path d="M68.9463 125.053H81.219L79.9271 120.218H70.2381L68.9463 125.053Z" fill="#D9D9D9"/>
|
||||
<path d="M68.9463 125.053H81.219L77.6663 128.853L72.8219 128.853L68.9463 125.053Z" fill="#C2C2C2"/>
|
||||
<rect x="101.254" y="75.4702" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3544_2528" x1="50.7039" y1="0.652832" x2="50.7039" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3544_2528" x1="50.97" y1="1.18701" x2="50.97" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
43
resources/images/extruder_badge_left_selected_dark.svg
Normal file
@@ -0,0 +1,43 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_4627_4246)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_4627_4246)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<path d="M18.5156 80.0127V99.292H21.9424V112.827H24.4355V120.856H29.2354L30.3438 123.3H32.0312L33.0381 120.856H37.8291V112.827H40.6309V99.292H44.0566V80.0127H18.5156ZM45.0566 100.292H41.6309V113.827H38.8291V121.856H33.708L32.7012 124.3H29.6992L28.5908 121.856H23.4355V113.827H20.9424V100.292H17.5156V79.0127H45.0566V100.292Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M29.7878 92.318L26.9697 89.4877L28.3738 88.0776L29.7778 89.4877L33.303 85.9473L34.7071 87.3575L29.7878 92.318Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4627_4246" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4627_4246" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
45
resources/images/extruder_badge_left_selected_single.svg
Normal file
@@ -0,0 +1,45 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.15332 0.786133H101.255V93.0305C101.255 99.9341 95.6581 105.531 88.7545 105.531H12.6533C5.74977 105.531 0.15332 99.9341 0.15332 93.0305V0.786133Z" fill="url(#paint0_linear_3544_2532)"/>
|
||||
<path d="M4.94238 1.32031H96.9977V91.7894C96.9977 97.3123 92.5205 101.789 86.9977 101.789H14.9424C9.41955 101.789 4.94238 97.3123 4.94238 91.7894V1.32031Z" fill="url(#paint1_linear_3544_2532)"/>
|
||||
<rect x="101.254" y="75.6035" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<rect x="17.0439" y="80.146" width="25.5414" height="18.5652" fill="#C2C2C2"/>
|
||||
<rect x="17.0439" y="80.146" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="83.2402" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="86.3335" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="89.4287" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="92.5234" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="95.6187" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.0439" y="98.7114" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<path d="M27.6348 120.706H31.684L30.5592 123.433H28.872L27.6348 120.706Z" fill="#D9D9D9"/>
|
||||
<rect x="20.4707" y="99.6948" width="18.6888" height="13.2655" fill="#A3A3A3"/>
|
||||
<rect x="22.9639" y="112.96" width="13.3936" height="8.0282" fill="#A3A3A3"/>
|
||||
<path d="M43.085 79.646V99.9253H39.6592V113.46H36.8574V121.49H31.9004L31.0215 123.624L30.8945 123.933H28.5498L28.417 123.64L27.4414 121.49H22.4639V113.46H19.9707V99.9253H16.5439V79.646H43.085Z" stroke="#009688"/>
|
||||
<path d="M21.5146 89.081C21.5146 84.6812 25.0814 81.0801 29.4811 81.0801C33.8809 81.0801 37.4476 84.6812 37.4476 89.081C37.4476 93.4807 33.8809 97.0819 29.4811 97.0819C25.0814 97.0819 21.5146 93.4807 21.5146 89.081Z" fill="#009688"/>
|
||||
<path d="M21.5146 89.081C21.5146 84.6812 25.0814 81.0801 29.4811 81.0801C33.8809 81.0801 37.4476 84.6812 37.4476 89.081C37.4476 93.4807 33.8809 97.0819 29.4811 97.0819C25.0814 97.0819 21.5146 93.4807 21.5146 89.081Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M28.316 92.4513L25.4979 89.621L26.902 88.2109L28.3061 89.621L31.8312 86.0806L33.2353 87.4908L28.316 92.4513Z" fill="white"/>
|
||||
<g opacity="0.2">
|
||||
<rect x="63.7783" y="80.9707" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="63.7783" y="89.2617" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="86.8433" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="91.6797" width="22.6076" height="0.690789" fill="#858585"/>
|
||||
<rect x="63.7783" y="94.0977" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.7783" y="96.5156" width="22.6076" height="0.690788" fill="#858585"/>
|
||||
<rect x="70.2383" y="97.2065" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.1133" y="97.2065" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="68.9463" y="83.0439" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<rect x="78.6348" y="83.0439" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<path d="M73.791 128.986H76.3747L75.6268 131.749L74.6069 131.749L73.791 128.986Z" fill="#5C5C5C"/>
|
||||
<path d="M68.9463 125.187H81.219L79.9271 120.351H70.2381L68.9463 125.187Z" fill="#D9D9D9"/>
|
||||
<path d="M68.9463 125.187H81.219L77.6663 128.986L72.8219 128.986L68.9463 125.187Z" fill="#C2C2C2"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3544_2532" x1="50.7039" y1="0.786133" x2="50.7039" y2="105.531" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3544_2532" x1="50.97" y1="1.32031" x2="50.97" y2="101.789" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,45 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_4627_4314)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_4627_4314)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<g opacity="0.2">
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
</g>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<path d="M18.5156 80.0127V99.292H21.9424V112.827H24.4355V120.856H29.2354L30.3438 123.3H32.0312L33.0381 120.856H37.8291V112.827H40.6309V99.292H44.0566V80.0127H18.5156ZM45.0566 100.292H41.6309V113.827H38.8291V121.856H33.708L32.7012 124.3H29.6992L28.5908 121.856H23.4355V113.827H20.9424V100.292H17.5156V79.0127H45.0566V100.292Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="#009688"/>
|
||||
<path d="M22.9863 88.9482C22.9863 84.5484 26.553 80.9473 30.9528 80.9473C35.3526 80.9473 38.9193 84.5484 38.9193 88.9482C38.9193 93.3479 35.3526 96.949 30.9528 96.949C26.553 96.949 22.9863 93.3479 22.9863 88.9482Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M29.7878 92.318L26.9697 89.4877L28.3738 88.0776L29.7778 89.4877L33.303 85.9473L34.7071 87.3575L29.7878 92.318Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4627_4314" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4627_4314" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
39
resources/images/extruder_badge_none_selected.svg
Normal file
@@ -0,0 +1,39 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.234375 0.652832H101.336V92.8972C101.336 99.8008 95.7391 105.397 88.8356 105.397H12.7344C5.83083 105.397 0.234375 99.8008 0.234375 92.8972V0.652832Z" fill="url(#paint0_linear_3482_2442)"/>
|
||||
<path d="M5.02344 1.18701H97.0787V91.6561C97.0787 97.179 92.6016 101.656 87.0787 101.656H15.0234C9.5006 101.656 5.02344 97.179 5.02344 91.6561V1.18701Z" fill="url(#paint1_linear_3482_2442)"/>
|
||||
<rect x="17.125" y="80.0127" width="25.5414" height="18.5652" fill="#C2C2C2"/>
|
||||
<rect x="17.125" y="80.0127" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="83.1069" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="86.2002" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="89.2954" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="92.3901" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="95.4854" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.125" y="98.5781" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<path d="M27.7158 120.573H31.7651L30.6403 123.299H28.9531L27.7158 120.573Z" fill="#D9D9D9"/>
|
||||
<rect x="20.5518" y="99.5615" width="18.6888" height="13.2655" fill="#A3A3A3"/>
|
||||
<rect x="23.0449" y="112.827" width="13.3936" height="8.0282" fill="#A3A3A3"/>
|
||||
<rect x="101.335" y="75.4702" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<rect x="63.8594" y="80.8379" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="63.8594" y="89.1284" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.8594" y="86.71" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.8594" y="91.5464" width="22.6076" height="0.690789" fill="#858585"/>
|
||||
<rect x="63.8594" y="93.9644" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.8594" y="96.3823" width="22.6076" height="0.690788" fill="#858585"/>
|
||||
<rect x="70.3193" y="97.0732" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.1943" y="97.0732" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="69.0273" y="82.9106" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<rect x="78.7158" y="82.9106" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<path d="M73.8721 128.853H76.4558L75.7079 131.616L74.688 131.616L73.8721 128.853Z" fill="#5C5C5C"/>
|
||||
<path d="M69.0273 125.053H81.3L80.0082 120.218H70.3192L69.0273 125.053Z" fill="#D9D9D9"/>
|
||||
<path d="M69.0273 125.053H81.3L77.7474 128.853L72.9029 128.853L69.0273 125.053Z" fill="#C2C2C2"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3482_2442" x1="50.785" y1="0.652832" x2="50.785" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3482_2442" x1="51.0511" y1="1.18701" x2="51.0511" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
39
resources/images/extruder_badge_none_selected_dark.svg
Normal file
@@ -0,0 +1,39 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_4627_4455)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_4627_4455)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4627_4455" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4627_4455" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
41
resources/images/extruder_badge_none_selected_single.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.355469 0.786133H101.457V93.0305C101.457 99.9341 95.8602 105.531 88.9567 105.531H12.8555C5.95192 105.531 0.355469 99.9341 0.355469 93.0305V0.786133Z" fill="url(#paint0_linear_3482_2486)"/>
|
||||
<path d="M5.14453 1.32031H97.1998V91.7894C97.1998 97.3123 92.7227 101.789 87.1998 101.789H15.1445C9.62169 101.789 5.14453 97.3123 5.14453 91.7894V1.32031Z" fill="url(#paint1_linear_3482_2486)"/>
|
||||
<rect x="17.2461" y="80.146" width="25.5414" height="18.5652" fill="#C2C2C2"/>
|
||||
<rect x="17.2461" y="80.146" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="83.2402" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="86.3335" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="89.4287" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="92.5234" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="95.6187" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.2461" y="98.7114" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<path d="M27.8369 120.706H31.8862L30.7614 123.433H29.0742L27.8369 120.706Z" fill="#D9D9D9"/>
|
||||
<rect x="20.6729" y="99.6948" width="18.6888" height="13.2655" fill="#A3A3A3"/>
|
||||
<rect x="23.166" y="112.96" width="13.3936" height="8.0282" fill="#A3A3A3"/>
|
||||
<rect x="101.456" y="75.6035" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<g opacity="0.2">
|
||||
<rect x="63.9805" y="80.9707" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="63.9805" y="89.2617" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.9805" y="86.8433" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.9805" y="91.6797" width="22.6076" height="0.690789" fill="#858585"/>
|
||||
<rect x="63.9805" y="94.0977" width="22.6076" height="0.69079" fill="#858585"/>
|
||||
<rect x="63.9805" y="96.5156" width="22.6076" height="0.690788" fill="#858585"/>
|
||||
<rect x="70.4404" y="97.2065" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.3154" y="97.2065" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="69.1484" y="83.0439" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<rect x="78.8369" y="83.0439" width="2.58372" height="2.76316" fill="#DBDBDB"/>
|
||||
<path d="M73.9932 128.986H76.5769L75.829 131.749L74.8091 131.749L73.9932 128.986Z" fill="#5C5C5C"/>
|
||||
<path d="M69.1484 125.187H81.4211L80.1293 120.351H70.4403L69.1484 125.187Z" fill="#D9D9D9"/>
|
||||
<path d="M69.1484 125.187H81.4211L77.8685 128.986L73.024 128.986L69.1484 125.187Z" fill="#C2C2C2"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3482_2486" x1="50.9061" y1="0.786133" x2="50.9061" y2="105.531" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3482_2486" x1="51.1722" y1="1.32031" x2="51.1722" y2="101.789" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,41 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_8941_38592)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_8941_38592)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<g opacity="0.2">
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
</g>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_8941_38592" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_8941_38592" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
43
resources/images/extruder_badge_right_selected.svg
Normal file
@@ -0,0 +1,43 @@
|
||||
<svg width="117" height="133" viewBox="0 0 117 133" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.544922 0.652832H101.646V92.8972C101.646 99.8008 96.0497 105.397 89.1461 105.397H13.0449C6.14138 105.397 0.544922 99.8008 0.544922 92.8972V0.652832Z" fill="url(#paint0_linear_3544_2529)"/>
|
||||
<path d="M5.33398 1.18701H97.3893V91.6561C97.3893 97.179 92.9121 101.656 87.3893 101.656H15.334C9.81115 101.656 5.33398 97.179 5.33398 91.6561V1.18701Z" fill="url(#paint1_linear_3544_2529)"/>
|
||||
<rect x="17.4355" y="80.0127" width="25.5414" height="18.5652" fill="#C2C2C2"/>
|
||||
<rect x="17.4355" y="80.0127" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="83.1069" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="86.2002" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="89.2954" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="92.3901" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="95.4854" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<rect x="17.4355" y="98.5781" width="25.5414" height="0.713966" fill="#858585"/>
|
||||
<path d="M28.0264 120.573H32.0756L30.9508 123.299H29.2636L28.0264 120.573Z" fill="#D9D9D9"/>
|
||||
<rect x="20.8623" y="99.5615" width="18.6888" height="13.2655" fill="#A3A3A3"/>
|
||||
<rect x="23.3555" y="112.827" width="13.3936" height="8.0282" fill="#A3A3A3"/>
|
||||
<rect x="101.646" y="75.4702" width="14.8991" height="18.7044" fill="#D1D1D1"/>
|
||||
<rect x="64.1699" y="80.8379" width="22.6076" height="16.2354" fill="#C2C2C2"/>
|
||||
<rect x="64.1699" y="89.1279" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.1699" y="86.71" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.1699" y="91.5459" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.1699" y="93.9644" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="64.1699" y="96.3823" width="22.6076" height="0.690866" fill="#858585"/>
|
||||
<rect x="70.6299" y="97.0732" width="9.68895" height="23.144" fill="#A3A3A3"/>
|
||||
<rect x="74.5059" y="97.0732" width="1.93779" height="23.144" fill="#E1E1E1"/>
|
||||
<rect x="69.3379" y="82.9102" width="2.58372" height="2.76346" fill="#DBDBDB"/>
|
||||
<rect x="79.0273" y="82.9102" width="2.58372" height="2.76346" fill="#DBDBDB"/>
|
||||
<path d="M74.1816 128.853H76.7654L76.0174 131.616L74.9976 131.616L74.1816 128.853Z" fill="#5C5C5C"/>
|
||||
<path d="M69.3379 125.053H81.6106L80.3187 120.217H70.6298L69.3379 125.053Z" fill="#D9D9D9"/>
|
||||
<path d="M69.3379 125.053H81.6106L78.0579 128.853L73.2135 128.853L69.3379 125.053Z" fill="#C2C2C2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M87.7773 98.041H81.3174V120.052L82.7197 125.3L82.3408 125.704L78.4912 129.82H77.5322L76.9834 131.846L76.7842 132.584H74.251L73.4346 129.82H72.8057L68.2207 125.327L68.3721 124.764L69.6289 120.059V98.041H63.1699V79.8057H87.7773V98.041ZM74.998 131.584H76.0186L76.7666 128.821H74.1826L74.998 131.584ZM69.3379 125.021L73.2139 128.82H78.0576L81.6104 125.021L80.3184 120.186H70.6299L69.3379 125.021ZM64.1699 97.041H70.6289V120.185H80.3174V97.041H86.7773V80.8057H64.1699V97.041Z" fill="#009688"/>
|
||||
<path d="M67.5068 89.3972C67.5068 84.9974 71.0735 81.3963 75.4733 81.3963C79.8731 81.3963 83.4398 84.9974 83.4398 89.3972C83.4398 93.7969 79.8731 97.398 75.4733 97.398C71.0735 97.398 67.5068 93.7969 67.5068 89.3972Z" fill="#009688"/>
|
||||
<path d="M67.5068 89.3972C67.5068 84.9974 71.0735 81.3963 75.4733 81.3963C79.8731 81.3963 83.4398 84.9974 83.4398 89.3972C83.4398 93.7969 79.8731 97.398 75.4733 97.398C71.0735 97.398 67.5068 93.7969 67.5068 89.3972Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M74.3084 92.7675L71.4902 89.9372L72.8943 88.527L74.2984 89.9372L77.8236 86.3968L79.2277 87.8069L74.3084 92.7675Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3544_2529" x1="51.0955" y1="0.652832" x2="51.0955" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#333333" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#333333" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_3544_2529" x1="51.3616" y1="1.18701" x2="51.3616" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#474747" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#474747" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
43
resources/images/extruder_badge_right_selected_dark.svg
Normal file
@@ -0,0 +1,43 @@
|
||||
<svg width="118" height="136" viewBox="0 0 118 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.625977 0.652344H101.727V92.8967C101.727 99.8003 96.1307 105.397 89.2272 105.397H13.126C6.22243 105.397 0.625977 99.8003 0.625977 92.8967V0.652344Z" fill="url(#paint0_linear_4627_4383)"/>
|
||||
<path d="M5.41504 1.18652H97.4703V91.6556C97.4703 97.1785 92.9932 101.656 87.4703 101.656H15.415C9.8922 101.656 5.41504 97.1785 5.41504 91.6556V1.18652Z" fill="url(#paint1_linear_4627_4383)"/>
|
||||
<path d="M116.626 75.4697H101.727V94.1741H116.626V75.4697Z" fill="#646464"/>
|
||||
<path d="M87.215 81.0449H64.6074V97.2803H87.215V81.0449Z" fill="#959595"/>
|
||||
<path d="M87.215 89.335H64.6074V90.0258H87.215V89.335Z" fill="#858585"/>
|
||||
<path d="M87.215 86.917H64.6074V87.6079H87.215V86.917Z" fill="#858585"/>
|
||||
<path d="M87.215 91.7529H64.6074V92.4438H87.215V91.7529Z" fill="#858585"/>
|
||||
<path d="M87.215 94.1719H64.6074V94.8627H87.215V94.1719Z" fill="#858585"/>
|
||||
<path d="M87.215 96.5898H64.6074V97.2807H87.215V96.5898Z" fill="#858585"/>
|
||||
<path d="M80.7554 97.2803H71.0664V120.424H80.7554V97.2803Z" fill="#737373"/>
|
||||
<path d="M76.8792 97.2803H74.9414V120.424H76.8792V97.2803Z" fill="#9D9D9D"/>
|
||||
<path d="M72.3581 83.1172H69.7744V85.8806H72.3581V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M82.0466 83.1172H79.4629V85.8806H82.0466V83.1172Z" fill="#B3B3B3"/>
|
||||
<path d="M74.6191 129.06H77.2029L76.4549 131.824H75.4351L74.6191 129.06Z" fill="#5C5C5C"/>
|
||||
<path d="M69.7744 125.26H82.0471L80.7552 120.424H71.0663L69.7744 125.26Z" fill="#9F9F9F"/>
|
||||
<path d="M69.7744 125.26H82.0471L78.4945 129.06H73.65L69.7744 125.26Z" fill="#8F8F8F"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M88.2139 98.248H81.7539V120.259L83.1562 125.507L82.7773 125.911L78.9277 130.027H77.9688L77.4199 132.053L77.2207 132.791H74.6875L73.8711 130.027H73.2422L68.6572 125.534L68.8086 124.971L70.0654 120.266V98.248H63.6064V80.0127H88.2139V98.248ZM75.4346 131.791H76.4551L77.2031 129.028H74.6191L75.4346 131.791ZM69.7744 125.229L73.6504 129.027H78.4941L82.0469 125.229L80.7549 120.393H71.0664L69.7744 125.229ZM64.6064 97.248H71.0654V120.392H80.7539V97.248H87.2139V81.0127H64.6064V97.248Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6044C67.9434 85.2046 71.5101 81.6035 75.9098 81.6035C80.3096 81.6035 83.8763 85.2046 83.8763 89.6044C83.8763 94.0042 80.3096 97.6053 75.9098 97.6053C71.5101 97.6053 67.9434 94.0042 67.9434 89.6044Z" fill="#009688"/>
|
||||
<path d="M67.9434 89.6044C67.9434 85.2046 71.5101 81.6035 75.9098 81.6035C80.3096 81.6035 83.8763 85.2046 83.8763 89.6044C83.8763 94.0042 80.3096 97.6053 75.9098 97.6053C71.5101 97.6053 67.9434 94.0042 67.9434 89.6044Z" fill="black" fill-opacity="0.08"/>
|
||||
<path d="M74.7449 92.9742L71.9268 90.1439L73.3308 88.7337L74.7349 90.1439L78.2601 86.6035L79.6642 88.0136L74.7449 92.9742Z" fill="white"/>
|
||||
<path d="M18.5156 80.0127H44.057V98.5779H18.5156V80.0127Z" fill="#959595"/>
|
||||
<path d="M18.5156 80.0127H44.057V80.7267H18.5156V80.0127Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 83.1064H44.057V83.8204H18.5156V83.1064Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 86.2002H44.057V86.9142H18.5156V86.2002Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 89.2959H44.057V90.0098H18.5156V89.2959Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 92.3896H44.057V93.1035H18.5156V92.3896Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 95.4854H44.057V96.1993H18.5156V95.4854Z" fill="#6E6E6E"/>
|
||||
<path d="M18.5156 98.5781H44.057V99.2924H18.5156V98.5781Z" fill="#6E6E6E"/>
|
||||
<path d="M29.1064 120.573H33.1557L32.0309 123.299H30.3437L29.1064 120.573Z" fill="#656565"/>
|
||||
<path d="M21.9424 99.5615H40.6312V112.827H21.9424V99.5615Z" fill="#737373"/>
|
||||
<path d="M24.4355 112.827H37.8292V120.856H24.4355V112.827Z" fill="#737373"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4627_4383" x1="51.1766" y1="0.652344" x2="51.1766" y2="105.397" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#BFBFBF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#686868" stop-opacity="0.4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4627_4383" x1="51.4427" y1="1.18652" x2="51.4427" y2="101.656" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#CCCCCC" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#919191" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 2.4 MiB |
38
resources/images/fila_switch.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<svg width="17" height="9" viewBox="0 0 17 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_iiii_6472_20428)">
|
||||
<rect x="0.0527344" y="0.0527344" width="16" height="8.42105" rx="0.842105" fill="#808080"/>
|
||||
</g>
|
||||
<rect x="0.0527344" y="0.0527344" width="16" height="8.42105" rx="0.842105" stroke="#C2C2C2" stroke-width="0.105263"/>
|
||||
<path d="M10.7006 2.79037H10.5244L10.426 2.792C9.41175 2.82502 8.47921 3.36695 7.94928 4.23755C7.46947 5.02578 6.61347 5.50693 5.69069 5.50693H5.51452V4.94947C5.51452 4.80429 5.35736 4.71355 5.23163 4.78614L3.94526 5.52882C3.81952 5.60141 3.81952 5.78289 3.94526 5.85548L5.23163 6.59816C5.35736 6.67075 5.51452 6.58001 5.51452 6.43483V5.87736H5.69069C6.74276 5.87736 7.71879 5.32886 8.26581 4.43018C8.73063 3.66656 9.54849 3.1912 10.4381 3.16225L10.5244 3.1608H10.7006V3.71826C10.7006 3.86344 10.8577 3.95418 10.9835 3.88159L12.2698 3.13891C12.3956 3.06632 12.3956 2.88485 12.2698 2.81225L10.9835 2.06958C10.8577 1.99699 10.7006 2.08773 10.7006 2.23291V2.79037Z" fill="#EEEEEE"/>
|
||||
<path d="M5.51452 2.79037H5.69069L5.78908 2.792C6.80334 2.82502 7.73588 3.36695 8.26581 4.23755C8.74562 5.02578 9.60161 5.50693 10.5244 5.50693H10.7006V4.94947C10.7006 4.80429 10.8577 4.71355 10.9835 4.78614L12.2698 5.52882C12.3956 5.60141 12.3956 5.78289 12.2698 5.85548L10.9835 6.59816C10.8577 6.67075 10.7006 6.58001 10.7006 6.43483V5.87736H10.5244C9.47233 5.87736 8.4963 5.32886 7.94928 4.43018C7.48446 3.66656 6.6666 3.1912 5.77697 3.16225L5.69069 3.1608H5.51452V3.71826C5.51452 3.86344 5.35735 3.95418 5.23162 3.88159L3.94525 3.13891C3.81952 3.06632 3.81952 2.88485 3.94525 2.81225L5.23162 2.06958C5.35735 1.99699 5.51452 2.08773 5.51452 2.23291V2.79037Z" fill="#EEEEEE"/>
|
||||
<defs>
|
||||
<filter id="filter0_iiii_6472_20428" x="-1" y="-1" width="18.1055" height="10.5264" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="-1"/>
|
||||
<feGaussianBlur stdDeviation="0.5"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_6472_20428"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="-1"/>
|
||||
<feGaussianBlur stdDeviation="0.5"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect1_innerShadow_6472_20428" result="effect2_innerShadow_6472_20428"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="1"/>
|
||||
<feGaussianBlur stdDeviation="0.5"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect2_innerShadow_6472_20428" result="effect3_innerShadow_6472_20428"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="1"/>
|
||||
<feGaussianBlur stdDeviation="0.5"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect3_innerShadow_6472_20428" result="effect4_innerShadow_6472_20428"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
38
resources/images/fila_switch_error.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<svg width="33" height="18" viewBox="0 0 33 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_iiii_6472_20289)">
|
||||
<rect x="0.105469" y="0.105469" width="32" height="16.8421" rx="1.68421" fill="#EA3D23"/>
|
||||
</g>
|
||||
<rect x="0.105469" y="0.105469" width="32" height="16.8421" rx="1.68421" stroke="#C2C2C2" stroke-width="0.210526"/>
|
||||
<path d="M21.4011 5.57976H21.0488L20.852 5.58301C18.8235 5.64906 16.9584 6.73293 15.8986 8.47412C14.9389 10.0506 13.2269 11.0129 11.3814 11.0129H11.029V9.89796C11.029 9.6076 10.7147 9.42613 10.4633 9.57131L7.89051 11.0567C7.63905 11.2018 7.63905 11.5648 7.89051 11.71L10.4633 13.1953C10.7147 13.3405 11.029 13.159 11.029 12.8687V11.7538H11.3814C13.4855 11.7538 15.4376 10.6567 16.5316 8.85939C17.4613 7.33213 19.097 6.38143 20.8762 6.32352L21.0488 6.32062H21.4011V7.43555C21.4011 7.72591 21.7155 7.90739 21.9669 7.76221L24.5397 6.27685C24.7911 6.13167 24.7911 5.76871 24.5397 5.62353L21.9669 4.13818C21.7155 3.993 21.4011 4.17447 21.4011 4.46484V5.57976Z" fill="#EEEEEE"/>
|
||||
<path d="M11.029 5.57976H11.3814L11.5782 5.58301C13.6067 5.64906 15.4718 6.73293 16.5316 8.47412C17.4912 10.0506 19.2032 11.0129 21.0488 11.0129H21.4011V9.89796C21.4011 9.6076 21.7155 9.42613 21.9669 9.57131L24.5397 11.0567C24.7911 11.2018 24.7911 11.5648 24.5397 11.71L21.9669 13.1953C21.7155 13.3405 21.4011 13.159 21.4011 12.8687V11.7538H21.0488C18.9447 11.7538 16.9926 10.6567 15.8986 8.85939C14.9689 7.33213 13.3332 6.38143 11.5539 6.32352L11.3814 6.32062H11.029V7.43555C11.029 7.72591 10.7147 7.90739 10.4632 7.76221L7.8905 6.27685C7.63904 6.13167 7.63904 5.76871 7.8905 5.62353L10.4632 4.13818C10.7147 3.993 11.029 4.17447 11.029 4.46484V5.57976Z" fill="#EEEEEE"/>
|
||||
<defs>
|
||||
<filter id="filter0_iiii_6472_20289" x="-2" y="-2" width="36.2109" height="21.0527" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="-2"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_6472_20289"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="-2"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect1_innerShadow_6472_20289" result="effect2_innerShadow_6472_20289"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect2_innerShadow_6472_20289" result="effect3_innerShadow_6472_20289"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="2"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="effect3_innerShadow_6472_20289" result="effect4_innerShadow_6472_20289"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
BIN
resources/images/filament_load_o1c_series_ext0.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
resources/images/filament_load_o1c_series_ext1.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
resources/images/filament_track_switch.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
13
resources/images/hotend_thumbnail.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg width="45" height="67" viewBox="0 0 45 67" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="44.2448" height="28.7351" fill="#C2C2C2"/>
|
||||
<rect width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="4.78857" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="9.57715" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="14.3687" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="19.1587" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="23.9458" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect y="28.7344" width="44.2448" height="1.1052" fill="#858585"/>
|
||||
<rect x="10.252" y="30.0713" width="23.7411" height="32.7086" fill="#A3A3A3"/>
|
||||
<rect x="20.2262" y="30.3394" width="3.16034" height="32.2355" fill="#FFF735"/>
|
||||
<path d="M18.3454 62.7793H25.3598L23.4114 66.9998H20.4887L18.3454 62.7793Z" fill="#D9D9D9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 868 B |
4
resources/images/leaf.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.2" d="M5.98183 18.0178C1.49214 10.5356 7.48183 3.05343 20.1981 3.80156C20.9462 16.5216 13.464 22.5075 5.98183 18.0178Z" fill="#00AF42"/>
|
||||
<path d="M20.9489 3.75655C20.9381 3.57307 20.8604 3.39991 20.7305 3.26994C20.6005 3.13998 20.4273 3.06226 20.2439 3.05155C13.1067 2.63249 7.38979 4.78124 4.95229 8.81249C4.10738 10.1915 3.69103 11.7903 3.75604 13.4062C3.80948 14.8987 4.24448 16.4062 5.04885 17.8922L3.21979 19.7203C3.07906 19.861 3 20.0519 3 20.2509C3 20.4499 3.07906 20.6408 3.21979 20.7815C3.36052 20.9223 3.55139 21.0013 3.75042 21.0013C3.94944 21.0013 4.14031 20.9223 4.28104 20.7815L6.10917 18.9525C7.59417 19.7559 9.1026 20.1909 10.5942 20.2444C10.6985 20.2481 10.8026 20.25 10.9064 20.25C12.4174 20.254 13.8997 19.8379 15.1879 19.0481C19.2192 16.6106 21.3689 10.8947 20.9489 3.75655ZM14.4145 17.7656C12.2817 19.0575 9.75698 19.0781 7.22292 17.8378L15.532 9.52967C15.6017 9.45999 15.6569 9.37727 15.6947 9.28622C15.7324 9.19518 15.7518 9.0976 15.7518 8.99905C15.7518 8.9005 15.7324 8.80292 15.6947 8.71188C15.6569 8.62083 15.6017 8.53811 15.532 8.46842C15.4623 8.39874 15.3796 8.34347 15.2885 8.30575C15.1975 8.26804 15.0999 8.24863 15.0014 8.24863C14.9028 8.24863 14.8052 8.26804 14.7142 8.30575C14.6231 8.34347 14.5404 8.39874 14.4707 8.46842L6.1626 16.7812C4.92604 14.25 4.94385 11.7187 6.23479 9.58967C8.30573 6.17061 13.2285 4.29842 19.4826 4.52155C19.7067 10.7709 17.8335 15.6947 14.4145 17.7656Z" fill="#00AF42"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/images/nozzle_rack.png
Normal file
|
After Width: | Height: | Size: 77 KiB |