Merge branch 'main' into feat/snap-store-packaging

This commit is contained in:
SoftFever
2026-06-20 13:16:01 +08:00
committed by GitHub
38 changed files with 16491 additions and 12026 deletions
+18 -12
View File
@@ -162,14 +162,6 @@ jobs:
run: | run: |
./build_release_macos.sh -u -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a universal -t 10.15 ./build_release_macos.sh -u -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a universal -t 10.15
- name: Delete intermediate per-arch artifacts
if: runner.os == 'macOS' && inputs.macos-combine-only
uses: geekyeggo/delete-artifact@v6
with:
name: |
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
# Thanks to RaySajuuk, it's working now # Thanks to RaySajuuk, it's working now
- name: Sign app and notary - 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' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only
@@ -180,6 +172,8 @@ jobs:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
CERTIFICATE_ID: ${{ secrets.MACOS_CERTIFICATE_ID }} CERTIFICATE_ID: ${{ secrets.MACOS_CERTIFICATE_ID }}
run: | run: |
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
source ${{ github.workspace }}/scripts/retry.sh
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
@@ -202,7 +196,7 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/* rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/ cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_Mac_universal_${{ env.ver }}.dmg codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
# Create separate OrcaSlicer_profile_validator DMG if the app exists # Create separate OrcaSlicer_profile_validator DMG if the app exists
@@ -211,7 +205,7 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/* rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/ cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
fi fi
@@ -229,11 +223,13 @@ jobs:
if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
run: | run: |
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
source ${{ github.workspace }}/scripts/retry.sh
mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/* rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/ cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
# Create separate OrcaSlicer_profile_validator DMG if the app exists # Create separate OrcaSlicer_profile_validator DMG if the app exists
if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then
@@ -241,9 +237,19 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/* rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/ cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
fi fi
# Delete the per-arch bundles only after signing/DMG creation succeeded, so a
# failed run keeps them available for a re-run instead of forcing a full rebuild.
- name: Delete intermediate per-arch artifacts
if: success() && runner.os == 'macOS' && inputs.macos-combine-only
uses: geekyeggo/delete-artifact@v6
with:
name: |
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
- name: Upload artifacts mac - name: Upload artifacts mac
if: runner.os == 'macOS' && inputs.macos-combine-only if: runner.os == 'macOS' && inputs.macos-combine-only
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
+6
View File
@@ -10,7 +10,13 @@ if (APPLE AND CMAKE_OSX_ARCHITECTURES)
set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=${CMAKE_OSX_ARCHITECTURES}") set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=${CMAKE_OSX_ARCHITECTURES}")
endif () endif ()
set(_options "")
if (MSVC AND DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
orcaslicer_add_cmake_project(Boost orcaslicer_add_cmake_project(Boost
${_options}
URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz" URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz"
URL_HASH SHA256=4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95 URL_HASH SHA256=4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95
LIST_SEPARATOR | LIST_SEPARATOR |
+14 -6
View File
@@ -155,17 +155,25 @@ if (NOT _is_multi AND NOT CMAKE_BUILD_TYPE)
endif () endif ()
function(orcaslicer_add_cmake_project projectname) function(orcaslicer_add_cmake_project projectname)
cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}) set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
if (_is_multi OR MSVC) if (_is_multi OR MSVC)
if (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG) if (P_ARGS_FORWARD_CONFIG)
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
elseif (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG)
set(_configs_line "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") set(_configs_line "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
else () else ()
set(_configs_line "") set(_configs_line "")
endif () endif ()
endif () endif ()
if (P_ARGS_FORWARD_CONFIG)
set(_target_config "$<CONFIG>")
else()
set(_target_config "Release")
endif()
if (MSVC) if (MSVC)
set(_gen CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}") set(_gen CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}")
else() else()
@@ -208,8 +216,8 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
${DEP_CMAKE_OPTS} ${DEP_CMAKE_OPTS}
${P_ARGS_CMAKE_ARGS} ${P_ARGS_CMAKE_ARGS}
${P_ARGS_UNPARSED_ARGUMENTS} ${P_ARGS_UNPARSED_ARGUMENTS}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j} BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
) )
if (FLATPAK) if (FLATPAK)
@@ -251,8 +259,8 @@ else()
${DEP_CMAKE_OPTS} ${DEP_CMAKE_OPTS}
${P_ARGS_CMAKE_ARGS} ${P_ARGS_CMAKE_ARGS}
${P_ARGS_UNPARSED_ARGUMENTS} ${P_ARGS_UNPARSED_ARGUMENTS}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j} BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
) )
endif() endif()
+6
View File
@@ -1,4 +1,10 @@
set(_options "")
if (MSVC AND DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
orcaslicer_add_cmake_project(Draco orcaslicer_add_cmake_project(Draco
${_options}
URL https://github.com/google/draco/archive/refs/tags/1.5.7.zip URL https://github.com/google/draco/archive/refs/tags/1.5.7.zip
URL_HASH SHA256=27b72ba2d5ff3d0a9814ad40d4cb88f8dc89a35491c0866d952473f8f9416b77 URL_HASH SHA256=27b72ba2d5ff3d0a9814ad40d4cb88f8dc89a35491c0866d952473f8f9416b77
) )
+5
View File
@@ -1,7 +1,11 @@
if (MSVC) if (MSVC)
set(_use_IPP "-DWITH_IPP=ON") set(_use_IPP "-DWITH_IPP=ON")
if (DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
else () else ()
set(_use_IPP "-DWITH_IPP=OFF") set(_use_IPP "-DWITH_IPP=OFF")
set(_options "")
endif () endif ()
if (IN_GIT_REPO) if (IN_GIT_REPO)
@@ -9,6 +13,7 @@ if (IN_GIT_REPO)
endif () endif ()
orcaslicer_add_cmake_project(OpenCV orcaslicer_add_cmake_project(OpenCV
${_options}
URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz
URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277 URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch
+18 -3
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-18 09:16-0300\n" "POT-Creation-Date: 2026-06-19 10:33-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -7779,6 +7779,15 @@ msgstr ""
msgid "Renders cast shadows on the plate in realistic view." msgid "Renders cast shadows on the plate in realistic view."
msgstr "" msgstr ""
msgid "Smooth normals"
msgstr ""
msgid ""
"Applies smooth normals to the realistic view.\n"
"\n"
"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")."
msgstr ""
msgid "Anti-aliasing" msgid "Anti-aliasing"
msgstr "" msgstr ""
@@ -12379,7 +12388,7 @@ msgstr ""
msgid "First layer height" msgid "First layer height"
msgstr "" msgstr ""
msgid "This is the height of the first layer. Making the first layer height thicker can improve build plate adhesion." msgid "Height of the first layer. Making the first layer height thicker can improve build plate adhesion."
msgstr "" msgstr ""
msgid "This is the speed for the first layer except for solid infill sections." msgid "This is the speed for the first layer except for solid infill sections."
@@ -12397,7 +12406,7 @@ msgstr ""
msgid "Travel speed of the first layer." msgid "Travel speed of the first layer."
msgstr "" msgstr ""
msgid "This is the number of top interface layers." msgid "Number of slow layers"
msgstr "" msgstr ""
msgid "The first few layers are printed slower than normal. The speed is gradually increased in a linear fashion over the specified number of layers." msgid "The first few layers are printed slower than normal. The speed is gradually increased in a linear fashion over the specified number of layers."
@@ -14210,6 +14219,9 @@ msgstr ""
msgid "Top interface layers" msgid "Top interface layers"
msgstr "" msgstr ""
msgid "This is the number of top interface layers."
msgstr ""
msgid "Bottom interface layers" msgid "Bottom interface layers"
msgstr "" msgstr ""
@@ -16870,6 +16882,9 @@ msgstr ""
msgid "Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small" msgid "Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small"
msgstr "" msgstr ""
msgid "Physical Printer"
msgstr ""
msgid "Print Host upload" msgid "Print Host upload"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+18 -3
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Orca Slicer\n" "Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-18 09:16-0300\n" "POT-Creation-Date: 2026-06-19 10:33-0300\n"
"PO-Revision-Date: 2026-06-17 15:44-0300\n" "PO-Revision-Date: 2026-06-17 15:44-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n" "Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: \n" "Language-Team: \n"
@@ -7775,6 +7775,15 @@ msgstr ""
msgid "Renders cast shadows on the plate in realistic view." msgid "Renders cast shadows on the plate in realistic view."
msgstr "" msgstr ""
msgid "Smooth normals"
msgstr ""
msgid ""
"Applies smooth normals to the realistic view.\n"
"\n"
"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")."
msgstr ""
msgid "Anti-aliasing" msgid "Anti-aliasing"
msgstr "" msgstr ""
@@ -12375,7 +12384,7 @@ msgstr ""
msgid "First layer height" msgid "First layer height"
msgstr "" msgstr ""
msgid "This is the height of the first layer. Making the first layer height thicker can improve build plate adhesion." msgid "Height of the first layer. Making the first layer height thicker can improve build plate adhesion."
msgstr "" msgstr ""
msgid "This is the speed for the first layer except for solid infill sections." msgid "This is the speed for the first layer except for solid infill sections."
@@ -12393,7 +12402,7 @@ msgstr ""
msgid "Travel speed of the first layer." msgid "Travel speed of the first layer."
msgstr "" msgstr ""
msgid "This is the number of top interface layers." msgid "Number of slow layers"
msgstr "" msgstr ""
msgid "The first few layers are printed slower than normal. The speed is gradually increased in a linear fashion over the specified number of layers." msgid "The first few layers are printed slower than normal. The speed is gradually increased in a linear fashion over the specified number of layers."
@@ -14206,6 +14215,9 @@ msgstr ""
msgid "Top interface layers" msgid "Top interface layers"
msgstr "" msgstr ""
msgid "This is the number of top interface layers."
msgstr ""
msgid "Bottom interface layers" msgid "Bottom interface layers"
msgstr "" msgstr ""
@@ -16866,6 +16878,9 @@ msgstr ""
msgid "Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small" msgid "Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small"
msgstr "" msgstr ""
msgid "Physical Printer"
msgstr ""
msgid "Print Host upload" msgid "Print Host upload"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Sourceable helper: `retry <cmd...>` runs a command, retrying up to 3 times
# with a 5-minute wait between attempts. Useful for flaky commands such as
# `hdiutil create` intermittently failing with "Resource busy".
retry() {
local attempt=1 max_attempts=3 delay=300
until "$@"; do
if [ "$attempt" -ge "$max_attempts" ]; then
echo "::error::Command failed after $attempt attempts: $*"
return 1
fi
echo "Attempt $attempt failed: $*. Retrying in $((delay / 60)) minutes..."
sleep "$delay"
attempt=$((attempt + 1))
done
}
@@ -8,6 +8,7 @@
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#include <cctype>
namespace Slic3r { namespace Slic3r {
@@ -282,4 +283,81 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) {
return output.str(); return output.str();
} }
std::string AdaptivePAProcessor::validate_adaptive_pa_model(const std::string& model_str)
{
if (model_str.empty())
return {}; // Empty model is valid
std::istringstream model_stream(model_str);
std::string line;
int line_number = 0;
while (std::getline(model_stream, line)) {
++line_number;
// Trim whitespace
const auto first = line.find_first_not_of(" \t\r\n");
if (first == std::string::npos)
continue; // Skip empty lines
const auto last = line.find_last_not_of(" \t\r\n");
line = line.substr(first, last - first + 1);
// Only numbers, commas and dots are allowed (no letters or other characters)
for (char c : line) {
if (!std::isdigit(static_cast<unsigned char>(c)) && c != ',' && c != '.') {
return "Line " + std::to_string(line_number) +
": only numbers, commas and dots are allowed";
}
}
// Count commas to validate format (should be exactly 2 for 3 values)
int comma_count = 0;
for (char c : line) {
if (c == ',') comma_count++;
}
if (comma_count != 2) {
return "Line " + std::to_string(line_number) +
": must contain exactly 3 comma-separated values (PA, flow, acceleration)";
}
// Parse and validate the values
try {
std::istringstream line_stream(line);
std::string value;
// Parse PA
if (!std::getline(line_stream, value, ','))
return "Line " + std::to_string(line_number) + ": missing PA value";
double pa = std::stod(value);
// Parse flow
if (!std::getline(line_stream, value, ','))
return "Line " + std::to_string(line_number) + ": missing flow value";
double flow = std::stod(value);
// Parse acceleration
if (!std::getline(line_stream, value, ','))
return "Line " + std::to_string(line_number) + ": missing acceleration value";
double accel = std::stod(value);
// Validate constraints
if (pa >= 2.0) {
return "Line " + std::to_string(line_number) + ": PA value must be less than 2";
}
if (flow <= pa) {
return "Line " + std::to_string(line_number) + ": flow value must be greater than PA value";
}
if (accel <= flow) {
return "Line " + std::to_string(line_number) + ": acceleration value must be greater than flow value";
}
} catch (const std::exception&) {
return "Line " + std::to_string(line_number) + ": invalid numeric value";
}
}
return {}; // All validations passed
}
} // namespace Slic3r } // namespace Slic3r
@@ -54,6 +54,20 @@ public:
*/ */
void resetPreviousPA(double PA){ m_last_predicted_pa = PA; }; void resetPreviousPA(double PA){ m_last_predicted_pa = PA; };
/**
* @brief Validates an adaptive pressure advance model string.
*
* Checks that:
* - Each non-empty line has exactly 3 comma-separated values (PA, flow, accel)
* - PA value is less than 2
* - Flow value is greater than PA value
* - Accel value is greater than flow value
*
* @param model_str The model string to validate (typically from config)
* @return Empty string if valid, or an error message describing the first issue found
*/
static std::string validate_adaptive_pa_model(const std::string& model_str);
private: private:
GCode &m_gcodegen; ///< Reference to the GCode object. GCode &m_gcodegen; ///< Reference to the GCode object.
std::unordered_map<unsigned int, std::unique_ptr<AdaptivePAInterpolator>> m_AdaptivePAInterpolators; ///< Map between Interpolator objects and tool ID's std::unordered_map<unsigned int, std::unique_ptr<AdaptivePAInterpolator>> m_AdaptivePAInterpolators; ///< Map between Interpolator objects and tool ID's
+18
View File
@@ -25,6 +25,7 @@
#include <limits> #include <limits>
#include <numeric> #include <numeric>
#include <unordered_set> #include <unordered_set>
#include <sstream>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
@@ -1925,6 +1926,23 @@ StringObjectException Print::validate(std::vector<StringObjectException> *warnin
if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter) if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter)
warn(L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences."), "precise_outer_wall"); warn(L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences."), "precise_outer_wall");
// check adaptive pressure advance model
for (unsigned int extruder_id : extruders) {
if (m_config.adaptive_pressure_advance.get_at(extruder_id) &&
m_config.enable_pressure_advance.get_at(extruder_id)) {
const std::string pa_model = m_config.adaptive_pressure_advance_model.get_at(extruder_id);
if (!pa_model.empty()) {
std::string validation_error = AdaptivePAProcessor::validate_adaptive_pa_model(pa_model);
if (!validation_error.empty()) {
warn(L("The Adaptive Pressure Advance model for one or more extruders may contain invalid values."),
"adaptive_pressure_advance_model");
break;
}
}
}
}
} catch (std::exception& e) { } catch (std::exception& e) {
BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl; BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl;
} }
+2 -2
View File
@@ -3347,7 +3347,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("initial_layer_print_height", coFloat); def = this->add("initial_layer_print_height", coFloat);
def->label = L("First layer height"); def->label = L("First layer height");
def->category = L("Quality"); def->category = L("Quality");
def->tooltip = L("This is the height of the first layer. Making the first layer height thicker can improve build plate adhesion."); def->tooltip = L("Height of the first layer. Making the first layer height thicker can improve build plate adhesion.");
def->sidetext = L("mm"); // millimeters, CIS languages need translation def->sidetext = L("mm"); // millimeters, CIS languages need translation
def->min = 0; def->min = 0;
def->set_default_value(new ConfigOptionFloat(0.2)); def->set_default_value(new ConfigOptionFloat(0.2));
@@ -3387,7 +3387,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); def->set_default_value(new ConfigOptionFloatOrPercent(100, true));
def = this->add("slow_down_layers", coInt); def = this->add("slow_down_layers", coInt);
def->label = L("This is the number of top interface layers."); def->label = L("Number of slow layers");
def->tooltip = L("The first few layers are printed slower than normal. " def->tooltip = L("The first few layers are printed slower than normal. "
"The speed is gradually increased in a linear fashion over the specified number of layers."); "The speed is gradually increased in a linear fashion over the specified number of layers.");
def->category = L("Speed"); def->category = L("Speed");
+40
View File
@@ -9,13 +9,29 @@
#include "libslic3r/MaterialType.hpp" #include "libslic3r/MaterialType.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
#include "libslic3r/GCode/AdaptivePAProcessor.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include <sstream>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
namespace {
std::string trim_copy(const std::string& text)
{
const auto first = text.find_first_not_of(" \t\r\n");
if (first == std::string::npos)
return {};
const auto last = text.find_last_not_of(" \t\r\n");
return text.substr(first, last - first + 1);
}
} // namespace
void ConfigManipulation::apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config) void ConfigManipulation::apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config)
{ {
bool modified = false; bool modified = false;
@@ -141,6 +157,30 @@ void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPri
} }
} }
void ConfigManipulation::check_adaptive_pressure_advance_model(DynamicPrintConfig* config)
{
if (is_msg_dlg_already_exist || !config->has("adaptive_pressure_advance_model"))
return;
const auto* model = config->option<ConfigOptionStrings>("adaptive_pressure_advance_model");
if (model == nullptr || model->values.empty())
return;
std::string raw_model;
for (const std::string& chunk : model->values)
raw_model += chunk;
std::string error = AdaptivePAProcessor::validate_adaptive_pa_model(raw_model);
if (!error.empty()) {
wxString msg_text = _L("Adaptive Pressure Advance model validation failed:\n");
msg_text += from_u8(error);
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
is_msg_dlg_already_exist = true;
dialog.ShowModal();
is_msg_dlg_already_exist = false;
}
}
void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig *config) void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig *config)
{ {
+1
View File
@@ -77,6 +77,7 @@ public:
void check_nozzle_recommended_temperature_range(DynamicPrintConfig *config); void check_nozzle_recommended_temperature_range(DynamicPrintConfig *config);
void check_nozzle_temperature_range(DynamicPrintConfig* config); void check_nozzle_temperature_range(DynamicPrintConfig* config);
void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config); void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config);
void check_adaptive_pressure_advance_model(DynamicPrintConfig* config);
void check_filament_max_volumetric_speed(DynamicPrintConfig *config); void check_filament_max_volumetric_speed(DynamicPrintConfig *config);
void check_chamber_temperature(DynamicPrintConfig* config); void check_chamber_temperature(DynamicPrintConfig* config);
void set_is_BBL_Printer(bool is_bbl_printer) { is_BBL_Printer = is_bbl_printer; }; void set_is_BBL_Printer(bool is_bbl_printer) { is_BBL_Printer = is_bbl_printer; };
+5 -2
View File
@@ -6241,8 +6241,11 @@ bool GUI_App::maybe_migrate_user_presets_on_login()
bool GUI_App::check_preset_parent_available(const std::pair<std::string, std::map<std::string, std::string>>& preset_data) bool GUI_App::check_preset_parent_available(const std::pair<std::string, std::map<std::string, std::string>>& preset_data)
{ {
std::string inherits_name = preset_data.second.at(BBL_JSON_KEY_INHERITS); auto it = preset_data.second.find(BBL_JSON_KEY_INHERITS);
// // If contains "fdm_", "@System", and "@base", is a common base template that doesn't need to be installed if (it == preset_data.second.end() || it->second.empty())
return true;
const std::string& inherits_name = it->second;
// If contains "fdm_", "@System", and "@base", is a common base template that doesn't need to be installed
if (inherits_name.find("fdm_") != std::string::npos || inherits_name.find("@System") != std::string::npos || inherits_name.find("@base") != std::string::npos) if (inherits_name.find("fdm_") != std::string::npos || inherits_name.find("@System") != std::string::npos || inherits_name.find("@base") != std::string::npos)
return true; return true;
+1 -1
View File
@@ -53,7 +53,7 @@ namespace GUI {
//------------------------------------------ //------------------------------------------
PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) : PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) :
DPIDialog(parent, wxID_ANY, _L("Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) DPIDialog(parent, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
SetBackgroundColour(*wxWHITE); SetBackgroundColour(*wxWHITE);
+9
View File
@@ -3946,6 +3946,15 @@ void TabFilament::build()
option.opt.is_code = true; option.opt.is_code = true;
option.opt.height = 15; option.opt.height = 15;
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
optgroup->m_on_change = [this](const t_config_option_key& opt_key, const boost::any& value) {
DynamicPrintConfig& filament_config = m_preset_bundle->filaments.get_edited_preset().config;
update_dirty();
if (opt_key == "adaptive_pressure_advance_model")
m_config_manipulation.check_adaptive_pressure_advance_model(&filament_config);
on_value_change(opt_key, value);
};
// //
optgroup = page->new_optgroup(L("Print chamber temperature"), L"param_chamber_temp"); optgroup = page->new_optgroup(L("Print chamber temperature"), L"param_chamber_temp");