mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 18:42:24 +00:00
Compare commits
9 Commits
v2.3.2-bet
...
v2.3.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e63fce706 | ||
|
|
380f4b4a18 | ||
|
|
240cf9ab5d | ||
|
|
05cb8b4d89 | ||
|
|
897a3e915f | ||
|
|
586e96479a | ||
|
|
0879b2079b | ||
|
|
c4801250ea | ||
|
|
f0386d981f |
2
.github/workflows/build_all.yml
vendored
2
.github/workflows/build_all.yml
vendored
@@ -66,7 +66,7 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-latest
|
||||
- os: orca-macos-arm64
|
||||
- os: macos-14
|
||||
arch: arm64
|
||||
# Don't run scheduled builds on forks:
|
||||
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
|
||||
|
||||
2
.github/workflows/build_check_cache.yml
vendored
2
.github/workflows/build_check_cache.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: set outputs
|
||||
id: set_outputs
|
||||
env:
|
||||
dep-folder-name: ${{ inputs.os != 'orca-macos-arm64' && '/OrcaSlicer_dep' || '' }}
|
||||
dep-folder-name: ${{ inputs.os != 'macos-14' && '/OrcaSlicer_dep' || '' }}
|
||||
output-cmd: ${{ inputs.os == 'windows-latest' && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}}
|
||||
run: |
|
||||
echo cache-key=${{ inputs.os }}-cache-orcaslicer_deps-build-${{ hashFiles('deps/**') }} >> ${{ env.output-cmd }}
|
||||
|
||||
14
.github/workflows/build_deps.yml
vendored
14
.github/workflows/build_deps.yml
vendored
@@ -74,18 +74,18 @@ jobs:
|
||||
cd ${{ github.workspace }}/deps/build
|
||||
|
||||
- name: Build on Mac ${{ inputs.arch }}
|
||||
if: inputs.os == 'orca-macos-arm64'
|
||||
if: inputs.os == 'macos-14'
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
# brew install automake texinfo libtool
|
||||
# brew list
|
||||
# brew uninstall --ignore-dependencies zstd
|
||||
./build_release_macos.sh -dx -a universal -t 10.15
|
||||
brew install automake texinfo libtool
|
||||
brew list
|
||||
brew uninstall --ignore-dependencies zstd
|
||||
./build_release_macos.sh -dx -a universal -t 10.15 -1
|
||||
for arch in arm64 x86_64; do
|
||||
(cd "${{ github.workspace }}/deps/build/${arch}" && \
|
||||
find . -mindepth 1 -maxdepth 1 ! -name 'OrcaSlicer_dep' -exec rm -rf {} +)
|
||||
done
|
||||
# brew install zstd
|
||||
brew install zstd
|
||||
|
||||
|
||||
- name: Apt-Install Dependencies
|
||||
@@ -104,7 +104,7 @@ jobs:
|
||||
|
||||
# Upload Artifacts
|
||||
# - name: Upload Mac ${{ inputs.arch }} artifacts
|
||||
# if: inputs.os == 'orca-macos-arm64'
|
||||
# if: inputs.os == 'macos-14'
|
||||
# uses: actions/upload-artifact@v6
|
||||
# with:
|
||||
# name: OrcaSlicer_dep_mac_${{ env.date }}
|
||||
|
||||
36
.github/workflows/build_orca.yml
vendored
36
.github/workflows/build_orca.yml
vendored
@@ -86,29 +86,29 @@ jobs:
|
||||
|
||||
# Mac
|
||||
- name: Install tools mac
|
||||
if: inputs.os == 'orca-macos-arm64'
|
||||
if: inputs.os == 'macos-14'
|
||||
run: |
|
||||
# brew install libtool
|
||||
# brew list
|
||||
brew install libtool
|
||||
brew list
|
||||
mkdir -p ${{ github.workspace }}/deps/build
|
||||
|
||||
# - name: Free disk space
|
||||
# if: inputs.os == 'orca-macos-arm64'
|
||||
# run: |
|
||||
# df -hI /dev/disk3s1s1
|
||||
# sudo find /Applications -maxdepth 1 -type d -name "Xcode_*.app" ! -name "Xcode_15.4.app" -exec rm -rf {} +
|
||||
# sudo rm -rf ~/Library/Developer/CoreSimulator/Caches/*
|
||||
# df -hI /dev/disk3s1s1
|
||||
- name: Free disk space
|
||||
if: inputs.os == 'macos-14'
|
||||
run: |
|
||||
df -hI /dev/disk3s1s1
|
||||
sudo find /Applications -maxdepth 1 -type d -name "Xcode_*.app" ! -name "Xcode_15.4.app" -exec rm -rf {} +
|
||||
sudo rm -rf ~/Library/Developer/CoreSimulator/Caches/*
|
||||
df -hI /dev/disk3s1s1
|
||||
|
||||
- name: Build slicer mac
|
||||
if: inputs.os == 'orca-macos-arm64'
|
||||
if: inputs.os == 'macos-14'
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
./build_release_macos.sh -s -n -x -a universal -t 10.15
|
||||
./build_release_macos.sh -s -n -x -a universal -t 10.15 -1
|
||||
|
||||
# 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/')) && inputs.os == 'orca-macos-arm64'
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && inputs.os == 'macos-14'
|
||||
working-directory: ${{ github.workspace }}
|
||||
env:
|
||||
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
|
||||
@@ -162,7 +162,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Create DMG without notary
|
||||
if: github.ref != 'refs/heads/main' && inputs.os == 'orca-macos-arm64'
|
||||
if: github.ref != 'refs/heads/main' && inputs.os == 'macos-14'
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg
|
||||
@@ -181,14 +181,14 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload artifacts mac
|
||||
if: inputs.os == 'orca-macos-arm64'
|
||||
if: inputs.os == 'macos-14'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: OrcaSlicer_Mac_universal_${{ env.ver }}
|
||||
path: ${{ github.workspace }}/OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
|
||||
- name: Upload OrcaSlicer_profile_validator DMG mac
|
||||
if: inputs.os == 'orca-macos-arm64'
|
||||
if: inputs.os == 'macos-14'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: OrcaSlicer_profile_validator_Mac_universal_DMG_${{ env.ver }}
|
||||
@@ -196,7 +196,7 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Deploy Mac release
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && inputs.os == 'orca-macos-arm64'
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && inputs.os == 'macos-14'
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
@@ -207,7 +207,7 @@ jobs:
|
||||
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 Mac OrcaSlicer_profile_validator DMG release
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && inputs.os == 'orca-macos-arm64'
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && inputs.os == 'macos-14'
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
|
||||
2
deps/GLEW/GLEW.cmake
vendored
2
deps/GLEW/GLEW.cmake
vendored
@@ -5,6 +5,8 @@ find_package(OpenGL QUIET REQUIRED)
|
||||
orcaslicer_add_cmake_project(
|
||||
GLEW
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/glew
|
||||
CMAKE_ARGS
|
||||
-DGLEW_USE_EGL=OFF
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
12
deps/GLEW/glew/CMakeLists.txt
vendored
12
deps/GLEW/glew/CMakeLists.txt
vendored
@@ -3,9 +3,17 @@ project(GLEW)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
if(OpenGL_EGL_FOUND)
|
||||
message(STATUS "building GLEW for EGL (hope that wxWidgets agrees, otherwise you won't have any output!)")
|
||||
# Allow parent project to control EGL usage.
|
||||
# Default to OFF since OrcaSlicer forces GDK_BACKEND=x11 (using GLX contexts).
|
||||
# GLEW must use glXGetProcAddressARB (GLX) to match wxWidgets GL canvas.
|
||||
# Using EGL function loading with GLX contexts causes rendering failures.
|
||||
option(GLEW_USE_EGL "Use EGL instead of GLX for OpenGL function loading" OFF)
|
||||
|
||||
if(GLEW_USE_EGL)
|
||||
message(STATUS "Building GLEW with EGL support")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGLEW_EGL")
|
||||
else()
|
||||
message(STATUS "Building GLEW with GLX support")
|
||||
endif()
|
||||
|
||||
add_library(GLEW src/glew.c)
|
||||
|
||||
1
deps/wxWidgets/wxWidgets.cmake
vendored
1
deps/wxWidgets/wxWidgets.cmake
vendored
@@ -51,6 +51,7 @@ orcaslicer_add_cmake_project(
|
||||
-DwxUSE_UNICODE=ON
|
||||
-DwxUSE_PRIVATE_FONTS=ON
|
||||
-DwxUSE_OPENGL=ON
|
||||
-DwxUSE_GLCANVAS_EGL=OFF
|
||||
-DwxUSE_WEBREQUEST=ON
|
||||
-DwxUSE_WEBVIEW=ON
|
||||
${_wx_edge}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Afinia",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Afinia configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Anker",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Anker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Anycubic",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Anycubic configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Artillery",
|
||||
"version": "02.03.02.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Artillery configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Bambulab",
|
||||
"url": "http://www.bambulab.com/Parameters/vendor/BBL.json",
|
||||
"version": "02.00.00.56",
|
||||
"version": "02.01.00.00",
|
||||
"force_update": "0",
|
||||
"description": "the initial version of BBL configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "BIQU",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "BIQU configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Blocks",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Blocks configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "CONSTRUCT3D",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Construct3D configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Chuanying",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Chuanying configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Co Print",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "CoPrint configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "CoLiDo",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "CoLiDo configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Comgrow",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Comgrow configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Creality",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Creality configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Cubicon",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Cubicon configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Custom Printer",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "My configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "DeltaMaker",
|
||||
"url": "",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "DeltaMaker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Dremel",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Dremel configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Elegoo",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Elegoo configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Eryone",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Eryone configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "FLSun",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "FLSun configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Flashforge",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Flashforge configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "FlyingBear",
|
||||
"version": "02.03.01.00",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "FlyingBear configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Folgertech",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Folgertech configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Geeetech",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Geeetech configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Ginger Additive",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "Ginger configuration",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "InfiMech",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "InfiMech configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Kingroon",
|
||||
"url": "https://kingroon.com/",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "Kingroon configuration files",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "LONGER",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "LONGER configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Lulzbot",
|
||||
"url": "https://ohai.lulzbot.com/group/taz-6/",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Lulzbot configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "M3D",
|
||||
"version": "1.0.0",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Configuration for M3D printers",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "MagicMaker",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "MagicMaker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Mellow",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Mellow Printer Profiles",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "OpenEYE",
|
||||
"url": "http://www.openeye.tech",
|
||||
"version": "01.00.00.03",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "OpenEYE Printers Configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Orca Arena Printer",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Orca Arena configuration files",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "OrcaFilamentLibrary",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Orca Filament Library",
|
||||
"filament_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Peopoly",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Peopoly configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Phrozen",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Phrozen configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Positron 3D",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Positron 3D Printer Profile",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Prusa",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Prusa configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Qidi",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Qidi configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "RH3D",
|
||||
"version": "00.06.10.25",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "RH3D - printer profiles",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Raise3D",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Raise3D configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "RatRig",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "RatRig configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "RolohaunDesign",
|
||||
"version": "02.03.02.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "RolohaunDesign Printer Profiles",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "SecKit",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "SecKit configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Snapmaker",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Snapmaker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Sovol",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Sovol configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Tiertime",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Tiertime configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Tronxy",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Tronxy configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TwoTrees",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "TwoTrees configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "UltiMaker",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "UltiMaker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Vivedino",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Vivedino configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Volumic",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "VOLUMIC configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Voron",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Voron configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Voxelab",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Voxelab configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Vzbot",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Vzbot configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "WEMAKE3D",
|
||||
"version": "02.03.01.20",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "WEMAKE3D configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Wanhao France",
|
||||
"version": "02.03.01.11",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Wanhao France D12 configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Wanhao",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Wanhao configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "WonderMaker",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "WonderMaker configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Z-Bolt",
|
||||
"url": "",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "0",
|
||||
"description": "Z-Bolt configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "innovatiQ",
|
||||
"version": "02.03.01.10",
|
||||
"version": "02.03.02.40",
|
||||
"force_update": "1",
|
||||
"description": "innovatiQ configuration",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -9288,6 +9288,61 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Options in printer_options_with_variant_2 are stored as (normal,silent) pairs per printer variant.
|
||||
// Some legacy presets/projects carry a variant list but still store only one pair; normalize to avoid crashes.
|
||||
static void normalize_stride2_floats(ConfigOptionFloats &opt, size_t expected_size)
|
||||
{
|
||||
auto &v = opt.values;
|
||||
if (expected_size == 0) {
|
||||
v.clear();
|
||||
return;
|
||||
}
|
||||
if (v.empty()) {
|
||||
// Fallback: keep behavior predictable instead of crashing. This should be rare.
|
||||
v.resize(expected_size, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
const double first = v[0];
|
||||
const double second = (v.size() >= 2) ? v[1] : first;
|
||||
|
||||
// Ensure we have at least one (normal,silent) pair to replicate.
|
||||
if (v.size() < 2) {
|
||||
v.resize(2, first);
|
||||
v[1] = second;
|
||||
}
|
||||
// Keep pair alignment if some legacy preset produced odd length.
|
||||
if (v.size() % 2 != 0)
|
||||
v.push_back(second);
|
||||
|
||||
if (v.size() > expected_size) {
|
||||
v.resize(expected_size);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t have_variants = v.size() / 2;
|
||||
const size_t want_variants = expected_size / 2;
|
||||
v.resize(expected_size);
|
||||
for (size_t vi = have_variants; vi < want_variants; ++vi) {
|
||||
v[vi * 2] = first;
|
||||
if (vi * 2 + 1 < v.size())
|
||||
v[vi * 2 + 1] = second;
|
||||
}
|
||||
}
|
||||
|
||||
static void log_normalize_legacy_vector_size(const char *fn, const std::string &key, int stride, size_t src_size, size_t dest_size, size_t expected_size,
|
||||
size_t restore_n, int cur_variant_count, int target_variant_count, size_t cur_ids, size_t target_ids,
|
||||
const ConfigOption *opt_src, const ConfigOption *opt_target)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << fn << ": normalizing legacy vector size for key '" << key << "'"
|
||||
<< " stride=" << stride << " src_size=" << src_size << " dest_size=" << dest_size << " expected=" << expected_size
|
||||
<< " restore_index.size=" << restore_n << " cur_variants=" << cur_variant_count << " target_variants=" << target_variant_count
|
||||
<< " cur_ids=" << cur_ids << " target_ids=" << target_ids << " cur_value=" << opt_src->serialize()
|
||||
<< " target_value=" << opt_target->serialize();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfig& new_config, const t_config_option_keys& keys, const std::set<std::string>& different_keys,
|
||||
std::string extruder_id_name, std::string extruder_variant_name, std::set<std::string>& key_set1, std::set<std::string>& key_set2)
|
||||
{
|
||||
@@ -9310,7 +9365,10 @@ void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfi
|
||||
|
||||
variant_index.resize(target_variant_count, -1);
|
||||
if (cur_variant_count == 0) {
|
||||
variant_index[0] = 0;
|
||||
// Defensive: target_variant_count may be 0 if the preset doesn't carry extruder_variant_name.
|
||||
// In that case keep variant_index empty and let the downstream size checks produce a useful error.
|
||||
if (!variant_index.empty())
|
||||
variant_index[0] = 0;
|
||||
}
|
||||
else if ((cur_extruder_ids.size() > 0) && cur_variant_count != cur_extruder_ids.size()){
|
||||
//should not happen
|
||||
@@ -9352,12 +9410,53 @@ void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfi
|
||||
//nothing to do, keep the original one
|
||||
}
|
||||
else {
|
||||
ConfigOptionVectorBase* opt_vec_src = static_cast<ConfigOptionVectorBase*>(opt_src);
|
||||
const ConfigOptionVectorBase* opt_vec_dest = static_cast<const ConfigOptionVectorBase*>(opt_target);
|
||||
int stride = 1;
|
||||
if (key_set2.find(opt) != key_set2.end())
|
||||
stride = 2;
|
||||
opt_vec_src->set_with_restore(opt_vec_dest, variant_index, stride);
|
||||
|
||||
const size_t restore_n = variant_index.size();
|
||||
const size_t expected_size = restore_n * size_t(stride);
|
||||
|
||||
if (stride == 2) {
|
||||
// Options in key_set2 are machine limits stored as (normal,silent) pairs per printer variant.
|
||||
if (opt_src->type() != coFloats || opt_target->type() != coFloats)
|
||||
throw ConfigurationError((boost::format("%1%: key '%2%' is expected to be ConfigOptionFloats for stride=2.") % __FUNCTION__ % opt).str());
|
||||
|
||||
auto *src_f = static_cast<ConfigOptionFloats*>(opt_src);
|
||||
ConfigOptionFloats rhs_tmp(*static_cast<const ConfigOptionFloats*>(opt_target));
|
||||
|
||||
const size_t src_size = src_f->values.size();
|
||||
const size_t dest_size = rhs_tmp.values.size();
|
||||
if (src_size != expected_size || dest_size != expected_size)
|
||||
log_normalize_legacy_vector_size(__FUNCTION__, opt, stride, src_size, dest_size, expected_size, restore_n, cur_variant_count,
|
||||
target_variant_count, cur_extruder_ids.size(), target_extruder_ids.size(), opt_src, opt_target);
|
||||
|
||||
// Normalize src in-place so backup_values indexing is safe, normalize rhs via a temporary copy.
|
||||
normalize_stride2_floats(*src_f, expected_size);
|
||||
normalize_stride2_floats(rhs_tmp, expected_size);
|
||||
src_f->set_with_restore(&rhs_tmp, variant_index, stride);
|
||||
} else {
|
||||
ConfigOptionVectorBase* opt_vec_src = static_cast<ConfigOptionVectorBase*>(opt_src);
|
||||
|
||||
const size_t src_size = opt_vec_src->size();
|
||||
const size_t dest_size = static_cast<const ConfigOptionVectorBase*>(opt_target)->size();
|
||||
if (src_size != expected_size || dest_size != expected_size)
|
||||
log_normalize_legacy_vector_size(__FUNCTION__, opt, stride, src_size, dest_size, expected_size, restore_n, cur_variant_count,
|
||||
target_variant_count, cur_extruder_ids.size(), target_extruder_ids.size(), opt_src, opt_target);
|
||||
|
||||
if (opt_vec_src->size() != expected_size)
|
||||
opt_vec_src->resize(expected_size, opt_target);
|
||||
|
||||
// Normalize rhs via a cloned temporary (rhs itself is const).
|
||||
ConfigOptionUniquePtr rhs_owner(opt_target->clone());
|
||||
ConfigOptionVectorBase *rhs_vec = dynamic_cast<ConfigOptionVectorBase*>(rhs_owner.get());
|
||||
if (rhs_vec == nullptr)
|
||||
throw ConfigurationError((boost::format("%1%: key '%2%' is expected to be a vector option.") % __FUNCTION__ % opt).str());
|
||||
if (rhs_vec->size() != expected_size)
|
||||
rhs_vec->resize(expected_size, opt_target);
|
||||
|
||||
opt_vec_src->set_with_restore(rhs_vec, variant_index, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,18 @@
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
#endif // __APPLE__
|
||||
|
||||
// Verify GLEW and wxWidgets use the same OpenGL backend (EGL vs GLX).
|
||||
// A mismatch causes rendering failures: GLEW's function loading must match
|
||||
// the context type created by wxWidgets.
|
||||
#if defined(__linux__)
|
||||
#if defined(GLEW_EGL) && (!defined(wxUSE_GLCANVAS_EGL) || !wxUSE_GLCANVAS_EGL)
|
||||
#error "OpenGL backend mismatch: GLEW has EGL support enabled but wxWidgets does not. Ensure GLEW_USE_EGL and wxUSE_GLCANVAS_EGL are both ON or both OFF."
|
||||
#endif
|
||||
#if !defined(GLEW_EGL) && defined(wxUSE_GLCANVAS_EGL) && wxUSE_GLCANVAS_EGL
|
||||
#error "OpenGL backend mismatch: wxWidgets has EGL support enabled but GLEW does not. Ensure GLEW_USE_EGL and wxUSE_GLCANVAS_EGL are both ON or both OFF."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "CalibUtils.hpp"
|
||||
#include "../GUI/I18N.hpp"
|
||||
#include "../GUI/GUI_App.hpp"
|
||||
#include "../GUI/DeviceCore/DevStorage.h"
|
||||
#include "../GUI/DeviceCore/DevStorage.h"
|
||||
#include "../GUI/DeviceManager.hpp"
|
||||
#include "../GUI/Jobs/ProgressIndicator.hpp"
|
||||
#include "../GUI/PartPlate.hpp"
|
||||
|
||||
@@ -461,42 +461,6 @@ void MoonrakerPrinterAgent::build_ams_payload(int ams_count, int max_lane_index,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Color normalization helper (handles #RRGGBB, 0xRRGGBB -> RRGGBBAA)
|
||||
auto normalize_color = [](const std::string& color) -> std::string {
|
||||
std::string value = color;
|
||||
boost::trim(value);
|
||||
|
||||
// Remove 0x or 0X prefix if present
|
||||
if (value.size() >= 2 && (value.rfind("0x", 0) == 0 || value.rfind("0X", 0) == 0)) {
|
||||
value = value.substr(2);
|
||||
}
|
||||
// Remove # prefix if present
|
||||
if (!value.empty() && value[0] == '#') {
|
||||
value = value.substr(1);
|
||||
}
|
||||
|
||||
// Extract only hex digits
|
||||
std::string normalized;
|
||||
for (char c : value) {
|
||||
if (std::isxdigit(static_cast<unsigned char>(c))) {
|
||||
normalized.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(c))));
|
||||
}
|
||||
}
|
||||
|
||||
// If 6 hex digits, add FF alpha
|
||||
if (normalized.size() == 6) {
|
||||
normalized += "FF";
|
||||
}
|
||||
|
||||
// Validate length - return default if invalid
|
||||
if (normalized.size() != 8) {
|
||||
return "00000000";
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
// Build BBL-format JSON for DevFilaSystemParser::ParseV1_0
|
||||
nlohmann::json ams_json = nlohmann::json::object();
|
||||
nlohmann::json ams_array = nlohmann::json::array();
|
||||
@@ -535,7 +499,7 @@ void MoonrakerPrinterAgent::build_ams_payload(int ams_count, int max_lane_index,
|
||||
|
||||
tray_json["tray_info_idx"] = tray->tray_info_idx;
|
||||
tray_json["tray_type"] = tray->tray_type;
|
||||
tray_json["tray_color"] = normalize_color(tray->tray_color);
|
||||
tray_json["tray_color"] = normalize_color_value(tray->tray_color);
|
||||
|
||||
// Add temperature data if provided
|
||||
if (tray->bed_temp > 0) {
|
||||
@@ -604,119 +568,30 @@ void MoonrakerPrinterAgent::build_ams_payload(int ams_count, int max_lane_index,
|
||||
|
||||
bool MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id)
|
||||
{
|
||||
// Fetch AFC lane data from Moonraker database (inline)
|
||||
std::string url = join_url(device_info.base_url, "/server/database/item?namespace=lane_data");
|
||||
|
||||
std::string response_body;
|
||||
bool success = false;
|
||||
std::string http_error;
|
||||
|
||||
auto http = Http::get(url);
|
||||
if (!device_info.api_key.empty()) {
|
||||
http.header("X-Api-Key", device_info.api_key);
|
||||
}
|
||||
http.timeout_connect(5)
|
||||
.timeout_max(10)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
if (status == 200) {
|
||||
response_body = body;
|
||||
success = true;
|
||||
} else {
|
||||
http_error = "HTTP error: " + std::to_string(status);
|
||||
}
|
||||
})
|
||||
.on_error([&](std::string body, std::string err, unsigned status) {
|
||||
http_error = err;
|
||||
if (status > 0) {
|
||||
http_error += " (HTTP " + std::to_string(status) + ")";
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
if (!success) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Failed to fetch lane data: " << http_error;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto json = nlohmann::json::parse(response_body, nullptr, false, true);
|
||||
if (json.is_discarded()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Invalid JSON response";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expected structure: { "result": { "namespace": "lane_data", "value": { "lane1": {...}, ... } } }
|
||||
if (!json.contains("result") || !json["result"].contains("value") || !json["result"]["value"].is_object()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Unexpected JSON structure or no lane_data found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse response into AmsTrayData
|
||||
const auto& value = json["result"]["value"];
|
||||
std::vector<AmsTrayData> trays;
|
||||
int max_lane_index = 0;
|
||||
|
||||
// Null-safe JSON accessors: nlohmann::json::value() throws type_error
|
||||
// when the key exists but the value is null (type mismatch).
|
||||
auto safe_string = [](const nlohmann::json& obj, const char* key) -> std::string {
|
||||
auto it = obj.find(key);
|
||||
if (it != obj.end() && it->is_string())
|
||||
return it->get<std::string>();
|
||||
return "";
|
||||
};
|
||||
auto safe_int = [](const nlohmann::json& obj, const char* key) -> int {
|
||||
auto it = obj.find(key);
|
||||
if (it != obj.end() && it->is_number())
|
||||
return it->get<int>();
|
||||
return 0;
|
||||
};
|
||||
|
||||
for (const auto& [lane_key, lane_obj] : value.items()) {
|
||||
if (!lane_obj.is_object()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract lane index from the "lane" field (tool number, 0-based)
|
||||
std::string lane_str = safe_string(lane_obj, "lane");
|
||||
int lane_index = -1;
|
||||
if (!lane_str.empty()) {
|
||||
try {
|
||||
lane_index = std::stoi(lane_str);
|
||||
} catch (...) {
|
||||
lane_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lane_index < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AmsTrayData tray;
|
||||
tray.slot_index = lane_index;
|
||||
tray.tray_color = safe_string(lane_obj, "color");
|
||||
tray.tray_type = safe_string(lane_obj, "material");
|
||||
tray.bed_temp = safe_int(lane_obj, "bed_temp");
|
||||
tray.nozzle_temp = safe_int(lane_obj, "nozzle_temp");
|
||||
tray.has_filament = !tray.tray_type.empty();
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
tray.tray_info_idx = bundle
|
||||
? bundle->filaments.filament_id_by_type(tray.tray_type)
|
||||
: map_filament_type_to_generic_id(tray.tray_type);
|
||||
|
||||
max_lane_index = std::max(max_lane_index, lane_index);
|
||||
trays.push_back(tray);
|
||||
// Try Happy Hare first (more widely adopted, supports more filament changers)
|
||||
if (fetch_hh_filament_info(trays, max_lane_index)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Detected Happy Hare MMU with "
|
||||
<< (max_lane_index + 1) << " gates";
|
||||
int ams_count = (max_lane_index + 4) / 4;
|
||||
build_ams_payload(ams_count, max_lane_index, trays);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (trays.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: No AFC lanes found";
|
||||
return false;
|
||||
// Fallback to AFC
|
||||
if (fetch_afc_filament_info(trays, max_lane_index)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Detected AFC with "
|
||||
<< (max_lane_index + 1) << " lanes";
|
||||
int ams_count = (max_lane_index + 4) / 4;
|
||||
build_ams_payload(ams_count, max_lane_index, trays);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate AMS count from max lane index (4 trays per AMS unit)
|
||||
int ams_count = (max_lane_index + 4) / 4;
|
||||
|
||||
// Build and parse the AMS payload
|
||||
build_ams_payload(ams_count, max_lane_index, trays);
|
||||
return true;
|
||||
// No MMU detected - this is normal for printers without MMU, not an error
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: No MMU system detected (neither HH nor AFC)";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string MoonrakerPrinterAgent::trim_and_upper(const std::string& input)
|
||||
@@ -780,6 +655,298 @@ std::string MoonrakerPrinterAgent::map_filament_type_to_generic_id(const std::st
|
||||
return UNKNOWN_FILAMENT_ID;
|
||||
}
|
||||
|
||||
// JSON helper methods - null-safe accessors
|
||||
std::string MoonrakerPrinterAgent::safe_json_string(const nlohmann::json& obj, const char* key)
|
||||
{
|
||||
auto it = obj.find(key);
|
||||
if (it != obj.end() && it->is_string())
|
||||
return it->get<std::string>();
|
||||
return "";
|
||||
}
|
||||
|
||||
int MoonrakerPrinterAgent::safe_json_int(const nlohmann::json& obj, const char* key)
|
||||
{
|
||||
auto it = obj.find(key);
|
||||
if (it != obj.end() && it->is_number())
|
||||
return it->get<int>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string MoonrakerPrinterAgent::safe_array_string(const nlohmann::json& arr, int idx)
|
||||
{
|
||||
if (arr.is_array() && idx >= 0 && idx < static_cast<int>(arr.size()) && arr[idx].is_string())
|
||||
return arr[idx].get<std::string>();
|
||||
return "";
|
||||
}
|
||||
|
||||
int MoonrakerPrinterAgent::safe_array_int(const nlohmann::json& arr, int idx)
|
||||
{
|
||||
if (arr.is_array() && idx >= 0 && idx < static_cast<int>(arr.size()) && arr[idx].is_number())
|
||||
return arr[idx].get<int>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string MoonrakerPrinterAgent::normalize_color_value(const std::string& color)
|
||||
{
|
||||
std::string value = color;
|
||||
boost::trim(value);
|
||||
|
||||
// Remove 0x or 0X prefix if present
|
||||
if (value.size() >= 2 && (value.rfind("0x", 0) == 0 || value.rfind("0X", 0) == 0)) {
|
||||
value = value.substr(2);
|
||||
}
|
||||
// Remove # prefix if present
|
||||
if (!value.empty() && value[0] == '#') {
|
||||
value = value.substr(1);
|
||||
}
|
||||
|
||||
// Extract only hex digits
|
||||
std::string normalized;
|
||||
for (char c : value) {
|
||||
if (std::isxdigit(static_cast<unsigned char>(c))) {
|
||||
normalized.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(c))));
|
||||
}
|
||||
}
|
||||
|
||||
// If 6 hex digits, add FF alpha
|
||||
if (normalized.size() == 6) {
|
||||
normalized += "FF";
|
||||
}
|
||||
|
||||
// Validate length - return default if invalid
|
||||
if (normalized.size() != 8) {
|
||||
return "00000000";
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
// Fetch filament info from Armored Turtle AFC
|
||||
bool MoonrakerPrinterAgent::fetch_afc_filament_info(std::vector<AmsTrayData>& trays, int& max_lane_index)
|
||||
{
|
||||
// Fetch AFC lane data from Moonraker database
|
||||
std::string url = join_url(device_info.base_url, "/server/database/item?namespace=lane_data");
|
||||
|
||||
std::string response_body;
|
||||
bool success = false;
|
||||
std::string http_error;
|
||||
|
||||
auto http = Http::get(url);
|
||||
if (!device_info.api_key.empty()) {
|
||||
http.header("X-Api-Key", device_info.api_key);
|
||||
}
|
||||
http.timeout_connect(5)
|
||||
.timeout_max(10)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
if (status == 200) {
|
||||
response_body = body;
|
||||
success = true;
|
||||
} else {
|
||||
http_error = "HTTP error: " + std::to_string(status);
|
||||
}
|
||||
})
|
||||
.on_error([&](std::string body, std::string err, unsigned status) {
|
||||
http_error = err;
|
||||
if (status > 0) {
|
||||
http_error += " (HTTP " + std::to_string(status) + ")";
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
if (!success) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_afc_filament_info: Failed to fetch lane data: " << http_error;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto json = nlohmann::json::parse(response_body, nullptr, false, true);
|
||||
if (json.is_discarded()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_afc_filament_info: Invalid JSON response";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expected structure: { "result": { "namespace": "lane_data", "value": { "lane1": {...}, ... } } }
|
||||
if (!json.contains("result") || !json["result"].contains("value") || !json["result"]["value"].is_object()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_afc_filament_info: Unexpected JSON structure or no lane_data found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse response into AmsTrayData
|
||||
const auto& value = json["result"]["value"];
|
||||
trays.clear();
|
||||
max_lane_index = 0;
|
||||
|
||||
for (const auto& [lane_key, lane_obj] : value.items()) {
|
||||
if (!lane_obj.is_object()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract lane index from the "lane" field (tool number, 0-based)
|
||||
std::string lane_str = safe_json_string(lane_obj, "lane");
|
||||
int lane_index = -1;
|
||||
if (!lane_str.empty()) {
|
||||
try {
|
||||
lane_index = std::stoi(lane_str);
|
||||
} catch (...) {
|
||||
lane_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lane_index < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AmsTrayData tray;
|
||||
tray.slot_index = lane_index;
|
||||
tray.tray_color = safe_json_string(lane_obj, "color");
|
||||
tray.tray_type = safe_json_string(lane_obj, "material");
|
||||
tray.bed_temp = safe_json_int(lane_obj, "bed_temp");
|
||||
tray.nozzle_temp = safe_json_int(lane_obj, "nozzle_temp");
|
||||
tray.has_filament = !tray.tray_type.empty();
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
tray.tray_info_idx = bundle
|
||||
? bundle->filaments.filament_id_by_type(tray.tray_type)
|
||||
: map_filament_type_to_generic_id(tray.tray_type);
|
||||
|
||||
max_lane_index = std::max(max_lane_index, lane_index);
|
||||
trays.push_back(tray);
|
||||
}
|
||||
|
||||
if (trays.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_afc_filament_info: No AFC lanes found";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fetch filament info from Happy Hare MMU
|
||||
bool MoonrakerPrinterAgent::fetch_hh_filament_info(std::vector<AmsTrayData>& trays, int& max_lane_index)
|
||||
{
|
||||
// Query Happy Hare MMU status
|
||||
std::string url = join_url(device_info.base_url, "/printer/objects/query?mmu");
|
||||
|
||||
std::string response_body;
|
||||
bool success = false;
|
||||
std::string http_error;
|
||||
|
||||
auto http = Http::get(url);
|
||||
if (!device_info.api_key.empty()) {
|
||||
http.header("X-Api-Key", device_info.api_key);
|
||||
}
|
||||
http.timeout_connect(5)
|
||||
.timeout_max(10)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
if (status == 200) {
|
||||
response_body = body;
|
||||
success = true;
|
||||
} else {
|
||||
http_error = "HTTP error: " + std::to_string(status);
|
||||
}
|
||||
})
|
||||
.on_error([&](std::string body, std::string err, unsigned status) {
|
||||
http_error = err;
|
||||
if (status > 0) {
|
||||
http_error += " (HTTP " + std::to_string(status) + ")";
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
if (!success) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent::fetch_hh_filament_info: Failed to fetch HH data: " << http_error;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto json = nlohmann::json::parse(response_body, nullptr, false, true);
|
||||
if (json.is_discarded()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent::fetch_hh_filament_info: Invalid JSON response";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expected structure: { "result": { "status": { "mmu": { ... } } } }
|
||||
if (!json.contains("result") || !json["result"].contains("status") ||
|
||||
!json["result"]["status"].contains("mmu") || !json["result"]["status"]["mmu"].is_object()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent::fetch_hh_filament_info: No mmu object in response";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& mmu = json["result"]["status"]["mmu"];
|
||||
|
||||
// Check if HH is installed (empty mmu object means HH not installed)
|
||||
if (mmu.empty()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent::fetch_hh_filament_info: Empty mmu object (HH not installed)";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get num_gates
|
||||
if (!mmu.contains("num_gates") || !mmu["num_gates"].is_number()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent::fetch_hh_filament_info: No num_gates field";
|
||||
return false;
|
||||
}
|
||||
|
||||
int num_gates = mmu["num_gates"].get<int>();
|
||||
if (num_gates <= 0) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_hh_filament_info: Invalid num_gates: " << num_gates;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get arrays
|
||||
const auto& gate_status = mmu.contains("gate_status") ? mmu["gate_status"] : nlohmann::json::array();
|
||||
const auto& gate_material = mmu.contains("gate_material") ? mmu["gate_material"] : nlohmann::json::array();
|
||||
const auto& gate_color = mmu.contains("gate_color") ? mmu["gate_color"] : nlohmann::json::array();
|
||||
const auto& gate_temperature = mmu.contains("gate_temperature") ? mmu["gate_temperature"] : nlohmann::json::array();
|
||||
|
||||
if (!gate_status.is_array() || !gate_material.is_array() ||
|
||||
!gate_color.is_array() || !gate_temperature.is_array()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_hh_filament_info: HH arrays not found or invalid type";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse gate data
|
||||
trays.clear();
|
||||
max_lane_index = 0;
|
||||
|
||||
for (int gate_idx = 0; gate_idx < num_gates; ++gate_idx) {
|
||||
// Check gate_status: -1 = unknown, 0 = empty, 1 or 2 = available
|
||||
int status = safe_array_int(gate_status, gate_idx);
|
||||
if (status <= 0) {
|
||||
continue; // Skip unknown or empty gates
|
||||
}
|
||||
|
||||
// Extract gate data
|
||||
std::string material = safe_array_string(gate_material, gate_idx);
|
||||
std::string color = safe_array_string(gate_color, gate_idx);
|
||||
int nozzle_temp = safe_array_int(gate_temperature, gate_idx);
|
||||
|
||||
// Skip if no material type (empty gate)
|
||||
if (material.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AmsTrayData tray;
|
||||
tray.slot_index = gate_idx;
|
||||
tray.tray_type = material;
|
||||
tray.tray_color = color;
|
||||
tray.nozzle_temp = nozzle_temp;
|
||||
tray.bed_temp = 0; // HH doesn't provide bed temp in gate arrays
|
||||
tray.has_filament = true;
|
||||
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
tray.tray_info_idx = bundle
|
||||
? bundle->filaments.filament_id_by_type(tray.tray_type)
|
||||
: map_filament_type_to_generic_id(tray.tray_type);
|
||||
|
||||
max_lane_index = std::max(max_lane_index, gate_idx);
|
||||
trays.push_back(tray);
|
||||
}
|
||||
|
||||
if (trays.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_hh_filament_info: No valid HH gates found";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int MoonrakerPrinterAgent::handle_request(const std::string& dev_id, const std::string& json_str)
|
||||
{
|
||||
auto json = nlohmann::json::parse(json_str, nullptr, false);
|
||||
|
||||
@@ -160,6 +160,17 @@ private:
|
||||
const std::string& api_key,
|
||||
uint64_t generation);
|
||||
|
||||
// System-specific filament fetch methods
|
||||
bool fetch_hh_filament_info(std::vector<AmsTrayData>& trays, int& max_lane_index);
|
||||
bool fetch_afc_filament_info(std::vector<AmsTrayData>& trays, int& max_lane_index);
|
||||
|
||||
// JSON helper methods
|
||||
static std::string safe_json_string(const nlohmann::json& obj, const char* key);
|
||||
static int safe_json_int(const nlohmann::json& obj, const char* key);
|
||||
static std::string safe_array_string(const nlohmann::json& arr, int idx);
|
||||
static int safe_array_int(const nlohmann::json& arr, int idx);
|
||||
static std::string normalize_color_value(const std::string& color);
|
||||
|
||||
std::string ssdp_announced_host;
|
||||
std::string ssdp_announced_id;
|
||||
std::shared_ptr<ICloudServiceAgent> m_cloud_agent;
|
||||
|
||||
@@ -7,7 +7,7 @@ set(SLIC3R_APP_KEY "OrcaSlicer")
|
||||
if(NOT DEFINED BBL_INTERNAL_TESTING)
|
||||
set(BBL_INTERNAL_TESTING "0")
|
||||
endif()
|
||||
set(SoftFever_VERSION "2.3.2-beta")
|
||||
set(SoftFever_VERSION "2.3.2-beta2")
|
||||
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)"
|
||||
SoftFever_VERSION_MATCH ${SoftFever_VERSION})
|
||||
set(ORCA_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
|
||||
Reference in New Issue
Block a user