From 0b77321d3a5b74301809e2474902ee262851858a Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 24 Jun 2026 19:16:15 +0800 Subject: [PATCH 1/4] bump flashforge profile version --- resources/profiles/Flashforge.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/profiles/Flashforge.json b/resources/profiles/Flashforge.json index da8160ea01..23b81bb56e 100644 --- a/resources/profiles/Flashforge.json +++ b/resources/profiles/Flashforge.json @@ -1,7 +1,7 @@ { "name": "Flashforge", "url": "", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "Flashforge configurations", "machine_model_list": [ From d3ac5ab98ea675a12c0300e75f1db9515b06c35d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:35:21 +0800 Subject: [PATCH 2/4] Bump actions/github-script from 7 to 9 (#13431) Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v7...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pr-label-bot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-label-bot.yml b/.github/workflows/pr-label-bot.yml index bbe1ac3472..c238c854f4 100644 --- a/.github/workflows/pr-label-bot.yml +++ b/.github/workflows/pr-label-bot.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Ask PR author for label - uses: actions/github-script@v7 + uses: actions/github-script@v9 with: script: | function isPermissionDenied(error) { @@ -88,7 +88,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Apply label command from PR author - uses: actions/github-script@v7 + uses: actions/github-script@v9 with: script: | function isPermissionDenied(error) { From 4e03983426ef6872e2a596fc5e9417d5aee7d069 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 24 Jun 2026 21:02:51 +0800 Subject: [PATCH 3/4] build belt parallel branch and publish the nightly release --- .github/workflows/build_all.yml | 8 ++++++-- .github/workflows/build_orca.yml | 25 +++++++++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 3fafbb1c2c..ad203ecfce 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -5,6 +5,7 @@ on: branches: - main - release/* + - belt-printer paths: - 'deps/**' - 'src/**' @@ -184,6 +185,9 @@ jobs: date: ver: ver_pure: + # Belt-printer nightlies share the main nightly release but carry a `_belt` + # suffix so they never overwrite the main assets. + nightly_suffix: ${{ github.ref == 'refs/heads/belt-printer' && '_belt' || '' }} steps: - name: "Remove unneeded stuff to free disk space" run: @@ -242,12 +246,12 @@ jobs: name: OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak path: '/__w/OrcaSlicer/OrcaSlicer/OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak' - name: Deploy Flatpak to nightly release - if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' + if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer') uses: WebFreak001/deploy-nightly@v3.2.0 with: upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label} release_id: 137995723 asset_path: /__w/OrcaSlicer/OrcaSlicer/OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak - asset_name: OrcaSlicer-Linux-flatpak_nightly_${{ matrix.variant.arch }}.flatpak + asset_name: OrcaSlicer-Linux-flatpak_nightly${{ env.nightly_suffix }}_${{ matrix.variant.arch }}.flatpak asset_content_type: application/octet-stream max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index fa53d5916b..aff9b79a85 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -29,6 +29,11 @@ jobs: ubuntu-ver: '2404' ubuntu-ver-str: '_Ubuntu2404' ORCA_UPDATER_SIG_KEY: ${{ secrets.ORCA_UPDATER_SIG_KEY }} + # Branches whose builds are published to the nightly release. The + # belt-printer branch ships alongside main but its assets carry a `_belt` + # suffix (nightly_suffix) so they never overwrite the main nightly assets. + deploy_nightly: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' }} + nightly_suffix: ${{ github.ref == 'refs/heads/belt-printer' && '_belt' || '' }} steps: - name: Checkout @@ -160,7 +165,7 @@ jobs: # Thanks to RaySajuuk, it's working now - name: Sign app and notary - if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only + if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only working-directory: ${{ github.workspace }} env: BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} @@ -216,7 +221,7 @@ jobs: fi - name: Create DMG without notary - if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only + if: github.ref != 'refs/heads/main' && github.ref != 'refs/heads/belt-printer' && runner.os == 'macOS' && inputs.macos-combine-only working-directory: ${{ github.workspace }} run: | # Load the `retry` helper (retries flaky commands such as `hdiutil create`). @@ -262,13 +267,13 @@ jobs: if-no-files-found: ignore - name: Deploy Mac release - if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED + if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED uses: WebFreak001/deploy-nightly@v3.2.0 with: upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label} release_id: 137995723 asset_path: ${{ github.workspace }}/OrcaSlicer_Mac_universal_${{ env.ver }}.dmg - asset_name: OrcaSlicer_Mac_universal_nightly.dmg + asset_name: OrcaSlicer_Mac_universal_nightly${{ env.nightly_suffix }}.dmg asset_content_type: application/octet-stream max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted @@ -350,24 +355,24 @@ jobs: path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe - name: Deploy Windows release portable - if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED + if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED uses: WebFreak001/deploy-nightly@v3.2.0 with: upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label} release_id: 137995723 asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_${{ env.ver }}_portable.zip - asset_name: OrcaSlicer_Windows_nightly_portable.zip + asset_name: OrcaSlicer_Windows_nightly${{ env.nightly_suffix }}_portable.zip asset_content_type: application/x-zip-compressed max_releases: 1 - name: Deploy Windows release installer - if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED + if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED uses: WebFreak001/deploy-nightly@v3.2.0 with: upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label} release_id: 137995723 asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_Installer_${{ env.ver }}.exe - asset_name: OrcaSlicer_Windows_Installer_nightly.exe + asset_name: OrcaSlicer_Windows_Installer_nightly${{ env.nightly_suffix }}.exe asset_content_type: application/x-msdownload max_releases: 1 @@ -471,13 +476,13 @@ jobs: path: './build/src/Release/OrcaSlicer_profile_validator' - name: Deploy Ubuntu release - if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }} + if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && env.deploy_nightly == 'true' && runner.os == 'Linux' && !vars.SELF_HOSTED }} uses: WebFreak001/deploy-nightly@v3.2.0 with: upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label} release_id: 137995723 asset_path: ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage - asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_nightly.AppImage + asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_nightly${{ env.nightly_suffix }}.AppImage asset_content_type: application/octet-stream max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted - name: Deploy Ubuntu release From da074043f2b9fa1cebd617b15a6a2f316df28a9e Mon Sep 17 00:00:00 2001 From: SoftFever Date: Thu, 25 Jun 2026 10:52:19 +0800 Subject: [PATCH 4/4] Fix fuzzy skin artifacting regression (#14376) (#14382) Fix fuzzy skin artifacting (#14376) --- .../WideningBeadingStrategy.cpp | 8 ++- tests/libslic3r/test_arachne_walls.cpp | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Arachne/BeadingStrategy/WideningBeadingStrategy.cpp b/src/libslic3r/Arachne/BeadingStrategy/WideningBeadingStrategy.cpp index 5bef586d66..ab8b070604 100644 --- a/src/libslic3r/Arachne/BeadingStrategy/WideningBeadingStrategy.cpp +++ b/src/libslic3r/Arachne/BeadingStrategy/WideningBeadingStrategy.cpp @@ -32,7 +32,13 @@ WideningBeadingStrategy::Beading WideningBeadingStrategy::compute(coord_t thickn // Previously used optimal_width which could differ from the outer wall width used in // bead count calculations, causing inconsistency where bead_count=2 was requested but // only 1 bead was produced. - if (thickness < getTransitionThickness(1)) { + // + // Orca #14376: only collapse to a single bead when at most one bead is requested. This + // branch emits one bead at the full wall thickness, so honoring it when bead_count >= 2 + // (which happens inside 1<->2 transition bands) produces an over-wide extrusion that shows + // up as a surface bulge. Deferring to the parent keeps the requested two beads and also + // keeps compute() consistent with the bead count the skeletal graph asked for. + if (bead_count <= 1 && thickness < getTransitionThickness(1)) { Beading ret; ret.total_thickness = thickness; if (thickness >= min_input_width) { diff --git a/tests/libslic3r/test_arachne_walls.cpp b/tests/libslic3r/test_arachne_walls.cpp index dc5d7143f6..2d8ee3bc03 100644 --- a/tests/libslic3r/test_arachne_walls.cpp +++ b/tests/libslic3r/test_arachne_walls.cpp @@ -19,11 +19,14 @@ #include "libslic3r/Arachne/WallToolPaths.hpp" #include "libslic3r/Arachne/utils/ExtrusionLine.hpp" +#include "libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.hpp" +#include "libslic3r/Arachne/BeadingStrategy/BeadingStrategy.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/ExPolygon.hpp" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/Point.hpp" +#include #include using namespace Slic3r; @@ -207,3 +210,58 @@ TEST_CASE("Arachne wall generation - 60% min_bead_width", "[Arachne]") { size_t duplicates = run_arachne_test(60); REQUIRE(duplicates == 0); } + +// Regression test for #14376 ("Fuzzy skin artifacting" — a surface bulge at a fixed height). +// +// PR #14031 changed WideningBeadingStrategy::compute() to take the thin-wall single-bead +// branch whenever thickness < getTransitionThickness(1). That branch emits a single bead at +// the full wall thickness and ignores the requested bead_count. When the skeletal graph asks +// for 2 beads at a thickness inside the 1<->2 transition band (between the inner wall width and +// getTransitionThickness(1)), the request was collapsed into one over-wide bead — an +// over-extruded line that shows up as a bulge on curved surfaces at a deterministic height. +// +// Profile mirrors the reporter's project ("0.20mm Standard @BBL X1C", 0.4mm nozzle): +// outer 0.42mm / inner 0.45mm, min_bead_width 85% (0.34mm), 2 walls (max_bead_count 4). +// For these numbers wall_split_middle_threshold = 2*0.34/0.42 - 1 = 0.619, so +// getTransitionThickness(1) = (1 + 0.619) * 0.42 = 0.68mm. A 0.5mm-thick wall therefore sits +// in the transition band: alpha produced 2 beads here, beta collapses it to 1 fat bead. +TEST_CASE("Arachne widening keeps two beads in transition band (#14376)", "[Arachne]") { + using namespace Slic3r::Arachne; + + // Widths in mm; the scaled coord_t values and the thresholds below are both derived from + // these so a width change cannot silently desync the transition-band math. + const double outer_mm = 0.42, inner_mm = 0.45, min_bead_mm = 0.34; // min_bead = 85% of 0.4mm nozzle + + const coord_t outer_width = scaled(outer_mm); + const coord_t inner_width = scaled(inner_mm); + const coord_t min_bead_width = scaled(min_bead_mm); + const coord_t min_feature_size = scaled(0.10); // 25% of 0.4mm nozzle + const coord_t transition_length = scaled(0.40); + const coord_t max_bead_count = 4; // 2 * wall_loops + + // Same derivation as WallToolPaths.cpp. + const double split_middle_threshold = std::clamp(2.0 * min_bead_mm / outer_mm - 1.0, 0.01, 0.99); + const double add_middle_threshold = std::clamp(min_bead_mm / inner_mm, 0.01, 0.99); + + auto strategy = BeadingStrategyFactory::makeStrategy( + outer_width, inner_width, transition_length, + /*transitioning_angle*/ float(M_PI / 4.0), /*print_thin_walls*/ true, + min_bead_width, min_feature_size, + split_middle_threshold, add_middle_threshold, + max_bead_count, /*outer_wall_offset*/ 0, /*inward_distributed_center_wall_count*/ 1); + + // A wall thickness inside the 1<->2 bead transition band (inner_width < t < transition). + const coord_t thickness = scaled(0.50); + REQUIRE(thickness > inner_width); + REQUIRE(thickness < strategy->getTransitionThickness(1)); + + // When the graph requests 2 beads, the strategy must produce 2 beads — not collapse them + // into a single full-thickness (bulge) bead. + const BeadingStrategy::Beading beading = strategy->compute(thickness, 2); + REQUIRE(beading.bead_widths.size() == 2); + + // And neither bead may be over-wide: a single collapsed bead would be ~0.5mm (the full + // thickness), well above the configured wall widths. + for (const coord_t w : beading.bead_widths) + CHECK(w <= inner_width); +}