mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-22 16:32:40 +00:00
Compare commits
195
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cda25c3715 | ||
|
|
9e34ca536b | ||
|
|
201617a6c0 | ||
|
|
2dcbee3d76 | ||
|
|
6183007c28 | ||
|
|
b23953d7cf | ||
|
|
cfc6be5001 | ||
|
|
19e094a1d1 | ||
|
|
a2c631753b | ||
|
|
29b9076440 | ||
|
|
323cd3afe1 | ||
|
|
57b3a040e2 | ||
|
|
811b587eb0 | ||
|
|
2876374b45 | ||
|
|
f769a39b7f | ||
|
|
fd9c1218a4 | ||
|
|
adbeefd424 | ||
|
|
423e7b1dbd | ||
|
|
f27b0a1f9d | ||
|
|
cf1c164546 | ||
|
|
bca8dd00dd | ||
|
|
8b7f8cac82 | ||
|
|
aae03257ed | ||
|
|
3fba237c9a | ||
|
|
cfb6349695 | ||
|
|
f53ad6993a | ||
|
|
e168d900f2 | ||
|
|
bc03e3be2f | ||
|
|
f224b8e4a6 | ||
|
|
8b479c9af3 | ||
|
|
d8299c388e | ||
|
|
4d85b6627e | ||
|
|
ee2b4ccf70 | ||
|
|
753c793ea0 | ||
|
|
9c5494b19f | ||
|
|
93a119427a | ||
|
|
d264fcaef4 | ||
|
|
b4ab6dedfd | ||
|
|
ed59f93456 | ||
|
|
cf52c81dcd | ||
|
|
803a2a3239 | ||
|
|
985092bb46 | ||
|
|
cb16a2e547 | ||
|
|
2c2e91b629 | ||
|
|
c3faf903ca | ||
|
|
5f3c957597 | ||
|
|
8557285389 | ||
|
|
a9edab78a8 | ||
|
|
79dede7d59 | ||
|
|
2ac45b2f78 | ||
|
|
b4f33e71e9 | ||
|
|
8c91cab971 | ||
|
|
79077518e9 | ||
|
|
56aa348c89 | ||
|
|
ae1752fbf2 | ||
|
|
cf3f36a1c6 | ||
|
|
cca7d8adb1 | ||
|
|
396d9ff51a | ||
|
|
81540c81e0 | ||
|
|
e7ace6cc99 | ||
|
|
79c20a1fad | ||
|
|
e48f9f47d2 | ||
|
|
2f566e3779 | ||
|
|
37d1edf69a | ||
|
|
f1cf9c69b1 | ||
|
|
1df362888e | ||
|
|
4b2466b179 | ||
|
|
3adcb3e953 | ||
|
|
104dbb2140 | ||
|
|
e482cbbdd7 | ||
|
|
2a5ddd9edb | ||
|
|
c10f83cf61 | ||
|
|
8eeec6935e | ||
|
|
131a2abf99 | ||
|
|
9daecc59b4 | ||
|
|
58e000d842 | ||
|
|
af6be5858e | ||
|
|
3fc7fd99d6 | ||
|
|
3fe043651b | ||
|
|
b0b78c296c | ||
|
|
62791fabfa | ||
|
|
b0ada2dee5 | ||
|
|
8f4df1aa8c | ||
|
|
5fec9b8d19 | ||
|
|
75ed5afbac | ||
|
|
01c553bad9 | ||
|
|
a4376c77c3 | ||
|
|
c459994290 | ||
|
|
3a0fda7d18 | ||
|
|
eb8733f0f4 | ||
|
|
55acb940a8 | ||
|
|
0d691403de | ||
|
|
9b2b75a51d | ||
|
|
25da273ea0 | ||
|
|
dbcb82075f | ||
|
|
2f82cfe40f | ||
|
|
972031cf06 | ||
|
|
2a4792e762 | ||
|
|
dd15ac6146 | ||
|
|
b0469254bc | ||
|
|
2228589e16 | ||
|
|
4d8480e1a1 | ||
|
|
4320cc78d9 | ||
|
|
d9d9678a7e | ||
|
|
d55a0bfec6 | ||
|
|
3b1017df51 | ||
|
|
f5b81d2ffc | ||
|
|
eb9cfe0ecb | ||
|
|
1e8805d43d | ||
|
|
e8f089dfa4 | ||
|
|
84e929ea24 | ||
|
|
abec603e73 | ||
|
|
0ed19d4826 | ||
|
|
b747c13ef4 | ||
|
|
6a12aca495 | ||
|
|
d486db6459 | ||
|
|
fe777b8801 | ||
|
|
1b3e206f34 | ||
|
|
4df1607ec4 | ||
|
|
a0ec8bec8a | ||
|
|
36c362cbd2 | ||
|
|
84fde32616 | ||
|
|
34e349e323 | ||
|
|
44941e571f | ||
|
|
876d6e2499 | ||
|
|
858b3024ff | ||
|
|
6595557c34 | ||
|
|
c729849843 | ||
|
|
c0563be36e | ||
|
|
462f8dce30 | ||
|
|
b2a0485139 | ||
|
|
f16071f083 | ||
|
|
a1505e9bed | ||
|
|
8e48312b1f | ||
|
|
ba7fdb8ceb | ||
|
|
8be9800567 | ||
|
|
c4eabc3c52 | ||
|
|
0d0d281d0c | ||
|
|
c4bbcd322b | ||
|
|
7aea1b1235 | ||
|
|
41c16436bf | ||
|
|
2bbb229c91 | ||
|
|
c2a43157d2 | ||
|
|
738b30a743 | ||
|
|
6e6ffe13f8 | ||
|
|
eb96d127b0 | ||
|
|
60421c33f4 | ||
|
|
300c4b8afb | ||
|
|
96092ef2d3 | ||
|
|
d9002ad87d | ||
|
|
4c1ea0a602 | ||
|
|
9415812d85 | ||
|
|
d3c728557e | ||
|
|
6558c52849 | ||
|
|
a34d056de2 | ||
|
|
7ba5718be6 | ||
|
|
c1163ce7e5 | ||
|
|
da187eaaf9 | ||
|
|
de0268ce86 | ||
|
|
108923bdaa | ||
|
|
44793f7a21 | ||
|
|
7cb1805272 | ||
|
|
d5c528b7c7 | ||
|
|
742cb712d8 | ||
|
|
fd1c5d826c | ||
|
|
58be7f4861 | ||
|
|
4031b00915 | ||
|
|
07c62112b8 | ||
|
|
f23e4963bf | ||
|
|
95279f7084 | ||
|
|
1014558c91 | ||
|
|
6515062a3a | ||
|
|
8153e26b6d | ||
|
|
79fd33d49a | ||
|
|
cdb662d4b2 | ||
|
|
a27fa7b5df | ||
|
|
cdeed107c5 | ||
|
|
be92f7e78c | ||
|
|
76f9de4cfb | ||
|
|
cd6d2cbf5e | ||
|
|
deaca0189f | ||
|
|
7d54ee286d | ||
|
|
dddfc7a8ad | ||
|
|
673bfb0dee | ||
|
|
b9e8c5a38c | ||
|
|
a2a4ca20e4 | ||
|
|
12075459d2 | ||
|
|
f3770f3106 | ||
|
|
90fbf1770f | ||
|
|
bde94ab37f | ||
|
|
6d25e1777e | ||
|
|
7ce26ca8e5 | ||
|
|
367fcce634 | ||
|
|
9b3a44b339 | ||
|
|
6384191102 |
@@ -58,6 +58,9 @@ Paths below are relative to this skill. Commands run from the repository root.
|
||||
9. **Run the full profile checks before reporting completion.** A vendor-scoped pass is only a
|
||||
development loop. Review also covers version bumps, assets, non-default processes and hardware
|
||||
tuning that CI cannot establish.
|
||||
10. **One all-printer preset per product; color is a runtime property, never a preset.** Never ship
|
||||
presets that differ only by color — CI accepts them, so this is a review call. See
|
||||
[color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property).
|
||||
|
||||
## Creating or modifying a profile
|
||||
|
||||
@@ -107,6 +110,7 @@ Paths below are relative to this skill. Commands run from the repository root.
|
||||
| A setting has no effect | Key spelling/type, `handle_legacy`, or a config key placed on a `machine_model` |
|
||||
| A preset exists but is not selectable | Index registration, `instantiation`, installation and compatibility |
|
||||
| A filament is missing, duplicated, or matches the wrong spool | [Compatibility and alias shadowing](references/filament-profiles.md#compatible_printers); [ids](references/ids.md) |
|
||||
| Presets differ only by color, or an all-printer library preset lacks `@System` | [Color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property) |
|
||||
| A bed temperature is ignored | [Plate-specific temperature keys](references/filament-profiles.md#bed-temperature-is-twelve-keys-not-one) |
|
||||
| A change is absent from the running app | Version bump and [installed profile location](references/validation.md#testing-in-the-app) |
|
||||
| A check fails | [Error → remedy](references/validation.md#error--remedy) |
|
||||
|
||||
@@ -52,6 +52,15 @@ a brand means adding a folder here; the folder name is a directory label only
|
||||
collection, so there is no duplicate-name error.
|
||||
- You may inherit from an instantiated preset as well as from a base; it is common.
|
||||
|
||||
## Color is a runtime property
|
||||
|
||||
`filament_id` identifies a product, not a color; filament sync/AMS reads the color from the spool at
|
||||
runtime. A product ships one all-printer preset and the color is chosen at runtime — never a sibling
|
||||
preset that differs only by color. A material family (PLA vs PLA Matte vs PLA Silk) is a new product; a
|
||||
color is not. A printer tune keeps the product alias and does not multiply per color either.
|
||||
|
||||
CI does not catch this — per-color presets pass `check` — so it is a review call.
|
||||
|
||||
## The two most common contributions
|
||||
|
||||
**A printer vendor tuning a generic.** Keep the `Generic X` base name so the alias shadows the library
|
||||
|
||||
@@ -46,12 +46,17 @@ to the first `@`; the target half is a label except for reserved forms:
|
||||
|
||||
- `@base` — a non-instantiated product root. `@base` is convention; a base is really identified by
|
||||
`instantiation: "false"` and no `setting_id` ([the three-part shape](filament-profiles.md#the-three-part-shape)).
|
||||
- `@System` — the OrcaFilamentLibrary selectable shim. The literal `Generic <mat> @System` is
|
||||
load-bearing for 3MF/project recovery, beyond the alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)).
|
||||
- `@System` — the OrcaFilamentLibrary selectable shim, and the convention for an all-printer product
|
||||
(`<Product> @System`, empty `compatible_printers`); not enforced, so a deviation is worth a review
|
||||
comment. The literal `Generic <mat> @System` is load-bearing for 3MF/project recovery, beyond the
|
||||
alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)).
|
||||
- `@<Vendor>`, `@<Vendor> <Model>`, `@<Vendor> <Model> <nozzle> nozzle` — printer tunes, BBL's shape.
|
||||
Other vendors differ (a bare model, a printer serial, Creality's `@<Model>-all`). Specificity is judged
|
||||
from `compatible_printers`, not the name
|
||||
([one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)).
|
||||
- Color is not part of the product name: `<Product> <Color>` presets are not authored; the color is
|
||||
chosen at runtime
|
||||
([color is a runtime property](filament-profiles.md#color-is-a-runtime-property)).
|
||||
|
||||
## Not the same as the filename
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ The table highlights gaps that need human review. What CI *does* run:
|
||||
| Whether the intended default survived compatibility selection | The sweep can select a different compatible preset |
|
||||
| A dangling `compatible_printers` inside an `instantiation: "false"` base | A base never becomes a `Preset`, so the reference check never sees it (a bad `inherits` in a base *is* caught) |
|
||||
| A `renamed_from` whose old name is still a live preset | The redirect is inert while a live preset carries that name |
|
||||
| A preset differentiated only by color, or an all-printer library preset without `@System` | Per-color presets split one product across ids and the selector fills with near-duplicates; CI stays green |
|
||||
| Per-extruder vector length on a multi-nozzle printer | Silently padded (with the **first** value) or truncated |
|
||||
|
||||
## 1. Was the vendor `version` bumped?
|
||||
|
||||
+42
-2
@@ -826,6 +826,37 @@ find_package(OpenSSL REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
|
||||
if (SLIC3R_GUI)
|
||||
# LibDataChannel's installed export references its bundled dependencies,
|
||||
# but does not install their CMake targets. Recreate those targets from
|
||||
# the same dependency prefix before loading the LibDataChannel config.
|
||||
if (NOT TARGET Usrsctp::usrsctp)
|
||||
find_library(_ORCA_USRSCTP_LIBRARY NAMES usrsctp
|
||||
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
|
||||
if (_ORCA_USRSCTP_LIBRARY)
|
||||
add_library(Usrsctp::usrsctp UNKNOWN IMPORTED GLOBAL)
|
||||
set_target_properties(Usrsctp::usrsctp PROPERTIES
|
||||
IMPORTED_LOCATION "${_ORCA_USRSCTP_LIBRARY}"
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES C
|
||||
INTERFACE_LINK_LIBRARIES "Threads::Threads")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT TARGET LibJuice::LibJuice)
|
||||
find_library(_ORCA_LIBJUICE_LIBRARY NAMES juice
|
||||
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
|
||||
if (_ORCA_LIBJUICE_LIBRARY)
|
||||
add_library(LibJuice::LibJuice UNKNOWN IMPORTED GLOBAL)
|
||||
set_target_properties(LibJuice::LibJuice PROPERTIES
|
||||
IMPORTED_LOCATION "${_ORCA_LIBJUICE_LIBRARY}"
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES C
|
||||
INTERFACE_LINK_LIBRARIES "Threads::Threads")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(LibDataChannel CONFIG REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(libcurl INTERFACE)
|
||||
target_link_libraries(libcurl INTERFACE CURL::libcurl)
|
||||
@@ -1106,6 +1137,7 @@ function(orcaslicer_copy_dlls target config postfix output_dlls)
|
||||
endif ()
|
||||
file(COPY ${_occt_dlls}
|
||||
${CMAKE_PREFIX_PATH}/bin/freetype.dll
|
||||
${CMAKE_PREFIX_PATH}/bin/avformat-61.dll
|
||||
${CMAKE_PREFIX_PATH}/bin/avcodec-61.dll
|
||||
${CMAKE_PREFIX_PATH}/bin/swresample-5.dll
|
||||
${CMAKE_PREFIX_PATH}/bin/swscale-8.dll
|
||||
@@ -1118,11 +1150,11 @@ function(orcaslicer_copy_dlls target config postfix output_dlls)
|
||||
${_out_dir}/WebView2Loader.dll
|
||||
|
||||
${_out_dir}/freetype.dll
|
||||
${_out_dir}/avformat-61.dll
|
||||
${_out_dir}/avcodec-61.dll
|
||||
${_out_dir}/swresample-5.dll
|
||||
${_out_dir}/swscale-8.dll
|
||||
${_out_dir}/avutil-59.dll
|
||||
PARENT_SCOPE
|
||||
)
|
||||
list(APPEND _dll_list ${_occt_staged})
|
||||
set(${output_dlls} ${_dll_list} PARENT_SCOPE)
|
||||
@@ -1142,7 +1174,10 @@ function(orcaslicer_copy_sos target config postfix output_sos)
|
||||
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif ()
|
||||
|
||||
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavcodec.so
|
||||
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavformat.so
|
||||
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61
|
||||
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61.1.100
|
||||
${CMAKE_PREFIX_PATH}/lib/libavcodec.so
|
||||
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61
|
||||
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61.3.100
|
||||
${CMAKE_PREFIX_PATH}/lib/libavutil.so
|
||||
@@ -1157,6 +1192,9 @@ function(orcaslicer_copy_sos target config postfix output_sos)
|
||||
DESTINATION ${_out_dir})
|
||||
|
||||
set(${output_sos}
|
||||
${_out_dir}/libavformat.so
|
||||
${_out_dir}/libavformat.so.61
|
||||
${_out_dir}/libavformat.so.61.1.100
|
||||
${_out_dir}/libavcodec.so
|
||||
${_out_dir}/libavcodec.so.61
|
||||
${_out_dir}/libavcodec.so.61.3.100
|
||||
@@ -1286,6 +1324,8 @@ endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(LIBRARY_FILES
|
||||
${LIBDIR_BIN}/libavformat.so.61
|
||||
${LIBDIR_BIN}/libavformat.so.61.1.100
|
||||
${LIBDIR_BIN}/libavcodec.so.61
|
||||
${LIBDIR_BIN}/libavcodec.so.61.3.100
|
||||
${LIBDIR_BIN}/libavutil.so.59
|
||||
|
||||
Vendored
+23
-11
@@ -156,7 +156,7 @@ if (NOT _is_multi AND NOT CMAKE_BUILD_TYPE)
|
||||
endif ()
|
||||
|
||||
function(orcaslicer_add_cmake_project projectname)
|
||||
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
|
||||
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND;SOURCE_DIR" "CMAKE_ARGS" ${ARGN})
|
||||
|
||||
# MSVC is true for clang-cl as well, so the sub-build toolchain has to key on the
|
||||
# generator. A non-Visual-Studio superbuild passes its own generator down, and with
|
||||
@@ -202,12 +202,18 @@ function(orcaslicer_add_cmake_project projectname)
|
||||
set(_build_j "-j${NPROC}")
|
||||
endif ()
|
||||
|
||||
set(_source_dir_arg "")
|
||||
if (P_ARGS_SOURCE_DIR)
|
||||
set(_source_dir_arg SOURCE_DIR ${P_ARGS_SOURCE_DIR})
|
||||
endif ()
|
||||
|
||||
if (NOT IS_CROSS_COMPILE OR NOT APPLE)
|
||||
ExternalProject_Add(
|
||||
dep_${projectname}
|
||||
EXCLUDE_FROM_ALL ON
|
||||
INSTALL_DIR ${DESTDIR}
|
||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
|
||||
${_source_dir_arg}
|
||||
${_gen}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
@@ -240,12 +246,14 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
|
||||
# note for future devs: shared libs may actually create a size reduction
|
||||
# but orcaslicer_deps tends to get really funny regarding linking after that (notably boost)
|
||||
# so, as much as I would like to use that, it's not happening
|
||||
ExternalProject_Add_Step(dep_${projectname} free_download_space
|
||||
DEPENDEES download # do after download
|
||||
COMMENT "Freeing Space: Removing source archive"
|
||||
WORKING_DIRECTORY ${DEP_DOWNLOAD_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -r ${projectname}
|
||||
)
|
||||
if (NOT P_ARGS_SOURCE_DIR)
|
||||
ExternalProject_Add_Step(dep_${projectname} free_download_space
|
||||
DEPENDEES download # do after download
|
||||
COMMENT "Freeing Space: Removing source archive"
|
||||
WORKING_DIRECTORY ${DEP_DOWNLOAD_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${projectname}
|
||||
)
|
||||
endif ()
|
||||
ExternalProject_Add_Step(dep_${projectname} free_build_space
|
||||
DEPENDEES install # do after install
|
||||
COMMENT "Freeing Space: Removing source and build files"
|
||||
@@ -259,6 +267,7 @@ else()
|
||||
EXCLUDE_FROM_ALL ON
|
||||
INSTALL_DIR ${DESTDIR}
|
||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
|
||||
${_source_dir_arg}
|
||||
${_gen}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
@@ -386,10 +395,6 @@ include(libnoise/libnoise.cmake)
|
||||
|
||||
include(Draco/Draco.cmake)
|
||||
|
||||
include(FFMPEG/FFMPEG.cmake)
|
||||
include(Assimp/Assimp.cmake)
|
||||
|
||||
|
||||
# I *think* 1.1 is used for *just* md5 hashing?
|
||||
# 3.1 has everything in the right place, but the md5 funcs used are deprecated
|
||||
# a grep across the repo shows it is used for other things
|
||||
@@ -400,6 +405,12 @@ if(NOT OPENSSL_FOUND)
|
||||
set(OPENSSL_PKG dep_OpenSSL)
|
||||
endif()
|
||||
|
||||
include(FFMPEG/FFMPEG.cmake)
|
||||
include(Assimp/Assimp.cmake)
|
||||
|
||||
include(DataChannel/DataChannel.cmake)
|
||||
set(DATACHANNEL_PKG dep_DataChannel)
|
||||
|
||||
# we don't want to load a "wrong" openssl when loading curl
|
||||
# so, just don't even bother
|
||||
# ...i think this is how it works? change if wrong
|
||||
@@ -473,6 +484,7 @@ set(_dep_list
|
||||
dep_wxInspector
|
||||
dep_FFMPEG
|
||||
dep_Assimp
|
||||
${DATACHANNEL_PKG}
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
# libdatachannel is the native ICE/DTLS/SCTP implementation used by the
|
||||
# GUI WebRTC camera controller. Keep the source revision fixed: the signaling
|
||||
# protocol is evolving independently of this transport dependency.
|
||||
#
|
||||
# It vendors plog, usrsctp and libjuice as git submodules, which a plain
|
||||
# GitHub tag tarball does not include. The flatpak sandbox has no network
|
||||
# access during the build, so there the manifest itself clones the repo
|
||||
# (submodules and all) into the dependency download directory before the
|
||||
# sandbox closes. ExternalProject_Add is pointed at that existing checkout
|
||||
# instead of being given its own network-dependent download method.
|
||||
if (FLATPAK)
|
||||
set(_datachannel_source
|
||||
SOURCE_DIR ${DEP_DOWNLOAD_DIR}/DataChannel
|
||||
)
|
||||
else()
|
||||
set(_datachannel_source
|
||||
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
|
||||
GIT_TAG v0.24.5
|
||||
GIT_SHALLOW ON
|
||||
GIT_SUBMODULES_RECURSE ON
|
||||
)
|
||||
endif()
|
||||
|
||||
orcaslicer_add_cmake_project(DataChannel
|
||||
DEPENDS ${OPENSSL_PKG}
|
||||
CMAKE_ARGS
|
||||
-DNO_EXAMPLES=ON
|
||||
-DNO_TESTS=ON
|
||||
-DNO_WEBSOCKET=ON
|
||||
-DNO_MEDIA=ON
|
||||
-DUSE_NICE=OFF
|
||||
-DUSE_SYSTEM_JUICE=OFF
|
||||
-DUSE_SYSTEM_USRSCTP=OFF
|
||||
-DOPENSSL_ROOT_DIR:PATH=${DESTDIR}
|
||||
-DOPENSSL_USE_STATIC_LIBS=ON
|
||||
${_datachannel_source}
|
||||
)
|
||||
Vendored
+23
-7
@@ -1,14 +1,26 @@
|
||||
set(_conf_cmd ./configure)
|
||||
|
||||
set(_ffmpeg_depends)
|
||||
set(_ffmpeg_configure_command ${_conf_cmd})
|
||||
if (TARGET dep_OpenSSL)
|
||||
set(_ffmpeg_depends DEPENDS dep_OpenSSL)
|
||||
set(_ffmpeg_configure_command
|
||||
${CMAKE_COMMAND} -E env
|
||||
"PKG_CONFIG_PATH=${DESTDIR}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}"
|
||||
${_conf_cmd}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set(_source_dir "${CMAKE_BINARY_DIR}/dep_FFMPEG-prefix/src/dep_FFMPEG")
|
||||
|
||||
set(PREBUILD_URL_arm64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-07-17-14-28/ffmpeg-n7.0.3-31-g9b6ffd74b5-winarm64-orca-shared-7.0.zip")
|
||||
set(PREBUILD_HASH_arm64 "12f4140279f2f8469885e1b5b2e8be9d788882914c21523cacd56989f3548054")
|
||||
set(PREBUILD_URL_x64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-07-17-14-28/ffmpeg-n7.0.3-31-g9b6ffd74b5-win64-orca-shared-7.0.zip")
|
||||
set(PREBUILD_HASH_x64 "e65916020ddb9ef84b2666dfbcbfc9b1d67f69d15b4a66db53754637bf2d498c")
|
||||
set(PREBUILD_URL_arm64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-09-18-16-50/ffmpeg-n7.0.3-33-g887d4b4919-winarm64-orca-shared-7.0.zip")
|
||||
set(PREBUILD_HASH_arm64 "da480cbb39680056de824c57ec4dc3bd577b479ebbc310ff1f9dc55cf014b4c1")
|
||||
set(PREBUILD_URL_x64 "https://github.com/Noisyfox/FFmpeg-Builds-Orca/releases/download/autobuild-2026-09-18-16-50/ffmpeg-n7.0.3-33-g887d4b4919-win64-orca-shared-7.0.zip")
|
||||
set(PREBUILD_HASH_x64 "85da19daf198f5548259d8aabb349db84997a3f6e6886d8d7764114add9c6dae")
|
||||
|
||||
ExternalProject_Add(dep_FFMPEG
|
||||
${_ffmpeg_depends}
|
||||
URL ${PREBUILD_URL_${DEPS_ARCH}}
|
||||
URL_HASH SHA256=${PREBUILD_HASH_${DEPS_ARCH}}
|
||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG
|
||||
@@ -21,6 +33,8 @@ if (MSVC)
|
||||
)
|
||||
|
||||
else ()
|
||||
set(_openssl_cmd --enable-openssl)
|
||||
|
||||
if (APPLE)
|
||||
set(_minos_cmd
|
||||
"--extra-cflags=-mmacosx-version-min=${DEP_OSX_TARGET}"
|
||||
@@ -52,10 +66,11 @@ else ()
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(dep_FFMPEG
|
||||
${_ffmpeg_depends}
|
||||
URL https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.0.3.tar.gz
|
||||
URL_HASH SHA256=DEEDCABE339165214A3637DF4C86A507AEF0D793CF8774FF68735F4737E8DDBC
|
||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG
|
||||
CONFIGURE_COMMAND ${_conf_cmd}
|
||||
CONFIGURE_COMMAND ${_ffmpeg_configure_command}
|
||||
${_cross_cmd}
|
||||
${_pic_cmd}
|
||||
${_arch_cmd}
|
||||
@@ -63,20 +78,21 @@ else ()
|
||||
"--prefix=${DESTDIR}"
|
||||
${_link_cmd}
|
||||
${_minos_cmd}
|
||||
${_openssl_cmd}
|
||||
--disable-doc
|
||||
--enable-small
|
||||
--disable-outdevs
|
||||
--disable-filters
|
||||
--enable-filter=*null*,afade,*fifo,*format,*resample,aeval,allrgb,allyuv,atempo,pan,*bars,color,*key,crop,draw*,eq*,framerate,*_qsv,*_vaapi,*v4l2*,hw*,scale,volume,test*
|
||||
--disable-protocols
|
||||
--enable-protocol=file,fd,pipe,rtp,udp
|
||||
--enable-protocol=file,fd,pipe,http,https,rtp,tcp,udp
|
||||
--disable-muxers
|
||||
--enable-muxer=rtp
|
||||
--disable-encoders
|
||||
--disable-decoders
|
||||
--enable-decoder=*aac*,h264*,mp3*,mjpeg,rv*
|
||||
--disable-demuxers
|
||||
--enable-demuxer=h264,mp3,mov
|
||||
--enable-demuxer=h264,mp3,mov,mpjpeg,rtsp,sdp
|
||||
--disable-zlib
|
||||
--disable-avdevice
|
||||
BUILD_IN_SOURCE ON
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
# Printer agents
|
||||
|
||||
Printer agents isolate printer-specific communication from the rest of OrcaSlicer. The GUI and
|
||||
`DeviceManager` operate on a shared set of printer operations and device state; a selected printer
|
||||
agent implements those operations for a particular printer ecosystem. The agent boundary allows
|
||||
Bambu, Moonraker-based printers, built-in integrations, and Python-provided integrations to use the
|
||||
same application workflow without making the GUI understand every printer protocol.
|
||||
|
||||
The current boundary is an adapter boundary around the existing application contract. In particular,
|
||||
some request fields and message payloads still use the Bambu-shaped representation that existing
|
||||
`MachineObject` and `DeviceManager` code consumes. The printer agent is responsible for translating
|
||||
that representation into the protocol spoken by its printer. This is an intentional compatibility
|
||||
constraint of the current design; the interface is not yet a neutral printer protocol.
|
||||
|
||||
The v1 dialect migration path is deliberately narrow. `DeviceManager` currently speaks the Bambu JSON
|
||||
dialect because that is the payload shape already used throughout the command and state workflow. The
|
||||
v1 `OrcaPrinterAgent` also accepts that Bambu dialect. Its transport path places the small translation
|
||||
needed for the target printer at `deliver_to_sink`, keeping the compatibility code at the edge rather
|
||||
than spreading it through `DeviceManager` or the agent interface.
|
||||
|
||||
The eventual direction is for `DeviceManager` to produce an Orca JSON dialect. The Bambu agent will then
|
||||
own the translation from Orca JSON to Bambu's protocol, while `OrcaPrinterAgent` can forward the Orca
|
||||
payload directly to its sink. The v1 translation at `deliver_to_sink` can then be removed without
|
||||
changing `DeviceManager`, the command callers, or the rest of the agent workflow.
|
||||
|
||||
## Components
|
||||
|
||||
The system has four relevant layers:
|
||||
|
||||
```text
|
||||
GUI / DeviceManager / MachineObject
|
||||
|
|
||||
NetworkAgent
|
||||
/ \
|
||||
IPrinterAgent ICloudServiceAgent
|
||||
| |
|
||||
printer protocol authentication and cloud services
|
||||
```
|
||||
|
||||
### `DeviceManager` and `MachineObject`
|
||||
|
||||
`DeviceManager` owns the application-facing printer workflow. It maintains `MachineObject` instances,
|
||||
updates their state, filters devices for the active printer agent, and initiates operations such as
|
||||
homing, temperature changes, printing, subscriptions, and camera playback.
|
||||
|
||||
`MachineObject` remains the shared state model used by the GUI. It does not contain the implementation
|
||||
of a printer protocol. When a device is discovered or returned by a cloud query, the device is tagged
|
||||
with the active `printer_agent_id`. Device lists and selected-machine operations use that tag to avoid
|
||||
sending an operation through an agent that does not own the device.
|
||||
|
||||
### `NetworkAgent`
|
||||
|
||||
`NetworkAgent` is the façade used by the GUI and `DeviceManager`. It owns:
|
||||
|
||||
- the currently selected `IPrinterAgent`;
|
||||
- the registered cloud-service instances, indexed by provider;
|
||||
- callbacks shared by the active printer agent and the application;
|
||||
- the forwarding methods for printer commands and cloud operations.
|
||||
|
||||
There is one active printer agent for the currently selected printer preset. Switching the preset
|
||||
increments the machine-list generation, disconnects the old printer agent, removes its callbacks, and
|
||||
installs the newly selected agent. The façade then forwards printer operations to that agent.
|
||||
|
||||
Cloud operations are selected separately using a provider key. `NetworkAgent` forwards a cloud request
|
||||
to the matching `ICloudServiceAgent`, and forwards cloud camera operations with a device ID. The
|
||||
printer agent receives a cloud-agent pointer through `set_cloud_agent()` when it is created, allowing
|
||||
printer communication to obtain cloud tokens without depending on a concrete cloud implementation.
|
||||
|
||||
### `IPrinterAgent`
|
||||
|
||||
`IPrinterAgent` is the printer-facing contract. It covers:
|
||||
|
||||
- cloud-relay and direct-LAN message delivery;
|
||||
- LAN connection, discovery, binding, and certificates;
|
||||
- printer subscriptions and callbacks;
|
||||
- print operations;
|
||||
- filament synchronization;
|
||||
- camera capability and local camera URL reporting;
|
||||
- printer command methods.
|
||||
|
||||
Concrete built-in implementations include the Bambu wrapper, the native Orca/Moonraker path, and
|
||||
other printer-agent implementations registered by the application. A printer agent may use either
|
||||
the cloud agent, a direct LAN connection, or both.
|
||||
|
||||
### `ICloudServiceAgent`
|
||||
|
||||
`ICloudServiceAgent` owns authentication and services provided by a cloud backend. It covers login
|
||||
state, tokens, user and printer lists, settings synchronization, model services, cloud messages, and
|
||||
cloud camera operations.
|
||||
|
||||
Cloud camera operations are device-scoped:
|
||||
|
||||
- `get_camera_url(dev_id, callback)` obtains a stream URL for one device;
|
||||
- `create_camera_signaling_channel(dev_id)` creates signaling for one device where the provider
|
||||
supports it.
|
||||
|
||||
This is separate from the local camera URL exposed by `IPrinterAgent`, which is currently scoped to
|
||||
the active printer agent because a normal LAN agent represents one physical printer connection.
|
||||
|
||||
## Agent registration and selection
|
||||
|
||||
`NetworkAgentFactory` maintains the printer-agent registry. Each registry entry contains an agent ID,
|
||||
a display name, and a factory function. Built-in agents register during application initialization.
|
||||
Python printer-agent capabilities register dynamically and contribute an agent ID and factory entry.
|
||||
|
||||
The selected printer preset contains the printer-agent choice. If no explicit choice is stored, the
|
||||
application preserves the existing default behavior: Bambu presets select the Bambu agent and other
|
||||
presets select the native Orca agent. When a preset is changed, `GUI_App` resolves the effective agent
|
||||
ID, obtains the corresponding cloud agent, creates the printer agent through the registry, and installs
|
||||
it in `NetworkAgent`.
|
||||
|
||||
The registry rejects conflicting agent IDs. This matters for Python plugins because an agent ID is the
|
||||
stable identity used by presets and device ownership; two enabled plugin capabilities must not claim
|
||||
the same ID.
|
||||
|
||||
## Message and command flow
|
||||
|
||||
There are two low-level message paths:
|
||||
|
||||
- `send_message()` publishes a command through the printer's cloud relay;
|
||||
- `send_message_to_printer()` sends a command directly to the printer over the LAN path.
|
||||
|
||||
Both paths accept a JSON string, quality-of-service and flag values, and return the existing network
|
||||
status code domain. The agent owns the conversion from that JSON contract to its native transport.
|
||||
|
||||
The typed `command_*` methods are the application-facing convenience layer. The five generic defaults
|
||||
currently implemented by `IPrinterAgent` construct the existing JSON dialect and route through the
|
||||
same message path:
|
||||
|
||||
| Method | Default operation |
|
||||
| --- | --- |
|
||||
| `command_xyz_abs()` | Send `G90` for absolute positioning |
|
||||
| `command_auto_leveling()` | Send `G29` for bed leveling |
|
||||
| `command_go_home()` | Use the supported homing operation or send `G28` |
|
||||
| `command_set_bed()` | Use the supported bed control or send `M140` |
|
||||
| `command_set_nozzle()` | Send `M104` for nozzle temperature |
|
||||
|
||||
These are compatibility defaults for common printer workflows, not a guarantee that every firmware
|
||||
implements every command identically. An agent can override a method when its protocol needs another
|
||||
operation. For example, a Klipper configuration may use `BED_MESH_CALIBRATE` instead of `G29`.
|
||||
|
||||
The remaining common command methods default to `ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED` because their
|
||||
existing behavior is vendor-specific or has no portable implementation:
|
||||
|
||||
- AMS RFID refresh;
|
||||
- AMS calibration;
|
||||
- AMS tray selection;
|
||||
- camera start;
|
||||
- axis control.
|
||||
|
||||
The methods remain on the common interface so an agent that supports them can override them explicitly.
|
||||
`sequence_id` remains part of the command contract because `DeviceManager` creates and tracks it as
|
||||
the command ID.
|
||||
|
||||
## Device ownership and stale responses
|
||||
|
||||
Printer-agent ownership is represented by `printer_agent_id` on device records and `MachineObject`
|
||||
instances. The active agent ID is attached when a device is discovered, returned by a cloud list, or
|
||||
reused after a preset switch. Local-machine configuration also persists the agent ID so a saved LAN
|
||||
device is not silently reused by an unrelated agent.
|
||||
|
||||
Cloud printer-list responses carry three pieces of request context added by `NetworkAgent`:
|
||||
|
||||
```text
|
||||
provider cloud provider used for the request
|
||||
agent_id active printer agent when the request was made
|
||||
generation machine-list generation when the request was made
|
||||
```
|
||||
|
||||
`DeviceManager` accepts the response only when those values still match the current provider, active
|
||||
agent, and generation. This prevents a slow response from the previous preset or provider from
|
||||
repopulating the current device list.
|
||||
|
||||
The provider mapping is currently selected by `GUI_App`: the Bambu agent maps to the Bambu cloud
|
||||
provider and other agents map to the Orca cloud provider. The generation check protects that existing
|
||||
selection from races; it does not make cloud-provider ownership intrinsic to an agent. Cloud-printer
|
||||
ownership and the broader Orca cloud services are therefore still separate architectural concerns.
|
||||
|
||||
## Python printer agents
|
||||
|
||||
`PrinterAgentPluginCapability` implements `IPrinterAgent` directly. The live capability object is
|
||||
registered with `NetworkAgentFactory` and handed out as the printer agent when its agent ID is selected.
|
||||
The plugin receives the selected `ICloudServiceAgent` through `set_cloud_agent()` just like a built-in
|
||||
printer agent.
|
||||
|
||||
Python plugins must implement the core communication and lifecycle methods required by the interface,
|
||||
including agent metadata, printer connection, discovery callbacks, and the two message-send methods.
|
||||
Methods that are meaningful only to a particular printer are optional overrides where the C++ base
|
||||
class provides a default.
|
||||
|
||||
All ten `command_*` methods are available in the Python binding and in the trampoline. Their override
|
||||
status is intentionally optional:
|
||||
|
||||
- the five generic commands use the C++ default when Python does not override them;
|
||||
- the five vendor-specific commands return `NOT_SUPPORTED` unless Python supplies an implementation;
|
||||
- a Python implementation can replace either behavior for its own protocol.
|
||||
|
||||
The Python camera binding exposes HTTP, HTTPS, RTSP, and HTTP-snapshot modes. WebRTC remains a
|
||||
built-in C++ camera mode, but is not exposed as a Python mode because the current Python capability
|
||||
does not provide the corresponding cloud signaling-channel contract.
|
||||
|
||||
## Camera playback boundary
|
||||
|
||||
The camera stream mode describes how a stream is obtained; it does not by itself define ownership of
|
||||
the wxWidgets view that renders it. `MediaPlayCtrl` selects and tears down the active backend, while
|
||||
the wx parent owns the child window or renderer. This is important because a web view, native media
|
||||
control, and frame-based/WebRTC renderer have different wx window-lifetime requirements.
|
||||
|
||||
Cloud URL and signaling requests are routed through `NetworkAgent` to the cloud provider selected for
|
||||
the device. Local URL requests are routed to the active printer agent. The distinction keeps cloud
|
||||
account services device-scoped while preserving the current one-LAN-agent/one-printer model.
|
||||
|
||||
## Compatibility constraints
|
||||
|
||||
The printer-agent boundary intentionally preserves several existing application contracts:
|
||||
|
||||
- Bambu-shaped JSON is still the shared command representation;
|
||||
- existing network status codes are reused, with Orca-specific unsupported/capability errors added
|
||||
in the Orca-reserved range;
|
||||
- `MachineObject` remains the shared device-state model;
|
||||
- preset and local-machine data retain compatibility with the existing agent-selection behavior;
|
||||
- Python plugins use the existing capability and pybind11 registration system.
|
||||
|
||||
The agent abstraction is therefore responsible for containing vendor differences, not for pretending
|
||||
that all vendor protocols are identical. The planned Orca JSON dialect is the protocol-neutral command
|
||||
model for the `DeviceManager`/agent boundary. Once it is introduced, Bambu-specific translation remains
|
||||
inside the Bambu agent and the Orca agent's v1 sink adapter can be removed as a self-contained cleanup.
|
||||
|
||||
## Main implementation locations
|
||||
|
||||
- [`IPrinterAgent`](../../src/slic3r/Utils/IPrinterAgent.hpp) — printer-agent contract and generic command defaults
|
||||
- [`ICloudServiceAgent`](../../src/slic3r/Utils/ICloudServiceAgent.hpp) — cloud service and per-device
|
||||
cloud camera contract
|
||||
- [`NetworkAgent`](../../src/slic3r/Utils/NetworkAgent.hpp) — façade and dispatch between active agents
|
||||
- [`NetworkAgentFactory`](../../src/slic3r/Utils/NetworkAgentFactory.hpp) — built-in and Python agent registry
|
||||
- [`DeviceManager`](../../src/slic3r/GUI/DeviceCore/DevManager.cpp) — device ownership, filtering, and
|
||||
stale-response checks
|
||||
- [`PrinterAgentPluginCapability`](../../src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp)
|
||||
— Python bindings
|
||||
- [`MediaPlayCtrl`](../../src/slic3r/GUI/MediaPlayCtrl.cpp) — camera backend selection and playback lifecycle
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -6161,9 +6161,6 @@ msgstr ""
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
@@ -6171,6 +6168,9 @@ msgstr ""
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -6637,9 +6637,6 @@ msgstr "Mostrar el contorn al voltant de l'objecte seleccionat a l'escena 3D"
|
||||
msgid "Preferences"
|
||||
msgstr "Preferències"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6648,6 +6645,9 @@ msgstr "Edita"
|
||||
msgid "View"
|
||||
msgstr "Vista"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Paquet de perfils"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Jakub Hencl\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6602,9 +6602,6 @@ msgstr "Zobrazit obrys kolem vybraného objektu ve 3D scéně."
|
||||
msgid "Preferences"
|
||||
msgstr "Předvolby"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6613,6 +6610,9 @@ msgstr "Upravit"
|
||||
msgid "View"
|
||||
msgstr "Zobrazit"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Balík předvoleb"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6490,9 +6490,6 @@ msgstr "Kontur um das ausgewählte Objekt in der 3D-Szene anzeigen."
|
||||
msgid "Preferences"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6501,6 +6498,9 @@ msgstr "Bearbeiten"
|
||||
msgid "View"
|
||||
msgstr "Ansicht"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Vorlagen-Bundle"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6157,9 +6157,6 @@ msgstr ""
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
@@ -6167,6 +6164,9 @@ msgstr ""
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Ian A. Bassi <>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6346,9 +6346,6 @@ msgstr "Mostrar el contorno alrededor del objeto seleccionado en la escena 3D."
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr "Edición"
|
||||
@@ -6356,6 +6353,9 @@ msgstr "Edición"
|
||||
msgid "View"
|
||||
msgstr "Vista"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Paquete de perfiles"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-07-20 13:33+0200\n"
|
||||
"Last-Translator: Manu Goiogana <mgoiogana@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6392,9 +6392,6 @@ msgstr "Erakutsi hautatutako objektuaren inguruko ingerada 3D eszenan."
|
||||
msgid "Preferences"
|
||||
msgstr "Hobespenak"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6403,6 +6400,9 @@ msgstr "Editatu"
|
||||
msgid "View"
|
||||
msgstr "Bista"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Aurrezarpen-paketea"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Guislain Cyril, Thomas Lété\n"
|
||||
@@ -6439,9 +6439,6 @@ msgstr "Afficher le tracé contour de l’objet sélectionné dans la scène 3D.
|
||||
msgid "Preferences"
|
||||
msgstr "Préférences"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6450,6 +6447,9 @@ msgstr "Édition"
|
||||
msgid "View"
|
||||
msgstr "Affichage"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Paquet de préréglages"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -6541,9 +6541,6 @@ msgstr "Körvonal megjelenítése a kijelölt objektum körül a 3D nézetben."
|
||||
msgid "Preferences"
|
||||
msgstr "Beállítások"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6552,6 +6549,9 @@ msgstr "Szerkesztés"
|
||||
msgid "View"
|
||||
msgstr "Nézet"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Beállításcsomag"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -6543,9 +6543,6 @@ msgstr "Mostra il contorno attorno all'oggetto selezionato nella scena 3D."
|
||||
msgid "Preferences"
|
||||
msgstr "Preferenze"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6554,6 +6551,9 @@ msgstr "Modifica"
|
||||
msgid "View"
|
||||
msgstr "Vista"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Pacchetto profili"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -6553,9 +6553,6 @@ msgstr "3Dシーンで選択したオブジェクトの周りにアウトライ
|
||||
msgid "Preferences"
|
||||
msgstr "設定"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6564,6 +6561,9 @@ msgstr "編集"
|
||||
msgid "View"
|
||||
msgstr "表示"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "プリセットバンドル"
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
|
||||
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6566,9 +6566,6 @@ msgstr "3D 장면에서 선택한 객체 주변에 윤곽선 표시"
|
||||
msgid "Preferences"
|
||||
msgstr "기본 설정"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6577,6 +6574,9 @@ msgstr "편집"
|
||||
msgid "View"
|
||||
msgstr "시점"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "사전 설정 번들"
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-07-02 14:13+0300\n"
|
||||
"Last-Translator: Gintaras Kučinskas <sharanchius@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6528,9 +6528,6 @@ msgstr "Rodyti kontūrą aplink pasirinktą objektą 3D scenoje."
|
||||
msgid "Preferences"
|
||||
msgstr "Parinktys"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6539,6 +6536,9 @@ msgstr "Redaguoti"
|
||||
msgid "View"
|
||||
msgstr "Vaizdas"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Profilių rinkinys"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -7122,9 +7122,6 @@ msgstr "Toon een omtrek rond het geselecteerde object in de 3D-scène."
|
||||
msgid "Preferences"
|
||||
msgstr "Voorkeuren"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -7133,6 +7130,9 @@ msgstr "Bewerken"
|
||||
msgid "View"
|
||||
msgstr "Weergave"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Voorinstellingenbundel"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6689,9 +6689,6 @@ msgstr "Przełącza wyświetlanie konturu wokół zaznaczonego obiektu w scenie
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencje"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6700,6 +6697,9 @@ msgstr "Edycja"
|
||||
msgid "View"
|
||||
msgstr "Widok"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Pakiet profili"
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-07-26 11:14-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
@@ -6363,9 +6363,6 @@ msgstr "Mostrar contorno ao redor do objeto selecionado na cena 3D."
|
||||
msgid "Preferences"
|
||||
msgstr "Preferências"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
@@ -6373,6 +6370,9 @@ msgstr "Editar"
|
||||
msgid "View"
|
||||
msgstr "Visualizar"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Pacote de Predefinições"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer V2.5.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-02-25 13:38+0300\n"
|
||||
"Last-Translator: Felix14_v2\n"
|
||||
"Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg <andylg@yandex.ru>\n"
|
||||
@@ -6597,9 +6597,6 @@ msgstr "Отображение контура вокруг выбранных м
|
||||
msgid "Preferences"
|
||||
msgstr "Настройки"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr "Правка"
|
||||
@@ -6607,6 +6604,9 @@ msgstr "Правка"
|
||||
msgid "View"
|
||||
msgstr "Вид"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Пакет профилей"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -7205,9 +7205,6 @@ msgstr "Visa en kontur runt det markerade objektet i 3D-scenen."
|
||||
msgid "Preferences"
|
||||
msgstr "Inställningar"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -7216,6 +7213,9 @@ msgstr "Redigera"
|
||||
msgid "View"
|
||||
msgstr "Vy"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Förinställningspaket"
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-06-19 13:40+0700\n"
|
||||
"Last-Translator: Icezaza\n"
|
||||
"Language-Team: Thai\n"
|
||||
@@ -6520,9 +6520,6 @@ msgstr "แสดงเค้าร่างรอบๆ วัตถุที
|
||||
msgid "Preferences"
|
||||
msgstr "การตั้งค่า"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6531,6 +6528,9 @@ msgstr "แก้ไข"
|
||||
msgid "View"
|
||||
msgstr "มุมมอง"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "ชุดที่ตั้งไว้ล่วงหน้า"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-08-21 23:18+0300\n"
|
||||
"Last-Translator: GlauTech\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6588,9 +6588,6 @@ msgstr "3D sahnede seçilen nesnenin etrafındaki ana hatları göster."
|
||||
msgid "Preferences"
|
||||
msgstr "Tercihler"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6599,6 +6596,9 @@ msgstr "Düzen"
|
||||
msgid "View"
|
||||
msgstr "Görünüm"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Ön ayar paketi"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: orcaslicerua\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-07-17 16:25+0300\n"
|
||||
"Last-Translator: Andrij Mizyk <andm1zyk@proton.me>\n"
|
||||
"Language-Team: Ukrainian\n"
|
||||
@@ -6557,9 +6557,6 @@ msgstr "Показувати контур навколо виділеного о
|
||||
msgid "Preferences"
|
||||
msgstr "Налаштування"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6568,6 +6565,9 @@ msgstr "Редагування"
|
||||
msgid "View"
|
||||
msgstr "Вигляд"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Набір пресетів"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: hainguyen.ts13@gmail.com\n"
|
||||
@@ -6907,9 +6907,6 @@ msgstr "Hiện đường viền xung quanh vật thể đã chọn trong cảnh
|
||||
msgid "Preferences"
|
||||
msgstr "Tùy chọn"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6918,6 +6915,9 @@ msgstr "Chỉnh sửa"
|
||||
msgid "View"
|
||||
msgstr "Xem"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgid "Preset Bundle"
|
||||
msgstr "Gói cài đặt sẵn"
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Slic3rPE\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
|
||||
"Last-Translator: Handle <mail@bysb.net>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6375,9 +6375,6 @@ msgstr "在3D场景中显示选中对象的轮廓"
|
||||
msgid "Preferences"
|
||||
msgstr "偏好设置"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6386,6 +6383,9 @@ msgstr "编辑"
|
||||
msgid "View"
|
||||
msgstr "视图"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "预设包"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-22 12:39+0800\n"
|
||||
"POT-Creation-Date: 2026-09-22 17:02+0800\n"
|
||||
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
|
||||
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -6505,9 +6505,6 @@ msgstr "在 3D 場景中顯示選定物件的輪廓"
|
||||
msgid "Preferences"
|
||||
msgstr "偏好設定"
|
||||
|
||||
msgid "Open speed dial"
|
||||
msgstr ""
|
||||
|
||||
# AI Translated
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
@@ -6516,6 +6513,9 @@ msgstr "編輯"
|
||||
msgid "View"
|
||||
msgstr "視角"
|
||||
|
||||
msgid "Open Speed Dial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Preset Bundle"
|
||||
msgstr "設定檔組"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Eryone",
|
||||
"version": "02.04.00.05",
|
||||
"version": "02.04.00.06",
|
||||
"force_update": "0",
|
||||
"description": "Eryone configurations",
|
||||
"machine_model_list": [
|
||||
@@ -432,10 +432,18 @@
|
||||
"name": "Eryone ABS",
|
||||
"sub_path": "filament/Eryone ABS.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone ABS+-HS @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone ABS+-HS @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone ABS-CF",
|
||||
"sub_path": "filament/Eryone ABS-CF.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone ABS-GF @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone ABS-GF @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone ASA",
|
||||
"sub_path": "filament/Eryone ASA.json"
|
||||
@@ -444,6 +452,10 @@
|
||||
"name": "Eryone ASA-CF",
|
||||
"sub_path": "filament/Eryone ASA-CF.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone ASA-HS @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone ASA-HS @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PA",
|
||||
"sub_path": "filament/Eryone PA.json"
|
||||
@@ -460,18 +472,50 @@
|
||||
"name": "Eryone PETG",
|
||||
"sub_path": "filament/Eryone PETG.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG HS @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PETG HS @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG-CF",
|
||||
"sub_path": "filament/Eryone PETG-CF.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG-GF @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PETG-GF @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG-Lite @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PETG-Lite @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG-Matte @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PETG-Matte @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PETG-Translucent @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PETG-Translucent @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PLA",
|
||||
"sub_path": "filament/Eryone PLA.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PLA+HS @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PLA+HS @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PLA-CF",
|
||||
"sub_path": "filament/Eryone PLA-CF.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PLA-Matte @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PLA-Matte @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PLA-Matte HS @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone PLA-Matte HS @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone PP",
|
||||
"sub_path": "filament/Eryone PP.json"
|
||||
@@ -488,6 +532,14 @@
|
||||
"name": "Eryone TPU",
|
||||
"sub_path": "filament/Eryone TPU.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone petg-Galaxy @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone petg-Galaxy @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle",
|
||||
"sub_path": "filament/Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "fdm_filament_pla",
|
||||
"sub_path": "filament/fdm_filament_pla.json"
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone ABS+-HS @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "aUH1I90BFXa0C84r",
|
||||
"filament_id": "OFRgjTRp",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone ABS+-HS @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"20"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.96"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"25"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"ABS"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"90"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"90"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"255"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"255"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone ABS-GF @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "WnsZC7HYi5Z1MOcn",
|
||||
"filament_id": "OFenMm2Y",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone ABS-GF @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"20"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.96"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"18"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"ABS"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"90"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"90"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"265"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"265"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone ASA-HS @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "xw8zqUsFb2WVaSo1",
|
||||
"filament_id": "OFIzY5sP",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone ASA-HS @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"20"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"20"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"ASA"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"90"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"90"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"260"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"260"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PETG HS @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "GtPiiNgHAnxrR9Tj",
|
||||
"filament_id": "OFtqfvcE",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG HS @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.97"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"15"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"70"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"70"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"240"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"240"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -40,7 +40,7 @@
|
||||
"14"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG"
|
||||
"Eryone PETG-CF"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG-CF"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PETG-GF @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "S1FBfw93PzYJMhCa",
|
||||
"filament_id": "OFbzOkXX",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG-GF @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.96"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"13"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"70"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"70"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"250"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"250"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PETG-Lite @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "CWHhUswq3j9XHAuC",
|
||||
"filament_id": "OFyWb8AA",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG-Lite @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.9796"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"13"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"70"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"70"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"245"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"245"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PETG-Matte @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "pzceBG5k2u3X9TLO",
|
||||
"filament_id": "OFSvr7Aj",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG-Matte @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"22"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"80"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"80"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"250"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"250"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PETG-Translucent @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "jN64L5SUnQB5dG1x",
|
||||
"filament_id": "OFY2E8cd",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PETG-Translucent @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.99"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"24"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"70"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"70"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"215"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"215"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PLA+HS @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "AfUEns6VhCXsj9Ft",
|
||||
"filament_id": "OFeRoHy3",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PLA+HS @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"80"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.99"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"18"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"55"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"55"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"210"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"210"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PLA-Matte @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "Ho1nQYsweqTTte0g",
|
||||
"filament_id": "OFFMWFWL",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PLA-Matte @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"80"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.99"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"21"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"55"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"55"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"215"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"215"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone PLA-Matte HS @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "8W0yhuRu7OBJkSOS",
|
||||
"filament_id": "OF9mNFSM",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone PLA-Matte HS @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"80"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"1.1"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"28"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"55"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"55"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"225"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"225"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone petg-Galaxy @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "R4BPYs8aAc9DFf0n",
|
||||
"filament_id": "OFWDDu8u",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone petg-Galaxy @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"close_fan_the_first_x_layers": [
|
||||
"3"
|
||||
],
|
||||
"fan_max_speed": [
|
||||
"50"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"30"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.96"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"21"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
"full_fan_speed_layer": [
|
||||
"2"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"70"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"70"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"245"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"245"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"name": "Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle",
|
||||
"inherits": "Eryone Standard PLA",
|
||||
"from": "system",
|
||||
"setting_id": "jCbto64oaAKrDaN0",
|
||||
"filament_id": "OF99Cc22",
|
||||
"instantiation": "true",
|
||||
"compatible_printers": [
|
||||
"Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"Eryone pla-Ultra Silk @Thinker X400 0.4 nozzle"
|
||||
],
|
||||
"fan_min_speed": [
|
||||
"80"
|
||||
],
|
||||
"filament_end_gcode": [
|
||||
"; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.97"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"15"
|
||||
],
|
||||
"filament_start_gcode": [
|
||||
"; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1"
|
||||
],
|
||||
"hot_plate_temp": [
|
||||
"55"
|
||||
],
|
||||
"hot_plate_temp_initial_layer": [
|
||||
"55"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"230"
|
||||
],
|
||||
"nozzle_temperature_initial_layer": [
|
||||
"230"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
"slow_down_min_speed": [
|
||||
"15"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "WonderMaker",
|
||||
"url": "",
|
||||
"version": "02.04.00.03",
|
||||
"version": "02.04.00.04",
|
||||
"force_update": "0",
|
||||
"description": "WonderMaker configurations",
|
||||
"machine_model_list": [
|
||||
@@ -432,12 +432,8 @@
|
||||
"sub_path": "machine/WonderMaker ZR 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra S 0.4 nozzle.json"
|
||||
"name": "fdm_ultra_common",
|
||||
"sub_path": "machine/fdm_ultra_common.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR 0.2 nozzle",
|
||||
@@ -455,6 +451,10 @@
|
||||
"name": "WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra 0.2 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra 0.6 nozzle.json"
|
||||
@@ -467,6 +467,10 @@
|
||||
"name": "WonderMaker ZR Ultra S 0.2 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra S 0.2 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra S 0.4 nozzle.json"
|
||||
},
|
||||
{
|
||||
"name": "WonderMaker ZR Ultra S 0.6 nozzle",
|
||||
"sub_path": "machine/WonderMaker ZR Ultra S 0.6 nozzle.json"
|
||||
|
||||
Executable → Regular
+8
-7
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"inherits": "fdm_ultra_common",
|
||||
"from": "system",
|
||||
"setting_id": "AX42zNj8YsJ94ilv",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.2",
|
||||
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"default_bed_type": "4",
|
||||
"max_layer_height": [
|
||||
"0.14"
|
||||
],
|
||||
"nozzle_diameter": [
|
||||
"0.2",
|
||||
"0.2",
|
||||
"0.2",
|
||||
"0.2"
|
||||
],
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.2",
|
||||
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"max_layer_height": [
|
||||
"0.14"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.04"
|
||||
],
|
||||
|
||||
Executable → Regular
+1
-49
@@ -1,65 +1,17 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"inherits": "fdm_klipper_common",
|
||||
"inherits": "fdm_ultra_common",
|
||||
"from": "system",
|
||||
"setting_id": "xJBdCljSZVDINXnP",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
|
||||
"default_bed_type": "4",
|
||||
"default_filament_profile": [
|
||||
"WonderMaker PLA Basic"
|
||||
],
|
||||
"single_extruder_multi_material": "0",
|
||||
"nozzle_diameter": [
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4"
|
||||
],
|
||||
"printable_area": [
|
||||
"0x0",
|
||||
"300x0",
|
||||
"300x270",
|
||||
"0x270"
|
||||
],
|
||||
"bed_exclude_area": [],
|
||||
"printable_height": "290",
|
||||
"extruder_clearance_radius": "134",
|
||||
"bed_mesh_min": [
|
||||
"10",
|
||||
"10"
|
||||
],
|
||||
"bed_mesh_max": [
|
||||
"290",
|
||||
"260"
|
||||
],
|
||||
"bed_mesh_probe_distance": [
|
||||
"50",
|
||||
"50"
|
||||
],
|
||||
"support_air_filtration": "0",
|
||||
"support_chamber_temp_control": "0",
|
||||
"machine_tool_change_time": "10",
|
||||
"machine_load_filament_time": "0",
|
||||
"machine_unload_filament_time": "0",
|
||||
"retract_lift_below": [
|
||||
"279",
|
||||
"279",
|
||||
"279",
|
||||
"279"
|
||||
],
|
||||
"enable_long_retraction_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"long_retractions_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
]
|
||||
}
|
||||
|
||||
Executable → Regular
+8
-7
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"inherits": "fdm_ultra_common",
|
||||
"from": "system",
|
||||
"setting_id": "6OWxZLFn3RD54QfX",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.6",
|
||||
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"default_bed_type": "4",
|
||||
"max_layer_height": [
|
||||
"0.42"
|
||||
],
|
||||
"nozzle_diameter": [
|
||||
"0.6",
|
||||
"0.6",
|
||||
"0.6",
|
||||
"0.6"
|
||||
],
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.6",
|
||||
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"max_layer_height": [
|
||||
"0.42"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.12"
|
||||
],
|
||||
|
||||
Executable → Regular
+8
-7
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"inherits": "fdm_ultra_common",
|
||||
"from": "system",
|
||||
"setting_id": "SY9snlsMkurhEYWP",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.8",
|
||||
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"default_bed_type": "4",
|
||||
"max_layer_height": [
|
||||
"0.56"
|
||||
],
|
||||
"nozzle_diameter": [
|
||||
"0.8",
|
||||
"0.8",
|
||||
"0.8",
|
||||
"0.8"
|
||||
],
|
||||
"printer_model": "WonderMaker ZR Ultra",
|
||||
"printer_variant": "0.8",
|
||||
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"max_layer_height": [
|
||||
"0.56"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.16"
|
||||
],
|
||||
|
||||
Executable → Regular
+5
-15
@@ -1,29 +1,19 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra S 0.2 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"from": "system",
|
||||
"setting_id": "ZNAx3f7tX3DatiK1",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra S",
|
||||
"nozzle_diameter": [
|
||||
"0.2",
|
||||
"0.2",
|
||||
"0.2",
|
||||
"0.2"
|
||||
],
|
||||
"printer_model": "WonderMaker ZR Ultra S",
|
||||
"printer_variant": "0.2",
|
||||
"default_print_profile": "0.10mm Standard @WonderMaker ZR Ultra 0.2 nozzle",
|
||||
"max_layer_height": [
|
||||
"0.14"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.04"
|
||||
],
|
||||
"retraction_length": [
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4"
|
||||
]
|
||||
"printer_variant": "0.2",
|
||||
"support_air_filtration": "1",
|
||||
"support_chamber_temp_control": "1"
|
||||
}
|
||||
|
||||
Executable → Regular
+3
-50
@@ -1,65 +1,18 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"inherits": "fdm_klipper_common",
|
||||
"inherits": "WonderMaker ZR Ultra 0.4 nozzle",
|
||||
"from": "system",
|
||||
"setting_id": "8xoZ6vYv9ws0J97u",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra S",
|
||||
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
|
||||
"default_bed_type": "4",
|
||||
"default_filament_profile": [
|
||||
"WonderMaker PLA Basic"
|
||||
],
|
||||
"single_extruder_multi_material": "0",
|
||||
"nozzle_diameter": [
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4"
|
||||
],
|
||||
"printable_area": [
|
||||
"0x0",
|
||||
"300x0",
|
||||
"300x270",
|
||||
"0x270"
|
||||
],
|
||||
"bed_exclude_area": [],
|
||||
"printable_height": "290",
|
||||
"extruder_clearance_radius": "134",
|
||||
"bed_mesh_min": [
|
||||
"10",
|
||||
"10"
|
||||
],
|
||||
"bed_mesh_max": [
|
||||
"290",
|
||||
"260"
|
||||
],
|
||||
"bed_mesh_probe_distance": [
|
||||
"50",
|
||||
"50"
|
||||
],
|
||||
"default_print_profile": "0.20mm Standard @WonderMaker ZR Ultra",
|
||||
"support_air_filtration": "1",
|
||||
"support_chamber_temp_control": "1",
|
||||
"machine_tool_change_time": "10",
|
||||
"machine_load_filament_time": "0",
|
||||
"machine_unload_filament_time": "0",
|
||||
"retract_lift_below": [
|
||||
"279",
|
||||
"279",
|
||||
"279",
|
||||
"279"
|
||||
],
|
||||
"enable_long_retraction_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"long_retractions_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
]
|
||||
"support_chamber_temp_control": "1"
|
||||
}
|
||||
|
||||
Executable → Regular
+8
-21
@@ -1,32 +1,19 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra S 0.6 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"from": "system",
|
||||
"setting_id": "xuJnOPTmSW1BMo6p",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra S",
|
||||
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"printer_variant": "0.6",
|
||||
"nozzle_diameter": [
|
||||
"0.6",
|
||||
"0.6",
|
||||
"0.6",
|
||||
"0.6"
|
||||
],
|
||||
"max_layer_height": [
|
||||
"0.42"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.12"
|
||||
],
|
||||
"retraction_length": [
|
||||
"1.4",
|
||||
"1.4",
|
||||
"1.4",
|
||||
"1.4"
|
||||
],
|
||||
"retraction_minimum_travel": [
|
||||
"3",
|
||||
"3",
|
||||
"3",
|
||||
"3"
|
||||
]
|
||||
"default_print_profile": "0.30mm Standard @WonderMaker ZR Ultra 0.6 nozzle",
|
||||
"printer_variant": "0.6",
|
||||
"support_air_filtration": "1",
|
||||
"support_chamber_temp_control": "1"
|
||||
}
|
||||
|
||||
Executable → Regular
+8
-21
@@ -1,32 +1,19 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "WonderMaker ZR Ultra S 0.8 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra S 0.4 nozzle",
|
||||
"inherits": "WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"from": "system",
|
||||
"setting_id": "0BPLKMspArilfkGT",
|
||||
"instantiation": "true",
|
||||
"printer_model": "WonderMaker ZR Ultra S",
|
||||
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"printer_variant": "0.8",
|
||||
"nozzle_diameter": [
|
||||
"0.8",
|
||||
"0.8",
|
||||
"0.8",
|
||||
"0.8"
|
||||
],
|
||||
"max_layer_height": [
|
||||
"0.56"
|
||||
],
|
||||
"min_layer_height": [
|
||||
"0.16"
|
||||
],
|
||||
"retract_length_toolchange": [
|
||||
"3",
|
||||
"3",
|
||||
"3",
|
||||
"3"
|
||||
],
|
||||
"retraction_length": [
|
||||
"3",
|
||||
"3",
|
||||
"3",
|
||||
"3"
|
||||
]
|
||||
"default_print_profile": "0.40mm Standard @WonderMaker ZR Ultra 0.8 nozzle",
|
||||
"printer_variant": "0.8",
|
||||
"support_air_filtration": "1",
|
||||
"support_chamber_temp_control": "1"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"type": "machine",
|
||||
"name": "fdm_ultra_common",
|
||||
"inherits": "fdm_klipper_common",
|
||||
"from": "system",
|
||||
"instantiation": "false",
|
||||
"default_bed_type": "4",
|
||||
"default_filament_profile": [
|
||||
"WonderMaker PLA Basic"
|
||||
],
|
||||
"single_extruder_multi_material": "0",
|
||||
"enable_filament_mapping": "1",
|
||||
"filament_swap_gcode": "M117 Swap filament for tool {next_extruder}\nPAUSE",
|
||||
"nozzle_diameter": [
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4",
|
||||
"0.4"
|
||||
],
|
||||
"printable_area": [
|
||||
"0x0",
|
||||
"300x0",
|
||||
"300x270",
|
||||
"0x270"
|
||||
],
|
||||
"bed_exclude_area": [],
|
||||
"printable_height": "290",
|
||||
"extruder_clearance_radius": "134",
|
||||
"bed_mesh_min": [
|
||||
"10",
|
||||
"10"
|
||||
],
|
||||
"bed_mesh_max": [
|
||||
"290",
|
||||
"260"
|
||||
],
|
||||
"bed_mesh_probe_distance": [
|
||||
"50",
|
||||
"50"
|
||||
],
|
||||
"support_air_filtration": "0",
|
||||
"support_chamber_temp_control": "0",
|
||||
"machine_tool_change_time": "10",
|
||||
"machine_load_filament_time": "0",
|
||||
"machine_unload_filament_time": "0",
|
||||
"retract_lift_below": [
|
||||
"279",
|
||||
"279",
|
||||
"279",
|
||||
"279"
|
||||
],
|
||||
"enable_long_retraction_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"long_retractions_when_cut": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0"
|
||||
]
|
||||
}
|
||||
@@ -575,7 +575,7 @@ function CapabilityCanRun(plugin, capability) {
|
||||
}
|
||||
|
||||
function IsPluginChecked(plugin) {
|
||||
return GetStatus(plugin) === "Activated";
|
||||
return plugin.is_loaded;
|
||||
}
|
||||
|
||||
function HasMixedCapabilityState(plugin) {
|
||||
@@ -1347,6 +1347,8 @@ function StatusDescription(plugin) {
|
||||
return "This plugin is still loading.";
|
||||
case "Error":
|
||||
return "This plugin is blocked until its error is fixed.";
|
||||
case "RuntimeError":
|
||||
return "This plugin is loaded but a capability reported an error.";
|
||||
case "Inactive":
|
||||
default:
|
||||
return "This plugin is inactive. Activate it to install or load it.";
|
||||
|
||||
@@ -424,6 +424,11 @@ body.pane-resizing {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-cell.status-runtimeerror {
|
||||
color: var(--plugin-status-warn);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-cell.status-loading {
|
||||
color: var(--plugin-status-warn);
|
||||
font-weight: 600;
|
||||
@@ -680,6 +685,11 @@ body.pane-resizing {
|
||||
color: var(--plugin-status-danger);
|
||||
}
|
||||
|
||||
.detail-status-chip.status-runtimeerror {
|
||||
background: var(--plugin-status-warn-bg);
|
||||
color: var(--plugin-status-warn);
|
||||
}
|
||||
|
||||
.detail-status-chip.status-loading {
|
||||
background: var(--plugin-status-warn-bg);
|
||||
color: var(--plugin-status-warn);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Bootstrap page for PluginWebDialog. The real plugin HTML is loaded via
|
||||
<!-- Bootstrap page for WebDialog. The real plugin HTML is loaded via
|
||||
wxWebView::SetPage once this page finishes loading; this file only exists
|
||||
to bring the webview up. -->
|
||||
<html>
|
||||
@@ -0,0 +1,146 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.12"
|
||||
#
|
||||
# [tool.orcaslicer.plugin]
|
||||
# name = "Dock Panel Demo"
|
||||
# description = "Opens a dockable panel beside the 3D view that lists the objects on the plate."
|
||||
# author = "OrcaSlicer"
|
||||
# version = "0.0.1"
|
||||
# ///
|
||||
"""Dock Panel Demo -- orca.host.ui.create_dock_panel().
|
||||
|
||||
Run it from the Plugins dialog. It opens an HTML panel docked on the right of the 3D view, in the
|
||||
same dock area as the sidebar. Drag its caption to dock it on another side (or float it, where the
|
||||
platform allows), hide it from the page and run the plugin again to bring it back, or close it with
|
||||
its close button or from the page.
|
||||
|
||||
page --orca.postMessage({command: 'refresh'})--> plugin.on_message()
|
||||
page --orca.postMessage({command: 'hide'})--> plugin.on_message() -> panel.hide()
|
||||
page --orca.close()--> panel closes, plugin.on_close()
|
||||
plugin --panel.post({command: 'objects', ...})--> page (orca.onMessage)
|
||||
"""
|
||||
import orca
|
||||
|
||||
PAGE = """
|
||||
<style>
|
||||
body { margin: 0; padding: 12px; font-size: 13px; }
|
||||
h3 { margin: 0 0 4px; font-size: 14px; }
|
||||
.note { margin: 0 0 12px; color: var(--orca-muted); font-size: 12px; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
|
||||
.actions button.quiet { background: transparent; color: var(--orca-fg); border-color: var(--orca-border); }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
td.count { text-align: right; font-variant-numeric: tabular-nums; }
|
||||
#status { margin-top: 10px; color: var(--orca-muted); font-size: 12px; }
|
||||
</style>
|
||||
|
||||
<h3>Objects on the plate</h3>
|
||||
<p class="note">Docked beside the 3D view. Drag the caption to move it.</p>
|
||||
|
||||
<div class="actions">
|
||||
<button type="button" id="refresh">Refresh</button>
|
||||
<button type="button" id="hide" class="quiet">Hide</button>
|
||||
<button type="button" id="close" class="quiet">Close</button>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Parts</th><th>Copies</th></tr></thead>
|
||||
<tbody id="rows"></tbody>
|
||||
</table>
|
||||
<p id="status">Waiting for the plugin...</p>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
function text(value) {
|
||||
var span = document.createElement("span");
|
||||
span.textContent = value;
|
||||
return span.innerHTML;
|
||||
}
|
||||
|
||||
function render(message) {
|
||||
var rows = document.getElementById("rows");
|
||||
var status = document.getElementById("status");
|
||||
if (message.error) {
|
||||
rows.innerHTML = "";
|
||||
status.textContent = message.error;
|
||||
return;
|
||||
}
|
||||
rows.innerHTML = message.objects.map(function (object) {
|
||||
return "<tr><td>" + text(object.name) + "</td><td class=\\"count\\">" + object.volumes +
|
||||
"</td><td class=\\"count\\">" + object.instances + "</td></tr>";
|
||||
}).join("");
|
||||
status.textContent = message.objects.length + " object(s), refreshed " + new Date().toLocaleTimeString();
|
||||
}
|
||||
|
||||
orca.onMessage(function (message) {
|
||||
if (message && message.command === "objects")
|
||||
render(message);
|
||||
});
|
||||
|
||||
document.getElementById("refresh").addEventListener("click", function () {
|
||||
orca.postMessage({ command: "refresh" });
|
||||
});
|
||||
document.getElementById("hide").addEventListener("click", function () {
|
||||
orca.postMessage({ command: "hide" });
|
||||
});
|
||||
document.getElementById("close").addEventListener("click", function () {
|
||||
orca.close();
|
||||
});
|
||||
|
||||
orca.postMessage({ command: "refresh" });
|
||||
})();
|
||||
</script>
|
||||
"""
|
||||
|
||||
|
||||
def plate_objects():
|
||||
try:
|
||||
model = orca.host.model()
|
||||
except RuntimeError as error:
|
||||
return {"command": "objects", "error": str(error)}
|
||||
return {
|
||||
"command": "objects",
|
||||
"objects": [
|
||||
{"name": obj.name or "(unnamed)", "volumes": obj.volume_count(), "instances": obj.instance_count()}
|
||||
for obj in model.objects()
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class DockPanelDemo(orca.script.ScriptPluginCapabilityBase):
|
||||
panel = None
|
||||
|
||||
def get_name(self):
|
||||
return "Dock Panel Demo"
|
||||
|
||||
def execute(self):
|
||||
# The capability instance lives as long as the plugin, so a second run finds the open panel.
|
||||
if self.panel is not None and self.panel.is_open():
|
||||
self.panel.show()
|
||||
return orca.ExecutionResult.success("Dock Panel Demo is already open.")
|
||||
self.panel = orca.host.ui.create_dock_panel(
|
||||
html=PAGE,
|
||||
title="Dock Panel Demo",
|
||||
width=320,
|
||||
height=480,
|
||||
on_message=self.on_message,
|
||||
on_close=self.on_close,
|
||||
dock="right",
|
||||
)
|
||||
return orca.ExecutionResult.success("Dock Panel Demo opened.")
|
||||
|
||||
# Called on the UI thread when the page posts.
|
||||
def on_message(self, message):
|
||||
command = (message or {}).get("command")
|
||||
if command == "refresh":
|
||||
self.panel.post(plate_objects())
|
||||
elif command == "hide":
|
||||
self.panel.hide()
|
||||
|
||||
def on_close(self):
|
||||
self.panel = None
|
||||
|
||||
|
||||
@orca.plugin
|
||||
class DockPanelDemoPlugin(orca.base):
|
||||
def register_capabilities(self):
|
||||
orca.register_capability(DockPanelDemo)
|
||||
@@ -331,6 +331,15 @@ modules:
|
||||
sha256: deedcabe339165214a3637df4c86a507aef0d793cf8774ff68735f4737e8ddbc
|
||||
dest: external-packages/FFMPEG
|
||||
|
||||
# libdatachannel v0.24.5
|
||||
# The Git checkout includes the submodules that are missing from the
|
||||
# GitHub source archive. DataChannel.cmake consumes it as SOURCE_DIR.
|
||||
- type: git
|
||||
url: https://github.com/paullouisageneau/libdatachannel.git
|
||||
tag: v0.24.5
|
||||
commit: 443f6934d9007eb7076ab7825ba330f355fcbead
|
||||
dest: external-packages/DataChannel
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Fallback archives for deps normally provided by the GNOME SDK.
|
||||
# These are only used if find_package() fails to locate them.
|
||||
|
||||
@@ -122,17 +122,19 @@ Vec2d printable_area_center(const DynamicPrintConfig &cfg)
|
||||
|
||||
// Put the prime tower where the GUI and CLI would before slicing. The config default (x 15, y 220)
|
||||
// lies off any bed shallower than the tower, and generation rejects an off-plate tower instead of
|
||||
// exporting it. Beside the centred cube, clear of the edge exclusion strips some beds carry, then
|
||||
// pulled inside the printable outline by the tower's own estimated footprint, with a few mm of
|
||||
// clearance so the conflict checker never sees the two touch.
|
||||
void place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er)
|
||||
// exporting it. Beside the cube at the bed centre, clear of the edge exclusion strips some beds
|
||||
// carry, with a few mm of clearance so the conflict checker never sees the two touch. The cube and
|
||||
// the tower's estimated footprint are then pulled inside the printable outline as one rigid pair:
|
||||
// moving the tower alone would push it back onto the cube on a narrow bed. Returns that move for
|
||||
// the cube.
|
||||
Vec2d place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er)
|
||||
{
|
||||
const auto *area = cfg.option<ConfigOptionPoints>("printable_area");
|
||||
if (area == nullptr || area->values.size() < 3)
|
||||
return;
|
||||
return Vec2d::Zero();
|
||||
const WipeTowerFootprint footprint = estimate_wipe_tower_footprint(cfg, resolve_wipe_tower_type(cfg), {0, 1}, cfg.opt_float("layer_height"), 10.);
|
||||
if (footprint.depth < EPSILON)
|
||||
return;
|
||||
return Vec2d::Zero();
|
||||
const double margin = WIPE_TOWER_MARGIN + footprint.brim_width;
|
||||
// The position is the tower's own origin; a rotated tower extends from it in another
|
||||
// direction, so place the rotated box's extents rather than the origin.
|
||||
@@ -143,13 +145,22 @@ void place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er)
|
||||
const Vec2d size = unscale(local.max) - lo;
|
||||
Vec2d pos(center.x() + 5. + margin + 5. - lo.x(), center.y() - size.y() / 2. - lo.y());
|
||||
box.translate(Point::new_scale(pos.x(), pos.y()));
|
||||
const Vec2f move = WipeTower::move_box_inside_polygon(get_extents(box), Polygons{Polygon::new_scale(area->values)}, scaled<coord_t>(margin));
|
||||
pos += move.cast<double>();
|
||||
// A bed too small for the pair keeps the cube at its centre and places the tower alone.
|
||||
const Polygons bed{Polygon::new_scale(area->values)};
|
||||
const BoundingBox tower = get_extents(box);
|
||||
BoundingBox pair = tower;
|
||||
pair.merge(Point::new_scale(center.x() - 5., center.y() - 5.));
|
||||
pair.merge(Point::new_scale(center.x() + 5., center.y() + 5.));
|
||||
const Point room = get_extents(bed).size() - Point::new_scale(2. * margin, 2. * margin);
|
||||
const bool rigid = pair.size().x() < room.x() && pair.size().y() < room.y();
|
||||
const Vec2d move = WipeTower::move_box_inside_polygon(rigid ? pair : tower, bed, scaled<coord_t>(margin)).cast<double>();
|
||||
pos += move;
|
||||
cfg.option<ConfigOptionFloats>("wipe_tower_x", true)->values = {pos.x()};
|
||||
cfg.option<ConfigOptionFloats>("wipe_tower_y", true)->values = {pos.y()};
|
||||
return rigid ? move : Vec2d::Zero();
|
||||
}
|
||||
|
||||
// Slice one centered cube that switches from filament 1 to filament 2 partway up, so exactly one
|
||||
// Slice one cube that switches from filament 1 to filament 2 partway up, so exactly one
|
||||
// filament change fires, then export. The change drives the printer's own change_filament_gcode: on a
|
||||
// single-nozzle machine it rides the AMS prime tower (append_tcr), on a multi-nozzle machine it routes
|
||||
// through the nozzle swap (set_extruder / append_tcr2) - the engine picks the path from the printer's
|
||||
@@ -157,10 +168,10 @@ void place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er)
|
||||
// Slic3r::PlaceholderParserError from export.
|
||||
std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl)
|
||||
{
|
||||
const Vec2d center = printable_area_center(cfg);
|
||||
place_wipe_tower(cfg, center);
|
||||
const Vec2d center = printable_area_center(cfg);
|
||||
const Vec2d cube_min = center - Vec2d(5., 5.) + place_wipe_tower(cfg, center);
|
||||
TriangleMesh m = make_cube(10, 10, 10);
|
||||
m.translate(float(center.x() - 5.), float(center.y() - 5.), 0.f);
|
||||
m.translate(static_cast<float>(cube_min.x()), static_cast<float>(cube_min.y()), 0.f);
|
||||
|
||||
Model model;
|
||||
Print print;
|
||||
|
||||
+5
-46
@@ -8,7 +8,6 @@
|
||||
#include "I18N.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "LifecycleEvents.hpp"
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "EdgeGrid.hpp"
|
||||
#include "Geometry/ConvexHull.hpp"
|
||||
@@ -2477,14 +2476,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
m_writer.set_is_bbl_machine(print->is_BBL_printer());
|
||||
print->set_started(psGCodeExport);
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(print->model().id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = path;
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportStarted, ctx);
|
||||
}
|
||||
|
||||
// check if any custom gcode contains keywords used by the gcode processor to
|
||||
// produce time estimation and gcode toolpaths
|
||||
std::vector<std::pair<std::string, std::string>> validation_res = DoExport::validate_custom_gcode(*print);
|
||||
@@ -2520,22 +2511,12 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
m_processor.set_print(print);
|
||||
GCodeOutputStream file(boost::nowide::fopen(path_tmp.c_str(), "wb"), m_processor);
|
||||
if (! file.is_open()) {
|
||||
std::string err_msg = std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n";
|
||||
BOOST_LOG_TRIVIAL(error) << err_msg << std::endl;
|
||||
BOOST_LOG_TRIVIAL(error) << std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n" << std::endl;
|
||||
if (!fs::exists(folder)) {
|
||||
//fs::create_directory(folder);
|
||||
std::string add_err_msg = "the parent path " + folder.string() +" is not there!!!";
|
||||
BOOST_LOG_TRIVIAL(error) << add_err_msg << std::endl;
|
||||
err_msg += add_err_msg;
|
||||
BOOST_LOG_TRIVIAL(error) << "the parent path " + folder.string() +" is not there!!!" << std::endl;
|
||||
}
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(print->model().id().id);
|
||||
ctx.code = LifecycleEvtCode::Error;
|
||||
ctx.msg = std::string(path) + "\n" + err_msg;
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
throw Slic3r::RuntimeError(err_msg);
|
||||
throw Slic3r::RuntimeError(std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -2546,18 +2527,11 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
boost::nowide::remove(path_tmp.c_str());
|
||||
throw Slic3r::RuntimeError(std::string("G-code export to ") + path + " failed\nIs the disk full?\n");
|
||||
}
|
||||
} catch (std::exception &ex) {
|
||||
} catch (std::exception & /* ex */) {
|
||||
// Rethrow on any exception. std::runtime_exception and CanceledException are expected to be thrown.
|
||||
// Close and remove the file.
|
||||
file.close();
|
||||
boost::nowide::remove(path_tmp.c_str());
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(print->model().id().id);
|
||||
ctx.code = LifecycleEvtCode::Error;
|
||||
ctx.msg = std::string(path) + "\n" + ex.what();
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
file.close();
|
||||
@@ -2663,13 +2637,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
|
||||
std::error_code ret = rename_file(path_tmp, path);
|
||||
if (ret) {
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(print->model().id().id);
|
||||
ctx.code = LifecycleEvtCode::Error;
|
||||
ctx.msg = std::string(path) + "\nFailed to rename the output G-code file: " + ret.message();
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
throw Slic3r::RuntimeError(
|
||||
std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + path + '\n' + "error code " + ret.message() + '\n' +
|
||||
"Is " + path_tmp + " locked?" + '\n');
|
||||
@@ -2680,15 +2647,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Exporting G-code finished" << log_memory_info();
|
||||
print->set_done(psGCodeExport);
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(print->model().id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = path;
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
|
||||
|
||||
// Orca: label_object_enabled reflects whether objects are labeled in the g-code (EXCLUDE_OBJECT /
|
||||
// M486), which is driven by exclude_object for every printer
|
||||
if(result != nullptr)
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// LifecycleEvents.hpp
|
||||
// --------------------
|
||||
// Application lifecycle events (project, slicing, plate editing, preset, printer connection, and
|
||||
// job activity) that other subsystems -- chiefly the plugin layer above libslic3r -- may want to
|
||||
// observe. Lives in libslic3r rather than the plugin layer because some events fire from inside
|
||||
// the slicing engine itself; see fire_lifecycle_event() below.
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
enum class LifecycleEvent {
|
||||
// Project (3mf)
|
||||
NewProject,
|
||||
ProjectOpened,
|
||||
ProjectBeforeSave,
|
||||
ProjectAfterSave,
|
||||
ProjectClosed,
|
||||
ProjectDirtyChanged,
|
||||
|
||||
// Slicing pipeline
|
||||
SliceStarted,
|
||||
SliceGeometryFinished,
|
||||
GCodeExportStarted,
|
||||
GCodeExportFinished,
|
||||
SlicingJobComplete,
|
||||
|
||||
// Plate/model editing
|
||||
ObjectAdded,
|
||||
ObjectDeleted,
|
||||
ObjectTransformed,
|
||||
ObjectChanged,
|
||||
ObjectRenamed,
|
||||
PlateCreated,
|
||||
PlateDeleted,
|
||||
PlateSelected,
|
||||
PlateRenamed,
|
||||
|
||||
// Preset
|
||||
PresetSelected,
|
||||
PresetSaved,
|
||||
|
||||
// Printer/device
|
||||
PrintStateChanged,
|
||||
DeviceOnlineChanged,
|
||||
DeviceDiscovered,
|
||||
DeviceSelected,
|
||||
DeviceConnected,
|
||||
DeviceDisconnected,
|
||||
UploadStarted,
|
||||
UploadFinished,
|
||||
|
||||
// Print/send jobs
|
||||
PrintJobStarted,
|
||||
PrintJobFinished,
|
||||
SendJobStarted,
|
||||
SendJobFinished,
|
||||
};
|
||||
|
||||
// Scoped so callers must qualify (LifecycleEvtCode::Error, not ERROR) -- ERROR/OK collide with
|
||||
// Windows macros (wingdi.h) as unqualified names.
|
||||
enum class LifecycleEvtCode { Ok, Error, Warn };
|
||||
|
||||
struct LifecycleEventContext
|
||||
{
|
||||
// The primary subject identifier for the event. This is event-specific (for example, a
|
||||
// project/output path, preset name, device id, or object name), must not contain status or
|
||||
// prose, and may be empty when the event has no single subject.
|
||||
std::string name;
|
||||
|
||||
// Outcome of the operation represented by the event. For state-change and start events,
|
||||
// Ok means that the event occurred; it does not imply that a future operation succeeded.
|
||||
LifecycleEvtCode code = LifecycleEvtCode::Ok;
|
||||
|
||||
// Optional human-readable detail or diagnostic text. It is not a stable parsing contract;
|
||||
// machine-readable data should be represented by a dedicated field or event instead.
|
||||
std::string msg;
|
||||
|
||||
// Stable subject/object identifier, when the source model provides one.
|
||||
std::string id;
|
||||
|
||||
// Previous value for rename and other before/after events.
|
||||
std::string previous_name;
|
||||
|
||||
// Device identifier for printer and job events.
|
||||
std::string device_id;
|
||||
|
||||
// Job identifier when the originating queue/task provides one.
|
||||
std::string job_id;
|
||||
|
||||
// Source subsystem or operation detail, suitable for filtering but not guaranteed to be
|
||||
// exhaustive across versions.
|
||||
std::string source;
|
||||
|
||||
// Plate, object, or volume index when the source uses an index rather than a stable id.
|
||||
int index = -1;
|
||||
|
||||
// Aggregate project dirty state for ProjectDirtyChanged.
|
||||
bool dirty = false;
|
||||
};
|
||||
|
||||
inline std::string lifecycle_event_to_string(LifecycleEvent event)
|
||||
{
|
||||
switch (event) {
|
||||
case LifecycleEvent::NewProject: return "NewProject";
|
||||
case LifecycleEvent::ProjectOpened: return "ProjectOpened";
|
||||
case LifecycleEvent::ProjectBeforeSave: return "ProjectBeforeSave";
|
||||
case LifecycleEvent::ProjectAfterSave: return "ProjectAfterSave";
|
||||
case LifecycleEvent::ProjectClosed: return "ProjectClosed";
|
||||
case LifecycleEvent::ProjectDirtyChanged: return "ProjectDirtyChanged";
|
||||
|
||||
case LifecycleEvent::SliceStarted: return "SliceStarted";
|
||||
case LifecycleEvent::SliceGeometryFinished: return "SliceGeometryFinished";
|
||||
case LifecycleEvent::GCodeExportStarted: return "GCodeExportStarted";
|
||||
case LifecycleEvent::GCodeExportFinished: return "GCodeExportFinished";
|
||||
case LifecycleEvent::SlicingJobComplete: return "SlicingJobComplete";
|
||||
|
||||
case LifecycleEvent::ObjectAdded: return "ObjectAdded";
|
||||
case LifecycleEvent::ObjectDeleted: return "ObjectDeleted";
|
||||
case LifecycleEvent::ObjectTransformed: return "ObjectTransformed";
|
||||
case LifecycleEvent::ObjectChanged: return "ObjectChanged";
|
||||
case LifecycleEvent::ObjectRenamed: return "ObjectRenamed";
|
||||
case LifecycleEvent::PlateCreated: return "PlateCreated";
|
||||
case LifecycleEvent::PlateDeleted: return "PlateDeleted";
|
||||
case LifecycleEvent::PlateSelected: return "PlateSelected";
|
||||
case LifecycleEvent::PlateRenamed: return "PlateRenamed";
|
||||
|
||||
case LifecycleEvent::PresetSelected: return "PresetSelected";
|
||||
case LifecycleEvent::PresetSaved: return "PresetSaved";
|
||||
case LifecycleEvent::PrintStateChanged: return "PrintStateChanged";
|
||||
|
||||
case LifecycleEvent::DeviceOnlineChanged: return "DeviceOnlineChanged";
|
||||
case LifecycleEvent::DeviceDiscovered: return "DeviceDiscovered";
|
||||
case LifecycleEvent::DeviceSelected: return "DeviceSelected";
|
||||
case LifecycleEvent::DeviceConnected: return "DeviceConnected";
|
||||
case LifecycleEvent::DeviceDisconnected: return "DeviceDisconnected";
|
||||
|
||||
case LifecycleEvent::UploadStarted: return "UploadStarted";
|
||||
case LifecycleEvent::UploadFinished: return "UploadFinished";
|
||||
case LifecycleEvent::PrintJobStarted: return "PrintJobStarted";
|
||||
case LifecycleEvent::PrintJobFinished: return "PrintJobFinished";
|
||||
case LifecycleEvent::SendJobStarted: return "SendJobStarted";
|
||||
case LifecycleEvent::SendJobFinished: return "SendJobFinished";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string lifecycle_evt_code_to_string(LifecycleEvtCode code)
|
||||
{
|
||||
switch (code) {
|
||||
case LifecycleEvtCode::Ok: return "Ok";
|
||||
case LifecycleEvtCode::Error: return "Error";
|
||||
case LifecycleEvtCode::Warn: return "Warn";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// Global cross-layer seam (mirrors ConfigBase::set_resolve_capability_fn): any libslic3r code can
|
||||
// fire a lifecycle event without depending on the plugin layer above it, which installs the
|
||||
// dispatcher here at startup. Not tied to Print/GCode specifically, since nothing here should
|
||||
// require callers to hold a Print& just to report an event.
|
||||
using LifecycleHookFn = std::function<void(LifecycleEvent, const LifecycleEventContext&)>;
|
||||
|
||||
inline LifecycleHookFn& lifecycle_hook_fn()
|
||||
{
|
||||
static LifecycleHookFn fn;
|
||||
return fn;
|
||||
}
|
||||
|
||||
inline void set_lifecycle_hook_fn(LifecycleHookFn fn) { lifecycle_hook_fn() = std::move(fn); }
|
||||
|
||||
inline void fire_lifecycle_event(LifecycleEvent event, const LifecycleEventContext& ctx)
|
||||
{
|
||||
if (const LifecycleHookFn& fn = lifecycle_hook_fn(); fn)
|
||||
fn(event, ctx);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,6 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "LifecycleEvents.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Time.hpp"
|
||||
#include "PlaceholderParser.hpp"
|
||||
@@ -2973,7 +2972,6 @@ void PresetCollection::save_current_preset(const std::string &new_name, bool det
|
||||
// 1) Find the preset with a new_name or create a new one,
|
||||
// initialize it with the edited config.
|
||||
auto it = this->find_preset_internal(new_name);
|
||||
const bool preset_existed = (it != m_presets.end() && it->name == new_name);
|
||||
if (it != m_presets.end() && it->name == new_name) {
|
||||
// Preset with the same name found.
|
||||
Preset &preset = *it;
|
||||
@@ -3081,14 +3079,6 @@ void PresetCollection::save_current_preset(const std::string &new_name, bool det
|
||||
this->get_selected_preset().save(&(parent_preset->config));
|
||||
else
|
||||
this->get_selected_preset().save(nullptr);
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = new_name;
|
||||
ctx.msg = preset_existed ? "overwrite" : "new";
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::PresetSaved, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// A detached standalone preset for the Full Publish receiver: create a user preset holding
|
||||
|
||||
@@ -3824,7 +3824,6 @@ unsigned int PresetBundle::sync_ams_list(std::vector<std::pair<DynamicPrintConfi
|
||||
ConfigOptionStrings *filament_color_type = project_config.option<ConfigOptionStrings>("filament_colour_type");
|
||||
ConfigOptionInts * filament_map = project_config.option<ConfigOptionInts>("filament_map");
|
||||
ConfigOptionInts * filament_volume_map = project_config.option<ConfigOptionInts>("filament_volume_map");
|
||||
|
||||
// Snapshot and temporarily strip mixed filament slots so AMS sync operates on physical
|
||||
// filaments only. A mixed slot is virtual and has no tray to sync against; leaving it in
|
||||
// would let AMS mapping overwrite it and would break the physical-first slot ordering the
|
||||
|
||||
+1
-39
@@ -14,7 +14,6 @@
|
||||
#include "Flow.hpp"
|
||||
#include "Geometry/ConvexHull.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "LifecycleEvents.hpp"
|
||||
#include "ShortestPath.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "Time.hpp"
|
||||
@@ -2695,13 +2694,6 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
|
||||
if (m_objects.empty())
|
||||
return;
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(m_model.id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::SliceStarted, ctx);
|
||||
}
|
||||
|
||||
for (PrintObject *obj : m_objects)
|
||||
obj->clear_shared_object();
|
||||
|
||||
@@ -3320,13 +3312,6 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(m_model.id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::SliceGeometryFinished, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// G-code export process, running at a background thread.
|
||||
@@ -4926,14 +4911,6 @@ void Print::set_gcode_file_invalidated()
|
||||
//BBS: add gcode file preload logic
|
||||
void Print::export_gcode_from_previous_file(const std::string& file, GCodeProcessorResult* result, ThumbnailsGeneratorCallback thumbnail_cb)
|
||||
{
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(m_model.id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = file;
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportStarted, ctx);
|
||||
}
|
||||
|
||||
try {
|
||||
GCodeProcessor processor;
|
||||
GCodeProcessor::s_IsBBLPrinter = is_BBL_printer();
|
||||
@@ -4953,28 +4930,13 @@ void Print::export_gcode_from_previous_file(const std::string& file, GCodeProces
|
||||
*result = std::move(processor.extract_result());
|
||||
result->filament_change_sequence = filament_seq_loaded;
|
||||
result->nozzle_change_sequence = nozzle_seq_loaded;
|
||||
} catch (std::exception &ex) {
|
||||
} catch (std::exception & /* ex */) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": found errors when process gcode file %1%") %file.c_str();
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(m_model.id().id);
|
||||
ctx.code = LifecycleEvtCode::Error;
|
||||
ctx.msg = file + "\n" + ex.what();
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
throw Slic3r::RuntimeError(
|
||||
std::string("Failed to process the G-code file ") + file + " from previous 3mf\n");
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": process the G-code file %1% successfully")%file.c_str();
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = std::to_string(m_model.id().id);
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = file;
|
||||
fire_lifecycle_event(LifecycleEvent::GCodeExportFinished, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<float, float> Print::object_skirt_offset(double margin_height) const
|
||||
|
||||
@@ -139,8 +139,16 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/TerminalDialog.hpp
|
||||
GUI/PluginProgressDialog.cpp
|
||||
GUI/PluginProgressDialog.hpp
|
||||
GUI/PluginWebDialog.cpp
|
||||
GUI/PluginWebDialog.hpp
|
||||
GUI/WebDialog.cpp
|
||||
GUI/WebDialog.hpp
|
||||
GUI/DockPanel.cpp
|
||||
GUI/DockPanel.hpp
|
||||
GUI/WebPanel.cpp
|
||||
GUI/WebPanel.hpp
|
||||
GUI/Widgets/WebHosting.cpp
|
||||
GUI/Widgets/WebHosting.hpp
|
||||
GUI/AuiPaneLayout.cpp
|
||||
GUI/AuiPaneLayout.hpp
|
||||
GUI/DragCanvas.cpp
|
||||
GUI/DragCanvas.hpp
|
||||
GUI/EditGCodeDialog.cpp
|
||||
@@ -228,6 +236,7 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/GLToolbar.hpp
|
||||
GUI/ImageDPIFrame.cpp
|
||||
GUI/ImageDPIFrame.hpp
|
||||
GUI/IMediaController.hpp
|
||||
GUI/GUI_App.cpp
|
||||
GUI/GUI_App.hpp
|
||||
GUI/GUI_AuxiliaryList.cpp
|
||||
@@ -351,6 +360,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/MediaFilePanel.h
|
||||
GUI/MediaPlayCtrl.cpp
|
||||
GUI/MediaPlayCtrl.h
|
||||
GUI/WebRtcMediaController.cpp
|
||||
GUI/WebRtcMediaController.hpp
|
||||
GUI/MeshUtils.cpp
|
||||
GUI/MeshUtils.hpp
|
||||
GUI/ModelMall.cpp
|
||||
@@ -544,6 +555,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/WebUserLoginDialog.hpp
|
||||
GUI/WebViewDialog.cpp
|
||||
GUI/WebViewDialog.hpp
|
||||
GUI/WebMediaController.hpp
|
||||
GUI/WebMediaController.cpp
|
||||
GUI/Widgets/AMSControl.cpp
|
||||
GUI/Widgets/AMSControl.hpp
|
||||
GUI/Widgets/AMSItem.cpp
|
||||
@@ -738,6 +751,7 @@ set(SLIC3R_GUI_SOURCES
|
||||
Utils/NetworkAgentFactory.cpp
|
||||
Utils/ICloudServiceAgent.hpp
|
||||
Utils/IPrinterAgent.hpp
|
||||
Utils/ICameraSignalingChannel.hpp
|
||||
Utils/OrcaCloudServiceAgent.cpp
|
||||
Utils/OrcaCloudServiceAgent.hpp
|
||||
Utils/OrcaPrinterAgent.cpp
|
||||
@@ -908,7 +922,7 @@ else()
|
||||
set(_opengl_link_lib OpenGL::GL)
|
||||
endif()
|
||||
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode md4c-html glad ${_opengl_link_lib} hidapi mdns ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise pybind11::embed)
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode md4c-html glad ${_opengl_link_lib} hidapi mdns ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto LibDataChannel::LibDataChannel noise::noise pybind11::embed)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# Linux finds wxWidgets in module mode, whose include dirs and definitions
|
||||
@@ -965,29 +979,32 @@ endif ()
|
||||
|
||||
if (APPLE)
|
||||
# Static FFmpeg from the deps install: nothing to bundle into the .app,
|
||||
# no rpath/install_name handling. Order matters: avcodec -> swscale -> avutil.
|
||||
# no rpath/install_name handling. Order matters: avformat -> avcodec -> swscale -> avutil.
|
||||
find_library(LIBAVFORMAT_LIBRARY NAMES libavformat.a PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBAVCODEC_LIBRARY NAMES libavcodec.a PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBSWSCALE_LIBRARY NAMES libswscale.a PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBAVUTIL_LIBRARY NAMES libavutil.a PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
if (NOT LIBAVCODEC_LIBRARY OR NOT LIBSWSCALE_LIBRARY OR NOT LIBAVUTIL_LIBRARY)
|
||||
message(FATAL_ERROR "Static FFmpeg (libavcodec.a/libswscale.a/libavutil.a) not found under ${CMAKE_PREFIX_PATH}/lib. Rebuild the deps — FFMPEG builds static-only on macOS.")
|
||||
if (NOT LIBAVFORMAT_LIBRARY OR NOT LIBAVCODEC_LIBRARY OR NOT LIBSWSCALE_LIBRARY OR NOT LIBAVUTIL_LIBRARY)
|
||||
message(FATAL_ERROR "Static FFmpeg (libavformat.a/libavcodec.a/libswscale.a/libavutil.a) not found under ${CMAKE_PREFIX_PATH}/lib. Rebuild the deps — FFMPEG builds static-only on macOS.")
|
||||
endif ()
|
||||
target_link_libraries(libslic3r_gui ${LIBAVCODEC_LIBRARY} ${LIBSWSCALE_LIBRARY} ${LIBAVUTIL_LIBRARY})
|
||||
target_link_libraries(libslic3r_gui ${LIBAVFORMAT_LIBRARY} ${LIBAVCODEC_LIBRARY} ${LIBSWSCALE_LIBRARY} ${LIBAVUTIL_LIBRARY})
|
||||
target_include_directories(libslic3r_gui SYSTEM PRIVATE ${CMAKE_PREFIX_PATH}/include)
|
||||
elseif (WIN32)
|
||||
# Prebuilt shared FFmpeg from the deps install. Windows has no pkg-config,
|
||||
# so resolve the import libraries out of the deps prefix directly; the DLLs
|
||||
# are copied next to the executable by the top level CMakeLists.
|
||||
find_library(LIBAVFORMAT_LIBRARY NAMES avformat PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBAVCODEC_LIBRARY NAMES avcodec PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBSWSCALE_LIBRARY NAMES swscale PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBAVUTIL_LIBRARY NAMES avutil PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
if (NOT LIBAVCODEC_LIBRARY OR NOT LIBSWSCALE_LIBRARY OR NOT LIBAVUTIL_LIBRARY)
|
||||
message(FATAL_ERROR "FFmpeg (avcodec/swscale/avutil) not found under ${CMAKE_PREFIX_PATH}/lib. Rebuild the deps.")
|
||||
endif ()
|
||||
target_link_libraries(libslic3r_gui ${LIBAVCODEC_LIBRARY} ${LIBSWSCALE_LIBRARY} ${LIBAVUTIL_LIBRARY})
|
||||
target_link_libraries(libslic3r_gui ${LIBAVFORMAT_LIBRARY} ${LIBAVCODEC_LIBRARY} ${LIBSWSCALE_LIBRARY} ${LIBAVUTIL_LIBRARY})
|
||||
target_include_directories(libslic3r_gui SYSTEM PRIVATE ${CMAKE_PREFIX_PATH}/include)
|
||||
else ()
|
||||
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
|
||||
libavformat
|
||||
libavcodec
|
||||
libswscale
|
||||
libavutil
|
||||
|
||||
@@ -45,6 +45,25 @@ int AVVideoDecoder::open(Bambu_StreamInfo const &info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AVVideoDecoder::open(AVCodecParameters const ¶meters)
|
||||
{
|
||||
if (avcodec_parameters_to_context(codec_ctx_, ¶meters) < 0)
|
||||
return -1;
|
||||
|
||||
auto codec = avcodec_find_decoder(codec_ctx_->codec_id);
|
||||
if (codec == nullptr) {
|
||||
fprintf(stderr, "AVVideoDecoder: unsupported codec!\n");
|
||||
return -1;
|
||||
}
|
||||
if (avcodec_open2(codec_ctx_, codec, nullptr) < 0) {
|
||||
fprintf(stderr, "AVVideoDecoder: could not open codec\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
frame_ = av_frame_alloc();
|
||||
return frame_ == nullptr ? -1 : 0;
|
||||
}
|
||||
|
||||
int AVVideoDecoder::decode(const Bambu_Sample &sample)
|
||||
{
|
||||
int ret = -1;
|
||||
@@ -71,6 +90,14 @@ int AVVideoDecoder::decode(const Bambu_Sample &sample)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int AVVideoDecoder::decode(const AVPacket &packet)
|
||||
{
|
||||
int ret = avcodec_send_packet(codec_ctx_, &packet);
|
||||
if (ret == 0)
|
||||
got_frame_ = avcodec_receive_frame(codec_ctx_, frame_) == 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int AVVideoDecoder::flush()
|
||||
{
|
||||
int ret = avcodec_send_packet(codec_ctx_, nullptr);
|
||||
|
||||
@@ -23,8 +23,10 @@ public:
|
||||
|
||||
public:
|
||||
int open(Bambu_StreamInfo const &info);
|
||||
int open(AVCodecParameters const ¶meters);
|
||||
|
||||
int decode(Bambu_Sample const &sample);
|
||||
int decode(AVPacket const &packet);
|
||||
|
||||
int flush();
|
||||
|
||||
@@ -34,6 +36,14 @@ public:
|
||||
|
||||
bool toWxBitmap(wxBitmap &bitmap, wxSize const & size);
|
||||
|
||||
// Native size of the most recently decoded frame, or an unspecified size if
|
||||
// nothing has decoded yet. Lets a caller learn the video dimensions when the
|
||||
// container/probe could not report them up front.
|
||||
wxSize decoded_frame_size() const
|
||||
{
|
||||
return got_frame_ && frame_ ? wxSize{frame_->width, frame_->height} : wxSize{};
|
||||
}
|
||||
|
||||
private:
|
||||
AVCodecContext *codec_ctx_ = nullptr;
|
||||
AVFrame * frame_ = nullptr;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "AuiPaneLayout.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
std::string aui_pane_layout_entry(const std::string& layout, const std::string& pane_name)
|
||||
{
|
||||
// Panes are separated by '|'; SavePerspective() escapes a '|' inside a caption as "\|".
|
||||
const std::string prefix = "name=" + pane_name + ";";
|
||||
size_t begin = 0;
|
||||
for (size_t i = 0; i <= layout.size(); ++i) {
|
||||
if (i < layout.size() && (layout[i] != '|' || (i > 0 && layout[i - 1] == '\\')))
|
||||
continue;
|
||||
if (layout.compare(begin, prefix.size(), prefix) == 0)
|
||||
return layout.substr(begin, i - begin);
|
||||
begin = i + 1;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
// The part a wxAuiManager layout string (wxAuiManager::SavePerspective) holds for `pane_name`, in the
|
||||
// form wxAuiManager::LoadPaneInfo() takes, or empty when the layout has no such pane.
|
||||
std::string aui_pane_layout_entry(const std::string& layout, const std::string& pane_name);
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -328,7 +328,7 @@ void SelectMObjectPopup::update_user_devices()
|
||||
}
|
||||
|
||||
m_bind_machine_list.clear();
|
||||
m_bind_machine_list = dev->get_my_machine_list();
|
||||
m_bind_machine_list = dev->get_my_machine_list(dev->get_current_printer_agent_id());
|
||||
|
||||
//sort list
|
||||
std::vector<std::pair<std::string, MachineObject*>> user_machine_list;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "libslic3r/Print.hpp"
|
||||
|
||||
#include "DeviceCore/DevConfig.h"
|
||||
#include "DeviceCore/DevConfigUtil.h"
|
||||
#include "DeviceCore/DevExtruderSystem.h"
|
||||
#include "DeviceCore/DevFilaBlackList.h"
|
||||
#include "DeviceCore/DevFilaSystem.h"
|
||||
@@ -1647,18 +1648,8 @@ bool CalibrationPresetPage::is_blocking_printing()
|
||||
if (obj_ == nullptr) return true;
|
||||
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
auto source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
auto target_model = obj_->printer_type;
|
||||
|
||||
if (source_model != target_model) {
|
||||
std::vector<std::string> compatible_machine = obj_->get_compatible_machine();
|
||||
vector<std::string>::iterator it = find(compatible_machine.begin(), compatible_machine.end(), source_model);
|
||||
if (it == compatible_machine.end()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
const auto source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
bool CalibrationPresetPage::is_nozzle_info_synced() const
|
||||
|
||||
@@ -28,7 +28,6 @@ wxEND_EVENT_TABLE()
|
||||
|
||||
wxDEFINE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
|
||||
wxDEFINE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CAM_SOURCE_CHANGE, wxCommandEvent);
|
||||
|
||||
#define CAMERAPOPUP_CLICK_INTERVAL 20
|
||||
|
||||
@@ -102,34 +101,6 @@ CameraPopup::CameraPopup(wxWindow *parent)
|
||||
top_sizer->Add(0, 0, wxALL, 0);
|
||||
}
|
||||
|
||||
// Orca: custom IP camera source — lets the user point Live Video at any camera URL (Orca feature; not in the reference)
|
||||
m_custom_camera_input_confirm = new Button(m_panel, _L("Enable"));
|
||||
m_custom_camera_input_confirm->SetBackgroundColor(wxColour(38, 166, 154));
|
||||
m_custom_camera_input_confirm->SetBorderColor(wxColour(38, 166, 154));
|
||||
m_custom_camera_input_confirm->SetTextColor(wxColour(0xFFFFFE));
|
||||
m_custom_camera_input_confirm->SetFont(Label::Body_14);
|
||||
m_custom_camera_input_confirm->SetMinSize(wxSize(FromDIP(90), FromDIP(30)));
|
||||
m_custom_camera_input_confirm->SetPosition(wxDefaultPosition);
|
||||
m_custom_camera_input_confirm->SetCornerRadius(FromDIP(12));
|
||||
m_custom_camera_input = new TextInput(m_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize);
|
||||
m_custom_camera_input->GetTextCtrl()->SetHint(_L("Hostname or IP"));
|
||||
m_custom_camera_input->GetTextCtrl()->SetFont(Label::Body_14);
|
||||
m_custom_camera_hint = new wxStaticText(m_panel, wxID_ANY, _L("Custom camera source"));
|
||||
m_custom_camera_hint->Wrap(-1);
|
||||
m_custom_camera_hint->SetFont(Label::Head_14);
|
||||
m_custom_camera_hint->SetForegroundColour(TEXT_COL);
|
||||
|
||||
m_custom_camera_input_confirm->Bind(wxEVT_BUTTON, &CameraPopup::on_camera_source_changed, this);
|
||||
|
||||
if (!wxGetApp().app_config->get("camera", "custom_source").empty()) {
|
||||
m_custom_camera_input->GetTextCtrl()->SetValue(wxGetApp().app_config->get("camera", "custom_source"));
|
||||
set_custom_cam_button_state(wxGetApp().app_config->get("camera", "enable_custom_source") == "true");
|
||||
}
|
||||
|
||||
top_sizer->Add(m_custom_camera_hint, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
||||
top_sizer->Add(0, 0, wxALL, 0);
|
||||
top_sizer->Add(m_custom_camera_input, 2, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, FromDIP(5));
|
||||
top_sizer->Add(m_custom_camera_input_confirm, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
|
||||
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
|
||||
|
||||
auto url = wxString(L"https://www.orcaslicer.com/wiki/"); // Orca: neutral wiki link (vendor URL removed)
|
||||
@@ -184,37 +155,6 @@ void CameraPopup::sdcard_absent_hint()
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
}
|
||||
|
||||
void CameraPopup::on_camera_source_changed(wxCommandEvent &event)
|
||||
{
|
||||
if (m_obj && !m_custom_camera_input->GetTextCtrl()->IsEmpty()) {
|
||||
handle_camera_source_change();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraPopup::handle_camera_source_change()
|
||||
{
|
||||
m_custom_camera_enabled = !m_custom_camera_enabled;
|
||||
|
||||
set_custom_cam_button_state(m_custom_camera_enabled);
|
||||
|
||||
wxGetApp().app_config->set("camera", "custom_source", m_custom_camera_input->GetTextCtrl()->GetValue().ToStdString());
|
||||
wxGetApp().app_config->set("camera", "enable_custom_source", m_custom_camera_enabled);
|
||||
|
||||
wxCommandEvent evt(EVT_CAM_SOURCE_CHANGE);
|
||||
evt.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
}
|
||||
|
||||
void CameraPopup::set_custom_cam_button_state(bool state)
|
||||
{
|
||||
m_custom_camera_enabled = state;
|
||||
auto stateColour = state ? wxColour(170, 0, 0) : wxColour(38, 166, 154);
|
||||
auto stateText = state ? "Disable" : "Enable";
|
||||
m_custom_camera_input_confirm->SetBackgroundColor(stateColour);
|
||||
m_custom_camera_input_confirm->SetBorderColor(stateColour);
|
||||
m_custom_camera_input_confirm->SetLabel(_L(stateText));
|
||||
}
|
||||
|
||||
void CameraPopup::on_switch_recording(wxCommandEvent& event)
|
||||
{
|
||||
if (!m_obj) return;
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
#include "Widgets/RadioBox.hpp"
|
||||
#include "Widgets/PopupWindow.hpp"
|
||||
#include "Widgets/TextInput.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
wxDECLARE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
|
||||
wxDECLARE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_CAM_SOURCE_CHANGE, wxCommandEvent);
|
||||
|
||||
class CameraPopup : public PopupWindow
|
||||
{
|
||||
@@ -53,9 +51,6 @@ protected:
|
||||
void on_switch_recording(wxCommandEvent& event);
|
||||
void on_set_resolution();
|
||||
void sdcard_absent_hint();
|
||||
void on_camera_source_changed(wxCommandEvent& event);
|
||||
void handle_camera_source_change();
|
||||
void set_custom_cam_button_state(bool state);
|
||||
|
||||
wxWindow * create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left);
|
||||
void select_curr_radiobox(int btn_idx);
|
||||
@@ -76,10 +71,10 @@ private:
|
||||
wxStaticText* m_text_liveview_retry;
|
||||
SwitchButton* m_switch_liveview_retry;
|
||||
#endif //BBL_RELEASE_TO_PUBLIC
|
||||
wxStaticText* m_custom_camera_hint;
|
||||
TextInput* m_custom_camera_input;
|
||||
Button* m_custom_camera_input_confirm;
|
||||
bool m_custom_camera_enabled{ false };
|
||||
// wxStaticText* m_custom_camera_hint;
|
||||
// TextInput* m_custom_camera_input;
|
||||
// Button* m_custom_camera_input_confirm;
|
||||
// bool m_custom_camera_enabled{ false };
|
||||
wxStaticText* m_text_resolution;
|
||||
wxWindow* m_resolution_options[RESOLUTION_OPTIONS_NUM];
|
||||
wxScrolledWindow *m_panel;
|
||||
|
||||
@@ -35,7 +35,9 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
|
||||
sizer_connect = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_textCtrl_code = new TextInput(this, wxEmptyString);
|
||||
m_textCtrl_code->GetTextCtrl()->SetMaxLength(10);
|
||||
// OrcaSonar uses a 12-character base32 access code. Keep this field long
|
||||
// enough for it while retaining the existing validation for LAN codes.
|
||||
m_textCtrl_code->GetTextCtrl()->SetMaxLength(12);
|
||||
m_textCtrl_code->SetFont(Label::Body_14);
|
||||
m_textCtrl_code->SetCornerRadius(FromDIP(5));
|
||||
m_textCtrl_code->SetSize(wxSize(FromDIP(330), FromDIP(40)));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "DevConfigUtil.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include "../I18N.hpp"
|
||||
@@ -41,6 +43,19 @@ static void _toolhead_translation_markers()
|
||||
|
||||
std::string DevPrinterConfigUtil::m_resource_file_path = "";
|
||||
|
||||
bool DevPrinterConfigUtil::is_printer_model_compatible(const std::string& source_model, MachineObject& machine)
|
||||
{
|
||||
const std::string& target_model = machine.printer_type;
|
||||
if (is_optional_printer_model_id(source_model) || is_optional_printer_model_id(target_model))
|
||||
return true;
|
||||
|
||||
if (source_model == target_model)
|
||||
return true;
|
||||
|
||||
const auto compatible_machine = machine.get_compatible_machine();
|
||||
return std::find(compatible_machine.begin(), compatible_machine.end(), source_model) != compatible_machine.end();
|
||||
}
|
||||
|
||||
|
||||
std::map<std::string, std::string> DevPrinterConfigUtil::get_all_model_id_with_name()
|
||||
{
|
||||
@@ -405,4 +420,4 @@ std::string DevPrinterConfigUtil::get_toolhead_display_name(
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class MachineObject;
|
||||
|
||||
/// Toolhead component type (extruder / nozzle / hotend)
|
||||
enum class ToolHeadComponent {
|
||||
Extruder,
|
||||
@@ -59,6 +61,10 @@ public:
|
||||
/*printer*/
|
||||
// info
|
||||
static std::map<std::string, std::string> get_all_model_id_with_name();
|
||||
// A printer agent may not know the physical model. Keep that case optional so
|
||||
// model compatibility checks do not turn missing identity into a hard error.
|
||||
static bool is_printer_model_compatible(const std::string& source_model, MachineObject& machine);
|
||||
static bool is_optional_printer_model_id(const std::string& model_id) { return model_id.empty(); }
|
||||
static std::string get_printer_type(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "printer_type"); }
|
||||
static std::string get_printer_display_name(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "display_name"); }
|
||||
static std::string get_printer_series_str(std::string type_str) { return get_value_from_config<std::string>(type_str, "printer_series"); }
|
||||
@@ -227,4 +233,4 @@ static std::string _parse_printer_type(const std::string &type_str)
|
||||
return type_str;
|
||||
}
|
||||
|
||||
};// namespace Slic3r
|
||||
};// namespace Slic3r
|
||||
|
||||
@@ -762,9 +762,9 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS
|
||||
{
|
||||
curr_tray->remain = -1;
|
||||
}
|
||||
if (tray_it->contains("tray_slot_placeholder")) {
|
||||
curr_tray->is_slot_placeholder = true;
|
||||
}
|
||||
// The tray objects are reused across status updates. Reset this
|
||||
// state when a previously empty slot receives a filament again.
|
||||
curr_tray->is_slot_placeholder = tray_it->contains("tray_slot_placeholder");
|
||||
int ams_id_int = 0;
|
||||
int tray_id_int = 0;
|
||||
try
|
||||
@@ -999,4 +999,4 @@ void DevFilaSystemParser::ParseAgentFilament(const json& data, MachineObject* ob
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <exception>
|
||||
|
||||
#include "DevManager.h"
|
||||
#include "CloudProvider.hpp"
|
||||
#include "DevUtil.h"
|
||||
|
||||
// TODO: remove this include
|
||||
@@ -10,11 +11,12 @@
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
#include "slic3r/Utils/NetworkAgentFactory.hpp"
|
||||
|
||||
#include "libslic3r/Time.hpp"
|
||||
|
||||
#include "IPrinterAgent.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace {
|
||||
@@ -265,6 +267,10 @@ namespace Slic3r
|
||||
/* update userMachineList info */
|
||||
auto it = userMachineList.find(dev_id);
|
||||
if (it != userMachineList.end()) {
|
||||
// A reused entry may have been created while another printer agent was active.
|
||||
// The response was obtained through the current agent, so move ownership with
|
||||
// the entry; otherwise agent-scoped lists hide it after a preset switch.
|
||||
it->second->printer_agent_id = get_current_printer_agent_id();
|
||||
if (it->second->get_dev_ip() != dev_ip ||
|
||||
it->second->bind_state != bind_state ||
|
||||
it->second->bind_sec_link != sec_link ||
|
||||
@@ -295,6 +301,9 @@ namespace Slic3r
|
||||
// update properties
|
||||
/* ip changed */
|
||||
obj = it->second;
|
||||
// A reused LAN entry may have been discovered while another printer agent was
|
||||
// active. The current discovery message establishes ownership for this agent.
|
||||
obj->printer_agent_id = get_current_printer_agent_id();
|
||||
|
||||
if (obj->get_dev_ip().compare(dev_ip) != 0) {
|
||||
if ( connection_name.empty() ) {
|
||||
@@ -356,10 +365,7 @@ namespace Slic3r
|
||||
obj->bind_state = "free";
|
||||
|
||||
obj->last_alive = Slic3r::Utils::get_current_time_utc();
|
||||
// Route through set_online_state() (rather than writing m_is_online directly) so the
|
||||
// DeviceOnlineChanged lifecycle event fires consistently; same effective value/behavior
|
||||
// here since the object was already online in the common case.
|
||||
obj->set_online_state(true);
|
||||
obj->m_is_online = true;
|
||||
obj->set_dev_name(dev_name);
|
||||
/* if (!obj->dev_ip.empty()) {
|
||||
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip);
|
||||
@@ -377,10 +383,6 @@ namespace Slic3r
|
||||
obj->bind_sec_link = sec_link;
|
||||
obj->dev_connection_name = connection_name;
|
||||
obj->bind_ssdp_version = ssdp_version;
|
||||
// Discovery establishes the initial reachability state. Do not report it as an
|
||||
// online transition; DeviceDiscovered below is the lifecycle event for a new
|
||||
// device. Subsequent updates route through set_online_state(), so a known device
|
||||
// still emits DeviceOnlineChanged when its reachability actually changes.
|
||||
obj->m_is_online = true;
|
||||
|
||||
//load access code
|
||||
@@ -397,15 +399,6 @@ namespace Slic3r
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " New Machine, dev_id= " << dev_id
|
||||
<< ", ip = " << dev_ip <<", printer_name = " << dev_name
|
||||
<< ", con_type= " << connect_type <<", signal= " << printer_signal << ", bind_state= " << bind_state;
|
||||
|
||||
// First discovery of a genuinely new device (not a periodic SSDP/heartbeat update to
|
||||
// an already-known one, which is handled in the branch above).
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceDiscovered, ctx);
|
||||
}
|
||||
}
|
||||
update_local_machine(*obj);
|
||||
}
|
||||
@@ -422,6 +415,9 @@ namespace Slic3r
|
||||
auto it = localMachineList.find(machine.dev_id);
|
||||
if (it != localMachineList.end()) {
|
||||
obj = it->second;
|
||||
// insert_local_device is called by the active agent, so a reused entry must follow
|
||||
// that agent as well; otherwise the agent-scoped printer list hides it.
|
||||
obj->printer_agent_id = get_current_printer_agent_id();
|
||||
} else {
|
||||
obj = new MachineObject(this, m_agent, machine.dev_name, machine.dev_id, machine.dev_ip);
|
||||
obj->printer_agent_id = get_current_printer_agent_id();
|
||||
@@ -514,7 +510,7 @@ namespace Slic3r
|
||||
|
||||
MachineObject* DeviceManager::get_my_machine(std::string dev_id)
|
||||
{
|
||||
auto list = get_my_machine_list();
|
||||
auto list = get_my_machine_list(get_current_printer_agent_id());
|
||||
auto it = list.find(dev_id);
|
||||
if (it != list.end())
|
||||
{
|
||||
@@ -551,25 +547,15 @@ namespace Slic3r
|
||||
OnSelectedMachineChanged(previous_selected_machine, selected_machine);
|
||||
}
|
||||
|
||||
void DeviceManager::clear_other_devices(const std::string& target_agent_id)
|
||||
void DeviceManager::clear_other_devices()
|
||||
{
|
||||
// why: on agent swap, keep "My Devices" but drop the transient "Other Devices"
|
||||
// Those belong to the previous agent's network scan; the new agent's start_discovery re-populates its own.
|
||||
//
|
||||
// Also drop "My Devices" stamped by a different agent than the one we're swapping to
|
||||
// (target_agent_id, passed by the caller since the live agent hasn't been repointed yet
|
||||
// at this point): otherwise a device first discovered under agent A survives every swap
|
||||
// with a stale printer_agent_id, stays hidden from every agent's filtered list, and only
|
||||
// gets re-tagged if something happens to delete and re-create it (e.g. account logout).
|
||||
// Dropping it here instead lets the new agent's start_discovery re-insert and re-stamp it
|
||||
// like any other fresh device.
|
||||
const auto my = get_my_machine_list();
|
||||
// Device entries are now scoped by printer_agent_id when they are presented. Keep
|
||||
// agent-owned discoveries across a switch so agents without automatic discovery (and
|
||||
// plugins whose devices have not received an access code yet) do not lose their list.
|
||||
// Entries without an owner are legacy/unscoped and cannot safely be shown.
|
||||
for (auto it = localMachineList.begin(); it != localMachineList.end();)
|
||||
{
|
||||
const bool is_my_device = my.find(it->first) != my.end();
|
||||
const bool agent_mismatch = !target_agent_id.empty() && it->second &&
|
||||
it->second->printer_agent_id != target_agent_id;
|
||||
if (!is_my_device || agent_mismatch)
|
||||
if (!it->second || it->second->printer_agent_id.empty())
|
||||
{
|
||||
delete it->second;
|
||||
it = localMachineList.erase(it);
|
||||
@@ -585,8 +571,22 @@ namespace Slic3r
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id
|
||||
<< " cur_selected=" << selected_machine;
|
||||
auto my_machine_list = get_my_machine_list();
|
||||
auto my_machine_list = get_my_machine_list(get_current_printer_agent_id());
|
||||
auto it = my_machine_list.find(dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: set_selected_machine lookup dev_id=" << dev_id
|
||||
<< " found=" << (it != my_machine_list.end())
|
||||
<< " my_machine_count=" << my_machine_list.size()
|
||||
<< " current_agent=" << get_current_printer_agent_id()
|
||||
<< " provider=" << GUI::wxGetApp().get_printer_cloud_provider();
|
||||
if (it != my_machine_list.end() && it->second) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: target machine dev_id=" << it->second->get_dev_id()
|
||||
<< " printer_agent_id=" << it->second->printer_agent_id
|
||||
<< " connection_type=" << it->second->connection_type()
|
||||
<< " dev_connection_type=" << it->second->dev_connection_type;
|
||||
} else if (!dev_id.empty()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Orca diagnostic: target machine was not found in the current agent's machine list";
|
||||
return false;
|
||||
}
|
||||
|
||||
// disconnect last if dev_id difference from previous one
|
||||
auto last_selected = my_machine_list.find(selected_machine);
|
||||
@@ -597,7 +597,9 @@ namespace Slic3r
|
||||
m_agent->disconnect_printer();
|
||||
}
|
||||
else if (last_selected->second->connection_type() == "cloud") {
|
||||
m_agent->set_user_selected_machine("");
|
||||
const int result = m_agent->set_user_selected_machine("");
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: cleared previous cloud selection dev_id="
|
||||
<< selected_machine << " result=" << result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,7 +651,9 @@ namespace Slic3r
|
||||
{
|
||||
// diff dev_id, cloud => set_user_selected_machine(new)
|
||||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: select new cloud machine, dev_id =" << dev_id;
|
||||
m_agent->set_user_selected_machine(dev_id);
|
||||
const int result = m_agent->set_user_selected_machine(dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: set new cloud selection dev_id="
|
||||
<< dev_id << " result=" << result;
|
||||
it->second->reset();
|
||||
}
|
||||
else
|
||||
@@ -677,6 +681,8 @@ namespace Slic3r
|
||||
|
||||
selected_machine = dev_id;
|
||||
record_user_last_machine(selected_machine);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: DeviceManager selection complete selected_machine="
|
||||
<< selected_machine;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -707,7 +713,9 @@ namespace Slic3r
|
||||
dev_list.push_back(it->first);
|
||||
BOOST_LOG_TRIVIAL(trace) << "add_user_subscribe: " << it->first;
|
||||
}
|
||||
m_agent->add_subscribe(dev_list);
|
||||
const int result = m_agent->add_subscribe(dev_list);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: add_user_subscribe count=" << dev_list.size()
|
||||
<< " result=" << result;
|
||||
}
|
||||
|
||||
|
||||
@@ -720,7 +728,9 @@ namespace Slic3r
|
||||
dev_list.push_back(it->first);
|
||||
BOOST_LOG_TRIVIAL(trace) << "del_user_subscribe: " << it->first;
|
||||
}
|
||||
m_agent->del_subscribe(dev_list);
|
||||
const int result = m_agent->del_subscribe(dev_list);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: del_user_subscribe count=" << dev_list.size()
|
||||
<< " result=" << result;
|
||||
}
|
||||
|
||||
void DeviceManager::subscribe_device_list(std::vector<std::string> dev_list)
|
||||
@@ -839,7 +849,23 @@ namespace Slic3r
|
||||
try
|
||||
{
|
||||
json j = json::parse(body);
|
||||
const std::string provider = GUI::wxGetApp().get_printer_cloud_provider();
|
||||
|
||||
const bool has_request_context = j.contains("provider") && j.contains("agent_id") && j.contains("generation");
|
||||
const std::string provider = j.contains("provider") ? j["provider"].get<std::string>()
|
||||
: GUI::wxGetApp().get_printer_cloud_provider();
|
||||
const std::string agent_id = j.contains("agent_id") ? j["agent_id"].get<std::string>()
|
||||
: get_current_printer_agent_id();
|
||||
const std::uint64_t generation = j.value("generation", std::uint64_t(0));
|
||||
|
||||
if (has_request_context &&
|
||||
(provider != GUI::wxGetApp().get_printer_cloud_provider() ||
|
||||
agent_id != get_current_printer_agent_id() ||
|
||||
generation != (m_agent ? m_agent->get_user_machine_list_generation() : 0))) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ": ignoring stale response provider="
|
||||
<< provider << " agent_id=" << agent_id
|
||||
<< " generation=" << generation;
|
||||
return;
|
||||
}
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": " << j;
|
||||
@@ -862,11 +888,14 @@ namespace Slic3r
|
||||
/* update field */
|
||||
obj = iter->second;
|
||||
obj->set_dev_id(dev_id);
|
||||
// A device can be rediscovered by a different agent after a preset
|
||||
// switch while retaining the same MachineObject instance.
|
||||
obj->printer_agent_id = agent_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = new MachineObject(this, m_agent, "", "", "");
|
||||
obj->printer_agent_id = get_current_printer_agent_id();
|
||||
obj->printer_agent_id = agent_id;
|
||||
if (m_agent)
|
||||
{
|
||||
obj->set_bind_status(m_agent->get_user_name(provider));
|
||||
@@ -881,6 +910,12 @@ namespace Slic3r
|
||||
|
||||
if (!obj) continue;
|
||||
|
||||
// Orca cloud printers are only ever delivered through this REST
|
||||
// account list; tag them so DeviceManager's cloud/lan branches
|
||||
// (subscribe + deselect in set_selected_machine) treat them right.
|
||||
if (provider == ORCA_CLOUD_PROVIDER)
|
||||
obj->dev_connection_type = "cloud";
|
||||
|
||||
if (!elem["dev_id"].is_null())
|
||||
obj->set_dev_id(elem["dev_id"].get<std::string>());
|
||||
if (!elem["dev_name"].is_null())
|
||||
@@ -912,6 +947,12 @@ namespace Slic3r
|
||||
acc_code.erase(std::remove(acc_code.begin(), acc_code.end(), '\n'), acc_code.end());
|
||||
obj->set_access_code(acc_code);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: parsed cloud machine dev_id=" << dev_id
|
||||
<< " name=" << obj->get_dev_name()
|
||||
<< " agent_id=" << obj->printer_agent_id
|
||||
<< " connection_type=" << obj->connection_type()
|
||||
<< " online=" << obj->m_is_online;
|
||||
}
|
||||
|
||||
//remove MachineObject from userMachineList
|
||||
@@ -927,6 +968,9 @@ namespace Slic3r
|
||||
iterat++;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: parse_user_print_info complete provider=" << provider
|
||||
<< " parsed_count=" << new_list.size()
|
||||
<< " stored_count=" << userMachineList.size();
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
@@ -943,10 +987,14 @@ namespace Slic3r
|
||||
unsigned int http_code;
|
||||
std::string body;
|
||||
int result = m_agent->get_user_print_info(&http_code, &body, provider);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: get_user_print_info provider=" << provider
|
||||
<< " result=" << result << " http_code=" << http_code
|
||||
<< " body_bytes=" << body.size();
|
||||
if (result == 0)
|
||||
{
|
||||
// parse_user_print_info and on_machine_alive (SSDP for discovery) both mutate the same userMachineList map.
|
||||
// on_machine_alive mutates the map on the UI thread, do the same for parse_user_print_info.
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: queueing parse_user_print_info on UI thread";
|
||||
Slic3r::GUI::wxGetApp().CallAfter([this, body]() { parse_user_print_info(body); });
|
||||
}
|
||||
}
|
||||
@@ -1001,14 +1049,8 @@ namespace Slic3r
|
||||
}
|
||||
|
||||
void DeviceManager::OnSelectedMachineChanged(const std::string& /*pre_dev_id*/,
|
||||
const std::string& new_dev_id)
|
||||
const std::string& /*new_dev_id*/)
|
||||
{
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = new_dev_id; // empty string is a valid deselection
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceSelected, ctx);
|
||||
}
|
||||
if (MachineObject* obj_ = get_selected_machine()) {
|
||||
GUI::wxGetApp().sidebar().update_sync_status(obj_);
|
||||
if(m_agent->get_filament_sync_mode() == FilamentSyncMode::subscription)
|
||||
|
||||
@@ -74,10 +74,9 @@ public:
|
||||
void erase_user_machine(std::string dev_id) { userMachineList.erase(dev_id); }
|
||||
void clean_user_info(bool keep_local_selection = false);
|
||||
|
||||
// target_agent_id: id of the agent being swapped to (empty = no agent-mismatch check,
|
||||
// just the original "drop Other Devices" behavior). Pass the incoming agent's id, not the
|
||||
// live one - this runs before the live agent is repointed.
|
||||
void clear_other_devices(const std::string& target_agent_id = "");
|
||||
// Retain agent-owned LAN discoveries across a switch; the active-agent list filter keeps
|
||||
// entries from other agents hidden while allowing them to reappear when switched back.
|
||||
void clear_other_devices();
|
||||
|
||||
void load_last_machine();
|
||||
void update_user_machine_list_info(const std::string& provider);
|
||||
@@ -154,4 +153,4 @@ public:
|
||||
protected:
|
||||
virtual void on_timer(wxTimerEvent& event);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
+200
-111
@@ -4,8 +4,8 @@
|
||||
#include "I18N.hpp"
|
||||
#include "libslic3r/Time.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "slic3r/Utils/Http.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
#include "slic3r/Utils/NetworkAgentFactory.hpp"
|
||||
#include "GuiColor.hpp"
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "DeviceCore/DevStatus.h"
|
||||
#include "DeviceCore/DevUpgrade.h"
|
||||
|
||||
#include "IPrinterAgent.hpp"
|
||||
|
||||
#define CALI_DEBUG
|
||||
#define MINUTE_30 1800000 //ms
|
||||
@@ -374,8 +375,22 @@ NozzleVolumeType convert_to_nozzle_type(const std::string &str)
|
||||
wxString MachineObject::get_printer_type_display_str() const
|
||||
{
|
||||
std::string display_name = DevPrinterConfigUtil::get_printer_display_name(printer_type);
|
||||
|
||||
// Bambu printers use m_resource_file_path + "/printers/" + type_str + ".json", which is a semantic that only works for their profiles.
|
||||
// For any other profile, we can simply consult preset bundle if the model_id exists.
|
||||
if (display_name.empty()) {
|
||||
for (const auto& [vendor_id, vendor] : GUI::wxGetApp().preset_bundle->vendors) {
|
||||
for (const auto& model : vendor.models) {
|
||||
if (printer_type == model.model_id)
|
||||
display_name = model.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!display_name.empty())
|
||||
return display_name;
|
||||
else if (printer_type == "orcasonar")
|
||||
return "OrcaSonar Printer";
|
||||
else
|
||||
return _L("Unknown");
|
||||
}
|
||||
@@ -1342,7 +1357,6 @@ int MachineObject::command_get_access_code() {
|
||||
return this->publish_json(j);
|
||||
}
|
||||
|
||||
|
||||
int MachineObject::command_request_push_all(bool request_now)
|
||||
{
|
||||
auto curr_time = std::chrono::system_clock::now();
|
||||
@@ -1474,26 +1488,20 @@ int MachineObject::command_upgrade_module(std::string url, std::string module_ty
|
||||
|
||||
int MachineObject::command_xyz_abs()
|
||||
{
|
||||
return this->publish_gcode("G90 \n");
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_xyz_abs(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_auto_leveling()
|
||||
{
|
||||
return this->publish_gcode("G29 \n");
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_auto_leveling(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_go_home()
|
||||
{
|
||||
if (m_support_mqtt_homing)
|
||||
{
|
||||
json j;
|
||||
j["print"]["command"] = "back_to_center";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
return this->publish_json(j);
|
||||
}
|
||||
|
||||
// gcode command
|
||||
return this->is_in_printing() ? this->publish_gcode("G28 X\n") : this->publish_gcode("G28 \n");
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_go_home(get_dev_id(), this->is_in_printing(), m_support_mqtt_homing, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_task_partskip(std::vector<int> part_ids)
|
||||
@@ -1615,23 +1623,14 @@ int MachineObject::command_stop_buzzer()
|
||||
|
||||
int MachineObject::command_set_bed(int temp)
|
||||
{
|
||||
if (m_support_mqtt_bet_ctrl)
|
||||
{
|
||||
json j;
|
||||
j["print"]["command"] = "set_bed_temp";
|
||||
j["print"]["temp"] = temp;
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
return this->publish_json(j);
|
||||
}
|
||||
|
||||
std::string gcode_str = (boost::format("M140 S%1%\n") % temp).str();
|
||||
return this->publish_gcode(gcode_str);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_set_bed(get_dev_id(), temp, m_support_mqtt_bet_ctrl, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_set_nozzle(int temp)
|
||||
{
|
||||
std::string gcode_str = (boost::format("M104 S%1%\n") % temp).str();
|
||||
return this->publish_gcode(gcode_str);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_set_nozzle(get_dev_id(), temp, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_set_nozzle_new(int nozzle_id, int temp)
|
||||
@@ -1736,9 +1735,8 @@ int MachineObject::command_ams_user_settings(bool start_read_opt, bool tray_read
|
||||
|
||||
int MachineObject::command_ams_calibrate(int ams_id)
|
||||
{
|
||||
std::string gcode_cmd = (boost::format("M620 C%1% \n") % ams_id).str();
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_debug: gcode_cmd" << gcode_cmd;
|
||||
return this->publish_gcode(gcode_cmd);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_ams_calibrate(get_dev_id(), ams_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_filament_settings(int ams_id, int slot_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max)
|
||||
@@ -1776,9 +1774,8 @@ int MachineObject::command_ams_filament_settings(int ams_id, int slot_id, std::s
|
||||
|
||||
int MachineObject::command_ams_refresh_rfid(std::string tray_id)
|
||||
{
|
||||
std::string gcode_cmd = (boost::format("M620 R%1% \n") % tray_id).str();
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_debug: gcode_cmd" << gcode_cmd;
|
||||
return this->publish_gcode(gcode_cmd);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_ams_refresh_rfid(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_refresh_rfid2(int ams_id, int slot_id)
|
||||
@@ -1791,12 +1788,17 @@ int MachineObject::command_ams_refresh_rfid2(int ams_id, int slot_id)
|
||||
return this->publish_json(j);
|
||||
}
|
||||
|
||||
int MachineObject::command_start_camera()
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
return m_agent->command_start_camera(get_dev_id());
|
||||
}
|
||||
|
||||
|
||||
int MachineObject::command_ams_select_tray(std::string tray_id)
|
||||
{
|
||||
std::string gcode_cmd = (boost::format("M620 P%1% \n") % tray_id).str();
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_debug: gcode_cmd" << gcode_cmd;
|
||||
return this->publish_gcode(gcode_cmd);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_ams_select_tray(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_control(std::string action)
|
||||
@@ -1955,47 +1957,10 @@ int MachineObject::command_ams_air_print_detect(bool air_print_detect)
|
||||
|
||||
int MachineObject::command_axis_control(std::string axis, double unit, double input_val, int speed)
|
||||
{
|
||||
if (m_support_mqtt_axis_control)
|
||||
{
|
||||
int dir = input_val > 0 ? 1 : -1;
|
||||
// i3-arch printers move the bed for Y/Z, so the on-screen direction is
|
||||
// reversed — same negation the g-code fallback below applies.
|
||||
if (!is_core_xy() && (axis.compare("Y") == 0 || axis.compare("Z") == 0)) {
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
json j;
|
||||
j["print"]["command"] = "xyz_ctrl";
|
||||
j["print"]["axis"] = axis;
|
||||
j["print"]["dir"] = dir;
|
||||
j["print"]["mode"] = (std::abs(input_val) >= 10) ? 1 : 0;
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
return this->publish_json(j);
|
||||
}
|
||||
|
||||
double value = input_val;
|
||||
if (!is_core_xy()) {
|
||||
if ( axis.compare("Y") == 0
|
||||
|| axis.compare("Z") == 0) {
|
||||
value = -1.0 * input_val;
|
||||
}
|
||||
}
|
||||
|
||||
char cmd[256];
|
||||
if (axis.compare("X") == 0
|
||||
|| axis.compare("Y") == 0
|
||||
|| axis.compare("Z") == 0) {
|
||||
sprintf(cmd, "M211 S \nM211 X1 Y1 Z1\nM1002 push_ref_mode\nG91 \nG1 %s%0.1f F%d\nM1002 pop_ref_mode\nM211 R\n", axis.c_str(), value * unit, speed);
|
||||
}
|
||||
else if (axis.compare("E") == 0) {
|
||||
sprintf(cmd, "M83 \nG0 %s%0.1f F%d\n", axis.c_str(), value * unit, speed);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return this->publish_gcode(cmd);
|
||||
if (!m_agent) return -1;
|
||||
return command_with_dialog(m_agent->command_axis_control(get_dev_id(), axis, unit, input_val, speed, is_core_xy(),
|
||||
m_support_mqtt_axis_control, MachineObject::m_sequence_id++,
|
||||
is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_extruder_control(int nozzle_id, double val)
|
||||
@@ -2620,33 +2585,67 @@ void MachineObject::reset()
|
||||
vt_slot.erase(vt_slot.begin() + 1);
|
||||
}
|
||||
}
|
||||
subtask_ = nullptr;
|
||||
// why: reset reuses MachineObject, so release its lazy subtask
|
||||
// before dropping the pointer to prevent reconnect leaks.
|
||||
if (subtask_) {
|
||||
delete subtask_;
|
||||
subtask_ = nullptr;
|
||||
}
|
||||
has_extra_flow_type = false;
|
||||
m_partskip_ids.clear();
|
||||
}
|
||||
|
||||
void MachineObject::set_print_state(std::string status)
|
||||
{
|
||||
const bool changed = (print_status != status);
|
||||
print_status = status;
|
||||
if (changed) {
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = print_status;
|
||||
fire_lifecycle_event(LifecycleEvent::PrintStateChanged, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// why: printer agents can report progress without BBL cloud task identity.
|
||||
void MachineObject::update_print_progress(const json& value)
|
||||
{
|
||||
if (value.is_string())
|
||||
mc_print_percent = stoi(value.get<std::string>());
|
||||
else if (value.is_number_integer())
|
||||
mc_print_percent = value.get<int>();
|
||||
else
|
||||
return;
|
||||
|
||||
if (BBLSubTask* curr_task = get_subtask())
|
||||
curr_task->task_progress = mc_print_percent;
|
||||
}
|
||||
|
||||
int MachineObject::connect(bool use_openssl)
|
||||
{
|
||||
if (get_dev_ip().empty()) return -1;
|
||||
std::string username = "bblp";
|
||||
std::string username = m_agent ? m_agent->default_lan_username() : std::string();
|
||||
std::string password = get_access_code();
|
||||
|
||||
std::string port;
|
||||
std::string host = Http::get_host_from_url(get_dev_ip(), &port);
|
||||
std::string ca_file;
|
||||
|
||||
if (GUI::wxGetApp().preset_bundle) {
|
||||
const auto& config = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
if (port.empty())
|
||||
port = config.opt_string("printhost_port");
|
||||
ca_file = config.opt_string("printhost_cafile");
|
||||
}
|
||||
|
||||
if (host.empty())
|
||||
host = get_dev_ip();
|
||||
|
||||
if (m_agent) {
|
||||
try {
|
||||
return m_agent->connect_printer(get_dev_id(), get_dev_ip(), username, password, use_openssl);
|
||||
PrinterConnectionParams params{
|
||||
get_dev_id(),
|
||||
host,
|
||||
port,
|
||||
username,
|
||||
password,
|
||||
use_openssl,
|
||||
ca_file
|
||||
};
|
||||
return m_agent->connect_printer(params);
|
||||
} catch (...) {
|
||||
;
|
||||
}
|
||||
@@ -2657,10 +2656,6 @@ int MachineObject::connect(bool use_openssl)
|
||||
int MachineObject::disconnect()
|
||||
{
|
||||
if (m_agent) {
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx);
|
||||
return m_agent->disconnect_printer();
|
||||
}
|
||||
return -1;
|
||||
@@ -2691,16 +2686,8 @@ bool MachineObject::is_connecting()
|
||||
|
||||
void MachineObject::set_online_state(bool on_off)
|
||||
{
|
||||
const bool changed = (m_is_online != on_off);
|
||||
m_is_online = on_off;
|
||||
if (!on_off) m_active_state = NotActive;
|
||||
if (changed) {
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
ctx.msg = on_off ? "online" : "offline";
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceOnlineChanged, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
bool MachineObject::is_info_ready(bool check_version) const
|
||||
@@ -2763,6 +2750,14 @@ int MachineObject::publish_json(const json& json_item, int qos, int flag)
|
||||
BOOST_LOG_TRIVIAL(error) << "publish_json: " << json_item.dump() << " code: " << rtn;
|
||||
}
|
||||
|
||||
// why: the agent is the only thing that knows what it can translate, so it reports
|
||||
// not-supported in its return value and this - the single funnel every command_* builder
|
||||
// passes through - is the one place that turns it into something the user sees. No list of
|
||||
// unsupported commands is needed anywhere: an agent that has no case for a command says so.
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE) {
|
||||
show_unsupported_dlg(rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@@ -3067,6 +3062,13 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
try {
|
||||
if (j.contains("info"))
|
||||
parse_new_info2(j["info"]);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "parse_json: failed to parse OrcaSonar capability info";
|
||||
}
|
||||
|
||||
try {
|
||||
if (auto ptr = m_fila_system->GetAmsFirmwareSwitch().lock()) {
|
||||
ptr->ParseFirmwareSwitch(j);
|
||||
@@ -3319,10 +3321,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
print_type = jj["print_type"].get<std::string>();
|
||||
}
|
||||
if (jj.contains("mc_percent")) {
|
||||
if (jj["mc_percent"].is_string())
|
||||
mc_print_percent = stoi(j["print"]["mc_percent"].get<std::string>());
|
||||
else if (jj["mc_percent"].is_number_integer())
|
||||
mc_print_percent = j["print"]["mc_percent"].get<int>();
|
||||
update_print_progress(jj["mc_percent"]);
|
||||
}
|
||||
if (jj.contains("mc_print_sub_stage")) {
|
||||
if (jj["mc_print_sub_stage"].is_number_integer())
|
||||
@@ -3492,6 +3491,9 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
this->task_id_ = jj["task_id"].get<std::string>();
|
||||
}
|
||||
|
||||
if (jj.contains("thumbnail_url") && jj["thumbnail_url"].is_string())
|
||||
m_agent_thumbnail_url = jj["thumbnail_url"].get<std::string>();
|
||||
|
||||
if (jj.contains("job_attr")) {
|
||||
int jobAttr = jj["job_attr"].get<int>();
|
||||
jobState_ = get_flag_bits(jobAttr, 4, 4);
|
||||
@@ -3537,7 +3539,6 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
update_slice_info(jj["project_id"].get<std::string>(), jj["profile_id"].get<std::string>(), jj["subtask_id"].get<std::string>(), plate_index);
|
||||
BBLSubTask* curr_task = get_subtask();
|
||||
if (curr_task) {
|
||||
curr_task->task_progress = mc_print_percent;
|
||||
curr_task->printing_status = print_status;
|
||||
curr_task->task_id = jj["subtask_id"].get<std::string>();
|
||||
}
|
||||
@@ -3840,6 +3841,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
has_ipcam = true;
|
||||
} else {
|
||||
has_ipcam = false;
|
||||
webcam_stream_url.clear();
|
||||
}
|
||||
}
|
||||
if (ipcam.contains("resolution")) {
|
||||
@@ -3874,6 +3876,9 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
liveview_local = local_rtsp_url.empty() ? LVL_None : local_rtsp_url == "disable"
|
||||
? LVL_Disable : boost::algorithm::starts_with(local_rtsp_url, "rtsps") ? LVL_Rtsps : LVL_Rtsp;
|
||||
}
|
||||
if (ipcam.contains("stream_url") && ipcam["stream_url"].is_string()) {
|
||||
webcam_stream_url = ipcam["stream_url"].get<std::string>();
|
||||
}
|
||||
if (ipcam.contains("tutk_server")) {
|
||||
tutk_state = ipcam["tutk_server"].get<std::string>();
|
||||
}
|
||||
@@ -4622,13 +4627,8 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
try {
|
||||
if (j.contains("event")) {
|
||||
if (j["event"].contains("event")) {
|
||||
if (j["event"]["event"].get<std::string>() == "client.disconnected") {
|
||||
if (j["event"]["event"].get<std::string>() == "client.disconnected")
|
||||
set_online_state(false);
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx);
|
||||
}
|
||||
else if (j["event"]["event"].get<std::string>() == "client.connected")
|
||||
set_online_state(true);
|
||||
}
|
||||
@@ -5458,6 +5458,86 @@ void MachineObject::parse_new_info(json print)
|
||||
}
|
||||
}
|
||||
|
||||
void MachineObject::parse_new_info2(const json& info)
|
||||
{
|
||||
if (!info.is_object() || info.value("command", "") != "get_capabilities")
|
||||
return;
|
||||
|
||||
const auto capabilities_it = info.find("capabilities");
|
||||
if (capabilities_it == info.end() || !capabilities_it->is_object())
|
||||
return;
|
||||
const auto flags_it = capabilities_it->find("flags");
|
||||
if (flags_it == capabilities_it->end() || !flags_it->is_object())
|
||||
return;
|
||||
|
||||
const json& flags = *flags_it;
|
||||
BOOST_LOG_TRIVIAL(info) << "parse_new_info2: OrcaSonar capability flags=" << flags.dump();
|
||||
|
||||
auto parse_bool = [&flags](const char* name, bool& target) {
|
||||
const auto it = flags.find(name);
|
||||
if (it != flags.end() && it->is_boolean())
|
||||
target = it->get<bool>();
|
||||
};
|
||||
|
||||
parse_bool("support_send_to_sd", is_support_send_to_sdcard);
|
||||
parse_bool("support_filament_backup", is_support_filament_backup);
|
||||
parse_bool("support_update_remain", is_support_update_remain);
|
||||
parse_bool("support_auto_recovery_step_loss", is_support_auto_recovery_step_loss);
|
||||
parse_bool("support_ams_humidity", is_support_ams_humidity);
|
||||
parse_bool("support_prompt_sound", is_support_prompt_sound);
|
||||
parse_bool("support_filament_tangle_detect", is_support_filament_tangle_detect);
|
||||
parse_bool("support_1080dpi", is_support_1080dpi);
|
||||
parse_bool("support_cloud_print_only", is_support_cloud_print_only);
|
||||
parse_bool("support_command_ams_switch", is_support_command_ams_switch);
|
||||
parse_bool("support_mqtt_alive", is_support_mqtt_alive);
|
||||
parse_bool("support_motor_noise_cali", is_support_motor_noise_cali);
|
||||
parse_bool("support_timelapse", is_support_timelapse);
|
||||
parse_bool("support_user_preset", is_support_user_preset);
|
||||
parse_bool("support_refresh_nozzle", is_support_refresh_nozzle);
|
||||
parse_bool("support_flow_calibration", is_support_flow_calibration);
|
||||
parse_bool("support_build_plate_marker_detect", is_support_build_plate_marker_detect);
|
||||
parse_bool("support_nozzle_blob_detect", is_support_nozzle_blob_detection);
|
||||
|
||||
if (!m_manager->IsMultiMachineEnabled() && !is_support_agora)
|
||||
parse_bool("support_tunnel_mqtt", is_support_tunnel_mqtt);
|
||||
|
||||
const auto bed_leveling_it = flags.find("support_bed_leveling");
|
||||
if (bed_leveling_it != flags.end() && bed_leveling_it->is_number_integer())
|
||||
is_support_bed_leveling = bed_leveling_it->get<int>();
|
||||
|
||||
auto copy_bool = [&flags](json& target, const char* name) {
|
||||
const auto it = flags.find(name);
|
||||
if (it != flags.end() && it->is_boolean())
|
||||
target[name] = *it;
|
||||
};
|
||||
|
||||
// The capability manifest uses an object for this range, while the legacy
|
||||
// DeviceCore parser consumes a boolean plus a two-element range array.
|
||||
json device_config;
|
||||
copy_bool(device_config, "support_chamber");
|
||||
copy_bool(device_config, "support_first_layer_inspect");
|
||||
copy_bool(device_config, "support_ai_monitoring");
|
||||
copy_bool(device_config, "support_lidar_calibration");
|
||||
const auto chamber_edit_it = flags.find("support_chamber_temp_edit");
|
||||
if (chamber_edit_it != flags.end() && chamber_edit_it->is_boolean()) {
|
||||
device_config["support_chamber_temp_edit"] = *chamber_edit_it;
|
||||
} else if (chamber_edit_it != flags.end() && chamber_edit_it->is_object()) {
|
||||
const auto min_it = chamber_edit_it->find("min");
|
||||
const auto max_it = chamber_edit_it->find("max");
|
||||
if (min_it != chamber_edit_it->end() && max_it != chamber_edit_it->end() && min_it->is_number() && max_it->is_number()) {
|
||||
device_config["support_chamber_temp_edit"] = true;
|
||||
device_config["support_chamber_temp_edit_range"] = {*min_it, *max_it};
|
||||
}
|
||||
}
|
||||
|
||||
json fan_config;
|
||||
copy_bool(fan_config, "support_aux_fan");
|
||||
copy_bool(fan_config, "support_chamber_fan");
|
||||
|
||||
m_config->ParseConfig(device_config);
|
||||
m_fan->ParseV2_0(fan_config);
|
||||
}
|
||||
|
||||
static bool is_hex_digit(char c) {
|
||||
return std::isxdigit(static_cast<unsigned char>(c)) != 0;
|
||||
}
|
||||
@@ -5963,6 +6043,15 @@ bool MachineObject::HasAms() const
|
||||
return m_fila_system->HasAms();
|
||||
}
|
||||
|
||||
int MachineObject::command_with_dialog(int cmd_result)
|
||||
{
|
||||
if (!m_agent)
|
||||
return -1;
|
||||
if (cmd_result == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || cmd_result == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(cmd_result);
|
||||
return cmd_result;
|
||||
}
|
||||
|
||||
void change_the_opacity(wxColour& colour)
|
||||
{
|
||||
if (colour.Alpha() == 255) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "boost/bimap/bimap.hpp"
|
||||
#include "libslic3r/calib.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "slic3r/Utils/PrinterNetworkTypes.hpp"
|
||||
|
||||
#include "DeviceCore/DevDefs.h"
|
||||
#include "DeviceCore/DevConfigUtil.h"
|
||||
@@ -100,7 +101,6 @@ struct DevPrintTaskRatingInfo;
|
||||
// given nozzle diameter (mm), bucketed per nozzle size to mirror the printer firmware.
|
||||
bool is_stringing_prone_filament(const std::string& filament_id, float nozzle_diameter);
|
||||
|
||||
|
||||
class MachineObject
|
||||
{
|
||||
private:
|
||||
@@ -307,7 +307,7 @@ public:
|
||||
bool ams_support_virtual_tray { true };
|
||||
time_t ams_user_setting_start = 0;
|
||||
time_t ams_switch_filament_start = 0;
|
||||
AmsStatusMain ams_status_main;
|
||||
AmsStatusMain ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_IDLE;
|
||||
int ams_status_sub;
|
||||
int ams_version = 0;
|
||||
|
||||
@@ -547,30 +547,12 @@ public:
|
||||
bool xcam_first_layer_inspector { false };
|
||||
time_t xcam_first_layer_hold_start = 0;
|
||||
std::string local_rtsp_url;
|
||||
std::string webcam_stream_url;
|
||||
std::string tutk_state;
|
||||
enum LiveviewLocal {
|
||||
LVL_None,
|
||||
LVL_Disable,
|
||||
LVL_Local,
|
||||
LVL_Rtsps,
|
||||
LVL_Rtsp
|
||||
} liveview_local{ LVL_None };
|
||||
enum LiveviewRemote {
|
||||
LVR_None,
|
||||
LVR_Tutk,
|
||||
LVR_Agora,
|
||||
LVR_TutkAgora
|
||||
} liveview_remote{ LVR_None };
|
||||
enum FileLocal {
|
||||
FL_None,
|
||||
FL_Local
|
||||
} file_local{ FL_None };
|
||||
enum FileRemote {
|
||||
FR_None,
|
||||
FR_Tutk,
|
||||
FR_Agora,
|
||||
FR_TutkAgora
|
||||
} file_remote{ FR_None };
|
||||
LiveviewLocal liveview_local{ LiveviewLocal::LVL_None };
|
||||
LiveviewRemote liveview_remote{ LiveviewRemote::LVR_None};
|
||||
FileLocal file_local{ FileLocal::FL_None };
|
||||
FileRemote file_remote{ FileRemote::FR_None };
|
||||
|
||||
enum PlateMakerDectect : int
|
||||
{
|
||||
@@ -708,6 +690,8 @@ public:
|
||||
std::string subtask_id_;
|
||||
std::string job_id_;
|
||||
std::string last_subtask_id_;
|
||||
// note: printer-agent-supplied thumbnail url, empty when the agent supplies none.
|
||||
std::string m_agent_thumbnail_url;
|
||||
BBLSliceInfo* slice_info {nullptr};
|
||||
boost::thread* get_slice_info_thread { nullptr };
|
||||
boost::thread* get_model_task_thread { nullptr };
|
||||
@@ -765,6 +749,7 @@ public:
|
||||
int command_set_printer_nozzle(std::string nozzle_type, float diameter);
|
||||
int command_set_printer_nozzle2(int id, std::string nozzle_type, float diameter);
|
||||
int command_get_access_code();
|
||||
int command_start_camera();
|
||||
int command_ack_proceed(json& proceed);
|
||||
int command_purification_disable();
|
||||
int command_dont_remind_next_time(json& mqtt_guard_json);
|
||||
@@ -894,6 +879,7 @@ public:
|
||||
static bool is_in_printing_status(std::string status);
|
||||
|
||||
void set_print_state(std::string status);
|
||||
void update_print_progress(const json& value);
|
||||
|
||||
bool is_connected();
|
||||
bool is_connecting();
|
||||
@@ -961,6 +947,7 @@ public:
|
||||
/*for parse new info*/
|
||||
bool check_enable_np(const json& print) const;
|
||||
void parse_new_info(json print);
|
||||
void parse_new_info2(const json& info);
|
||||
int get_flag_bits(std::string str, int start, int count = 1) const;
|
||||
uint32_t get_flag_bits_no_border(std::string str, int start_idx, int count = 1) const;
|
||||
int get_flag_bits(int num, int start, int count = 1, int base = 10) const;
|
||||
@@ -989,7 +976,7 @@ public:
|
||||
void command_set_save_remote_print_file_to_storage(bool save);
|
||||
|
||||
private:
|
||||
|
||||
int command_with_dialog(int cmd_result);
|
||||
/* xcam door open check*/
|
||||
bool is_support_door_open_check = false;
|
||||
DoorOpenCheckState xcam_door_open_check = DoorOpenCheckState::DOOR_OPEN_CHECK_DISABLE;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "DockPanel.hpp"
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "Widgets/WebHosting.hpp"
|
||||
|
||||
#include <wx/weakref.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
std::string plugin_pane_name(const std::string& plugin_key, const std::string& title)
|
||||
{
|
||||
std::string name = "plugin:" + plugin_key + ":" + title;
|
||||
std::replace_if(name.begin(), name.end(), [](char c) { return c == '|' || c == ';' || c == '=' || c == '\\'; }, '_');
|
||||
return name;
|
||||
}
|
||||
|
||||
DockPanel::DockPanel(wxWindow* parent,
|
||||
const std::string& html,
|
||||
MessageHandler on_message,
|
||||
CloseHandler on_close,
|
||||
CloseHandler on_destroyed)
|
||||
: WebPanel(parent, web_hosting::orca_bridge_script())
|
||||
, m_html(html)
|
||||
, m_on_message(std::move(on_message))
|
||||
, m_on_close(std::move(on_close))
|
||||
, m_on_destroyed(std::move(on_destroyed))
|
||||
{
|
||||
// A link asking for a new window has nowhere to open from a docked panel.
|
||||
browser()->Bind(wxEVT_WEBVIEW_NEWWINDOW, [](wxWebViewEvent& event) { event.Veto(); });
|
||||
}
|
||||
|
||||
DockPanel::~DockPanel()
|
||||
{
|
||||
if (m_on_destroyed)
|
||||
m_on_destroyed();
|
||||
}
|
||||
|
||||
bool DockPanel::on_page_message(const std::string& kind, const nlohmann::json& data)
|
||||
{
|
||||
if (kind == "message") {
|
||||
if (m_on_message)
|
||||
m_on_message(data);
|
||||
return true;
|
||||
}
|
||||
if (kind == "close") {
|
||||
request_close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DockPanel::push_message(const nlohmann::json& data)
|
||||
{
|
||||
if (!m_closing)
|
||||
post_to_page(data.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace));
|
||||
}
|
||||
|
||||
void DockPanel::fire_close()
|
||||
{
|
||||
if (m_closing)
|
||||
return;
|
||||
m_closing = true;
|
||||
if (m_on_close) {
|
||||
CloseHandler on_close = std::move(m_on_close);
|
||||
m_on_close = nullptr;
|
||||
on_close();
|
||||
}
|
||||
}
|
||||
|
||||
void DockPanel::request_close()
|
||||
{
|
||||
if (m_closing)
|
||||
return;
|
||||
fire_close();
|
||||
// A page-requested close arrives inside the web view's script callback, so destroy later; another
|
||||
// close path may have destroyed the panel by then.
|
||||
wxWeakRef<DockPanel> self(this);
|
||||
CallAfter([self]() {
|
||||
if (self)
|
||||
self->remove_pane();
|
||||
});
|
||||
}
|
||||
|
||||
void DockPanel::destroy_silently()
|
||||
{
|
||||
m_closing = true;
|
||||
m_on_close = nullptr;
|
||||
remove_pane();
|
||||
}
|
||||
|
||||
void DockPanel::remove_pane()
|
||||
{
|
||||
if (Plater* plater = wxGetApp().plater())
|
||||
plater->remove_dock_pane(this);
|
||||
else
|
||||
Destroy();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "WebPanel.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
// Stable across sessions so the saved layout finds the pane; free of wxAuiManager layout delimiters.
|
||||
std::string plugin_pane_name(const std::string& plugin_key, const std::string& title);
|
||||
|
||||
// A WebPanel docked in the Plater, on the plugin-window bridge minus submit. It can be destroyed
|
||||
// without the GIL, so its hooks must not capture pybind11 objects.
|
||||
class DockPanel : public WebPanel
|
||||
{
|
||||
public:
|
||||
using MessageHandler = std::function<void(const nlohmann::json& data)>;
|
||||
using CloseHandler = std::function<void()>;
|
||||
|
||||
// on_close fires once, on a user or page close. on_destroyed runs on every destruction and must
|
||||
// touch host-side state only.
|
||||
DockPanel(wxWindow* parent,
|
||||
const std::string& html,
|
||||
MessageHandler on_message,
|
||||
CloseHandler on_close,
|
||||
CloseHandler on_destroyed);
|
||||
~DockPanel() override;
|
||||
|
||||
// Main thread only.
|
||||
void push_message(const nlohmann::json& data);
|
||||
// Fires on_close, then removes the pane.
|
||||
void request_close();
|
||||
// Removes the pane without on_close, for plugin unload. Destroys at once: unload always comes from
|
||||
// the host, never from this panel's own callbacks.
|
||||
void destroy_silently();
|
||||
// Fires on_close at most once; also run by the pane's own close button.
|
||||
void fire_close();
|
||||
|
||||
protected:
|
||||
std::optional<std::string> page_html() override { return m_html; }
|
||||
bool on_page_message(const std::string& kind, const nlohmann::json& data) override;
|
||||
|
||||
private:
|
||||
void remove_pane();
|
||||
|
||||
std::string m_html;
|
||||
bool m_closing{false};
|
||||
MessageHandler m_on_message;
|
||||
CloseHandler m_on_close;
|
||||
CloseHandler m_on_destroyed;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "slic3r/Utils/MacDarkMode.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
|
||||
#include <slic3r/GUI/GUI_Utils.hpp>
|
||||
|
||||
@@ -5027,16 +5026,8 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||
//BBS: nofity object list to update
|
||||
wxGetApp().plater()->sidebar().obj_list()->update_plate_values_for_items();
|
||||
|
||||
if (object_moved) {
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "moved";
|
||||
if (done.size() == 1)
|
||||
ctx.name = m_model->objects[done.begin()->first]->name;
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
|
||||
if (object_moved)
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED));
|
||||
}
|
||||
|
||||
// BBS: support wipe-tower for multi-plates
|
||||
for (int plate_id = 0; plate_id < wipe_tower_origins.size(); plate_id++) {
|
||||
@@ -5157,16 +5148,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||
//BBS: nofity object list to update
|
||||
wxGetApp().plater()->sidebar().obj_list()->update_plate_values_for_items();
|
||||
|
||||
if (!done.empty()) {
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "rotated";
|
||||
if (done.size() == 1)
|
||||
ctx.name = m_model->objects[done.begin()->first]->name;
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
|
||||
if (!done.empty())
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED));
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
@@ -5257,16 +5240,8 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
|
||||
//BBS: notify object info update
|
||||
wxGetApp().plater()->show_object_info();
|
||||
|
||||
if (!done.empty()) {
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "scaled";
|
||||
if (done.size() == 1)
|
||||
ctx.name = m_model->objects[done.begin()->first]->name;
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
|
||||
if (!done.empty())
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_SCALED));
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
+20
-57
@@ -4,6 +4,7 @@
|
||||
#include "libslic3r/Platform.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "Shortcuts.hpp"
|
||||
#include "DeviceCore/DevConfigUtil.h"
|
||||
#include "BindDialog.hpp"
|
||||
#include "DeviceManager.hpp"
|
||||
#include "HMS.hpp"
|
||||
@@ -24,7 +25,6 @@
|
||||
#include <boost/locale/encoding_utf.hpp>
|
||||
#include <boost/log/detail/native_typeof.hpp>
|
||||
#include <libslic3r/Config.hpp>
|
||||
#include <mutex>
|
||||
#include <slic3r/plugin/PythonPluginInterface.hpp>
|
||||
#include <wx/event.h>
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
#include <iterator>
|
||||
#include <exception>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
#include <thread>
|
||||
#include <string_view>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp>
|
||||
@@ -88,7 +90,6 @@
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "libslic3r/miniz_extension.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
#include "slic3r/plugin/host/PluginHostUi.hpp"
|
||||
#include "slic3r/plugin/PythonInterpreter.hpp"
|
||||
@@ -108,19 +109,18 @@
|
||||
#include "../Utils/PrintHost.hpp"
|
||||
#include "../Utils/Process.hpp"
|
||||
#include "../Utils/wxInspectorPlugins/Registration.hpp"
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
#include "../Utils/Http.hpp"
|
||||
#include "../Utils/InstanceID.hpp"
|
||||
#include "../Utils/UndoRedo.hpp"
|
||||
#include "slic3r/Config/Snapshot.hpp"
|
||||
#include "Preferences.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "SysInfoDialog.hpp"
|
||||
#include "UpdateDialogs.hpp"
|
||||
#include "Mouse3DController.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
#ifdef __APPLE__
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
#include "DeepLinkHandlerMac.h"
|
||||
#endif
|
||||
#include "NotificationManager.hpp"
|
||||
@@ -129,8 +129,6 @@
|
||||
#include "PrintHostDialogs.hpp"
|
||||
#include "NetworkPluginDialog.hpp"
|
||||
#include "DesktopIntegrationDialog.hpp"
|
||||
#include "SendSystemInfoDialog.hpp"
|
||||
#include "ParamsDialog.hpp"
|
||||
#include "KBShortcutsDialog.hpp"
|
||||
#include "DownloadProgressDialog.hpp"
|
||||
#include "TroubleshootDialog.hpp"
|
||||
@@ -141,7 +139,6 @@
|
||||
#include "Widgets/ProgressDialog.hpp"
|
||||
|
||||
//BBS: DailyTip and UserGuide Dialog
|
||||
#include "WebDownPluginDlg.hpp"
|
||||
#include "WebGuideDialog.hpp"
|
||||
#include "ReleaseNote.hpp"
|
||||
#include "PrivacyUpdateDialog.hpp"
|
||||
@@ -2182,11 +2179,6 @@ void GUI_App::init_networking_callbacks()
|
||||
obj->command_get_access_code();
|
||||
if (m_agent)
|
||||
m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
|
||||
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = obj->get_dev_id();
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceConnected, ctx);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2225,11 +2217,6 @@ void GUI_App::init_networking_callbacks()
|
||||
obj->command_get_version();
|
||||
event.SetInt(0);
|
||||
event.SetString(obj->get_dev_id());
|
||||
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = obj->get_dev_id();
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceConnected, ctx);
|
||||
} else if (state == ConnectStatus::ConnectStatusFailed) {
|
||||
// Orca: only update status if same device id
|
||||
if (m_device_manager->selected_machine != dev_id) return;
|
||||
@@ -2245,22 +2232,10 @@ void GUI_App::init_networking_callbacks()
|
||||
wxGetApp().show_dialog(text);
|
||||
}
|
||||
event.SetInt(-1);
|
||||
|
||||
{
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx);
|
||||
}
|
||||
} else if (state == ConnectStatus::ConnectStatusLost) {
|
||||
m_device_manager->set_selected_machine("");
|
||||
event.SetInt(-1);
|
||||
BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = lost";
|
||||
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = dev_id;
|
||||
ctx.code = LifecycleEvtCode::Ok;
|
||||
fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx);
|
||||
} else {
|
||||
event.SetInt(-1);
|
||||
BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = " << state;
|
||||
@@ -2410,14 +2385,8 @@ bool GUI_App::is_blocking_printing(MachineObject *obj_)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
std::string target_model;
|
||||
if (obj_ == nullptr) {
|
||||
obj_ = dev->get_selected_machine();
|
||||
if (obj_) {
|
||||
target_model = obj_->printer_type;
|
||||
}
|
||||
} else {
|
||||
target_model = obj_->printer_type;
|
||||
}
|
||||
|
||||
if (!obj_)
|
||||
@@ -2428,14 +2397,7 @@ bool GUI_App::is_blocking_printing(MachineObject *obj_)
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
std::string source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
|
||||
if (source_model != target_model) {
|
||||
std::vector<std::string> compatible_machine = obj_->get_compatible_machine();
|
||||
vector<std::string>::iterator it = find(compatible_machine.begin(), compatible_machine.end(), source_model);
|
||||
if (it == compatible_machine.end()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
|
||||
@@ -3990,20 +3952,16 @@ void GUI_App::set_live_printer_agent(std::shared_ptr<IPrinterAgent> agent)
|
||||
m_agent->set_user_selected_machine("");
|
||||
// note: belt-and-suspenders (precedent: DeviceManagerRefresher::on_timer)
|
||||
dev->OnSelectedMachineLost(); // why: clear stale sidebar sync-status / AMS
|
||||
// why: drop stale LAN discoveries; keep My Devices, but only those belonging to the
|
||||
// agent we're about to swap to, so a device stamped by the outgoing agent doesn't
|
||||
// linger hidden - the new agent's start_discovery re-inserts and re-stamps it fresh.
|
||||
// agent is null when clearing the live agent entirely (e.g. plugin unload); there's no
|
||||
// target to filter against then, so fall back to the original "keep all My Devices"
|
||||
// behavior rather than guessing.
|
||||
dev->clear_other_devices(agent ? agent->get_agent_info().id : std::string());
|
||||
// why: retain agent-owned LAN discoveries so agents without automatic discovery (for
|
||||
// example the Moonraker-based Qidi/Snapmaker agents) can reuse them after a switch.
|
||||
dev->clear_other_devices();
|
||||
}
|
||||
|
||||
m_agent->set_printer_agent(agent);
|
||||
sidebar().update_all_preset_comboboxes();
|
||||
}
|
||||
|
||||
std::string GUI_App::resolve_printer_agent_id(const std::string& stored_id)
|
||||
std::string GUI_App::resolve_printer_agent_id(const std::string& stored_id) const
|
||||
{
|
||||
if (!stored_id.empty())
|
||||
return stored_id;
|
||||
@@ -4039,6 +3997,7 @@ void GUI_App::switch_printer_agent()
|
||||
|
||||
std::string log_dir = data_dir();
|
||||
std::string cloud_agent_id = agent_info.id == BBL_PRINTER_AGENT_ID ? BBL_CLOUD_PROVIDER : ORCA_CLOUD_PROVIDER;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << agent_info.id;
|
||||
std::shared_ptr<ICloudServiceAgent> cloud_agent = m_agent->get_cloud_agent(cloud_agent_id);
|
||||
|
||||
// Create new printer agent via registry
|
||||
@@ -4052,8 +4011,10 @@ void GUI_App::switch_printer_agent()
|
||||
return;
|
||||
}
|
||||
|
||||
// The factory caches agents per ID, so an identical pointer means the agent type is unchanged.
|
||||
if (m_agent->get_printer_agent() == new_printer_agent) {
|
||||
// Compare the registered IDs, not only the implementation pointer. Different registry IDs
|
||||
// may intentionally be backed by the same implementation object (especially for plugins).
|
||||
const auto current_printer_agent = m_agent->get_printer_agent();
|
||||
if (current_printer_agent && current_printer_agent->get_agent_info().id == effective_agent_id) {
|
||||
// Orca: the agent type is unchanged (e.g. switching between two Moonraker/Klipper
|
||||
// printer presets), so the selected machine and the agent's cached device_info still
|
||||
// point at the previously active printer preset. Re-select the machine when the new
|
||||
@@ -5034,14 +4995,16 @@ bool GUI_App::is_user_login(const std::string& provider/* = ORCA_CLOUD_PROVIDER*
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& GUI_App::get_printer_cloud_provider() const
|
||||
std::string GUI_App::get_printer_cloud_provider() const
|
||||
{
|
||||
// Orca todo: this need to be revisted. currently it is mainly used for device manager and related clausses and only bambu machines use them.
|
||||
//
|
||||
return BBL_CLOUD_PROVIDER;
|
||||
const std::string agent_id = resolve_printer_agent_id(
|
||||
preset_bundle ? preset_bundle->printers.get_edited_preset().config.opt_string("printer_agent")
|
||||
: std::string());
|
||||
return agent_id == BBL_PRINTER_AGENT_ID ? BBL_CLOUD_PROVIDER : ORCA_CLOUD_PROVIDER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GUI_App::check_login(const std::string& provider/* = ORCA_CLOUD_PROVIDER*/)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <wx/snglinst.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <stack>
|
||||
|
||||
//#define BBL_HAS_FIRST_PAGE 1
|
||||
#define STUDIO_INACTIVE_TIMEOUT 15*60*1000
|
||||
#define LOG_FILES_MAX_NUM 30
|
||||
@@ -378,7 +375,7 @@ public:
|
||||
// Reconcile the live printer agent with the stored preset selection.
|
||||
void switch_printer_agent();
|
||||
|
||||
std::string resolve_printer_agent_id(const std::string& stored_id);
|
||||
std::string resolve_printer_agent_id(const std::string& stored_id) const;
|
||||
// ORCA TODO: in the future, bbl presets should specify "bbl" printer agent id
|
||||
// then, all resolve and canonical would just be ORCA<->""
|
||||
std::string canonical_printer_agent_id(const std::string& picked_id);
|
||||
@@ -504,7 +501,7 @@ public:
|
||||
bool check_login(const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
void get_login_info(const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
bool is_user_login(const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
const std::string& get_printer_cloud_provider() const;
|
||||
std::string get_printer_cloud_provider() const;
|
||||
|
||||
void request_user_login(int online_login = 0, const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
void request_user_handle(int online_login = 0, const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/LifecycleEvents.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GUI_Factories.hpp"
|
||||
//#include "GUI_ObjectLayers.hpp"
|
||||
@@ -11,7 +10,6 @@
|
||||
#include "BitmapComboBox.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
|
||||
#include "OptionsGroup.hpp"
|
||||
#include "Tab.hpp"
|
||||
@@ -1161,39 +1159,17 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const
|
||||
if (m_objects_model->GetItemType(item) & itObject) {
|
||||
std::string name = m_objects_model->GetName(item).ToUTF8().data();
|
||||
if (obj->name != name) {
|
||||
const std::string previous_name = obj->name;
|
||||
obj->name = name;
|
||||
// if object has just one volume, rename this volume too
|
||||
if (obj->volumes.size() == 1)
|
||||
obj->volumes[0]->name = obj->name;
|
||||
Slic3r::save_object_mesh(*obj);
|
||||
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = name;
|
||||
ctx.previous_name = previous_name;
|
||||
ctx.id = std::to_string(obj->id().id);
|
||||
ctx.index = obj_idx;
|
||||
ctx.source = "object";
|
||||
fire_lifecycle_event(LifecycleEvent::ObjectRenamed, ctx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (volume_id < 0) return;
|
||||
std::string name = m_objects_model->GetName(item).ToUTF8().data();
|
||||
if (obj->volumes[volume_id]->name == name)
|
||||
return;
|
||||
|
||||
const std::string previous_name = obj->volumes[volume_id]->name;
|
||||
obj->volumes[volume_id]->name = name;
|
||||
|
||||
LifecycleEventContext ctx;
|
||||
ctx.name = name;
|
||||
ctx.previous_name = previous_name;
|
||||
ctx.id = std::to_string(obj->volumes[volume_id]->id().id);
|
||||
ctx.index = volume_id;
|
||||
ctx.source = "volume";
|
||||
fire_lifecycle_event(LifecycleEvent::ObjectRenamed, ctx);
|
||||
obj->volumes[volume_id]->name = m_objects_model->GetName(item).ToUTF8().data();
|
||||
}
|
||||
|
||||
void ObjectList::update_name_in_list(int obj_idx, int vol_idx) const
|
||||
@@ -3543,14 +3519,7 @@ void ObjectList::delete_all_connectors_for_object(int obj_idx)
|
||||
obj->delete_connectors();
|
||||
|
||||
if (obj->volumes.empty() || !obj->has_solid_mesh()) {
|
||||
const std::string deleted_obj_name = obj->name;
|
||||
model.delete_object(idx);
|
||||
{
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.name = deleted_obj_name;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectDeleted, ctx);
|
||||
}
|
||||
m_objects_model->Delete(m_objects_model->GetItemById(idx));
|
||||
continue;
|
||||
}
|
||||
@@ -4119,13 +4088,6 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed,
|
||||
const auto item = m_objects_model->AddObject(model_object, warning_bitmap, model_object->is_cut());
|
||||
Expand(m_objects_model->GetParent(item));
|
||||
|
||||
{
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.name = model_object->name;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectAdded, ctx);
|
||||
}
|
||||
|
||||
if (!do_info_update)
|
||||
return;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/uri.h>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class IMediaController
|
||||
{
|
||||
public:
|
||||
virtual ~IMediaController() = default;
|
||||
|
||||
virtual void Load(wxURI url) = 0;
|
||||
|
||||
virtual void Play() = 0;
|
||||
|
||||
virtual void Stop() = 0;
|
||||
|
||||
virtual wxMediaState GetState() { return wxMediaState{}; }
|
||||
|
||||
virtual int GetLastError() const { return {}; };
|
||||
|
||||
virtual wxSize GetVideoSize() const { return {}; };
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
|
||||
#include "libnest2d/common.hpp"
|
||||
|
||||
@@ -699,13 +698,6 @@ void ArrangeJob::finalize(bool canceled, std::exception_ptr &eptr) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange m_unprintable: name: %4%, bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) % ap.name;
|
||||
}
|
||||
|
||||
{
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "arranged";
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
}
|
||||
|
||||
m_plater->update();
|
||||
// BBS
|
||||
//wxGetApp().obj_manipul()->set_dirty();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
#include "libnest2d/common.hpp"
|
||||
|
||||
#include <numeric>
|
||||
@@ -348,13 +347,6 @@ void FillBedJob::finalize(bool canceled, std::exception_ptr &eptr)
|
||||
m_plater->arrange();
|
||||
}
|
||||
m_plater->update();
|
||||
|
||||
{
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "arranged";
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
m_plater->mark_plate_toolbar_image_dirty();
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
|
||||
|
||||
@@ -255,12 +254,6 @@ void OrientJob::finalize(bool canceled, std::exception_ptr &eptr)
|
||||
mesh.apply();
|
||||
}
|
||||
|
||||
if (!m_selected.empty()) {
|
||||
Slic3r::LifecycleEventContext ctx;
|
||||
ctx.code = Slic3r::LifecycleEvtCode::Ok;
|
||||
ctx.msg = "auto_oriented";
|
||||
Slic3r::fire_lifecycle_event(Slic3r::LifecycleEvent::ObjectTransformed, ctx);
|
||||
}
|
||||
|
||||
m_plater->update();
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "PrintJob.hpp"
|
||||
#include "libslic3r/LifecycleEvents.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
@@ -15,6 +14,7 @@
|
||||
|
||||
#include "slic3r/Utils/FileTransferUtils.hpp"
|
||||
#include "slic3r/Utils/BBLNetworkPlugin.hpp"
|
||||
#include "NetworkAgent.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
@@ -134,13 +134,6 @@ wxString PrintJob::get_http_error_msg(unsigned int status, std::string body)
|
||||
|
||||
void PrintJob::process(Ctl &ctl)
|
||||
{
|
||||
LifecycleEventContext start_ctx;
|
||||
start_ctx.name = m_project_name;
|
||||
start_ctx.device_id = m_dev_id;
|
||||
start_ctx.source = "print_job";
|
||||
fire_lifecycle_event(LifecycleEvent::PrintJobStarted, start_ctx);
|
||||
m_lifecycle_started = true;
|
||||
|
||||
/* display info */
|
||||
std::string msg;
|
||||
int curr_percent = 10;
|
||||
@@ -211,7 +204,7 @@ void PrintJob::process(Ctl &ctl)
|
||||
params.dev_ip = m_dev_ip;
|
||||
params.use_ssl_for_ftp = m_local_use_ssl_for_ftp;
|
||||
params.use_ssl_for_mqtt = m_local_use_ssl;
|
||||
params.username = "bblp";
|
||||
params.username = m_agent->default_lan_username();
|
||||
params.password = m_access_code;
|
||||
|
||||
// check access code and ip address
|
||||
@@ -694,7 +687,6 @@ void PrintJob::process(Ctl &ctl)
|
||||
}
|
||||
wxQueueEvent(m_plater, evt);
|
||||
m_job_finished = true;
|
||||
m_lifecycle_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,19 +699,6 @@ void PrintJob::finalize(bool canceled, std::exception_ptr &eptr) {
|
||||
eptr = std::current_exception();
|
||||
}
|
||||
|
||||
if (m_lifecycle_started && !m_lifecycle_finished) {
|
||||
LifecycleEventContext finish_ctx;
|
||||
finish_ctx.name = m_project_name;
|
||||
finish_ctx.device_id = m_dev_id;
|
||||
finish_ctx.source = "print_job";
|
||||
finish_ctx.code = canceled ? LifecycleEvtCode::Warn :
|
||||
(eptr || !m_lifecycle_success ? LifecycleEvtCode::Error : LifecycleEvtCode::Ok);
|
||||
finish_ctx.msg = canceled ? "cancelled" : (eptr ? "exception" :
|
||||
(m_lifecycle_success ? "" : "failed"));
|
||||
fire_lifecycle_event(LifecycleEvent::PrintJobFinished, finish_ctx);
|
||||
m_lifecycle_finished = true;
|
||||
}
|
||||
|
||||
if (canceled || eptr)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,9 +43,6 @@ class PrintJob : public Job
|
||||
std::function<void()> m_success_fun{nullptr};
|
||||
std::string m_dev_id;
|
||||
bool m_job_finished{ false };
|
||||
bool m_lifecycle_started{ false };
|
||||
bool m_lifecycle_finished{ false };
|
||||
bool m_lifecycle_success{ false };
|
||||
int m_print_job_completed_id = 0;
|
||||
wxString m_completed_evt_data;
|
||||
std::function<void()> m_enter_ip_address_fun_fail{ nullptr };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "SendJob.hpp"
|
||||
#include "libslic3r/LifecycleEvents.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
@@ -127,7 +126,7 @@ void SendJob::process(Ctl &ctl)
|
||||
if (m_is_check_mode) {
|
||||
PrintParams verify_params;
|
||||
verify_params.dev_ip = m_dev_ip;
|
||||
verify_params.username = "bblp";
|
||||
verify_params.username = agent->default_lan_username();
|
||||
verify_params.password = m_access_code;
|
||||
verify_params.use_ssl_for_ftp = m_local_use_ssl_for_ftp;
|
||||
verify_params.use_ssl_for_mqtt = m_local_use_ssl;
|
||||
@@ -149,13 +148,6 @@ void SendJob::process(Ctl &ctl)
|
||||
}
|
||||
}
|
||||
|
||||
LifecycleEventContext start_ctx;
|
||||
start_ctx.name = m_project_name;
|
||||
start_ctx.device_id = m_dev_id;
|
||||
start_ctx.source = "send_job";
|
||||
fire_lifecycle_event(LifecycleEvent::SendJobStarted, start_ctx);
|
||||
m_lifecycle_started = true;
|
||||
|
||||
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
|
||||
|
||||
PartPlate* plate = m_plater->get_partplate_list().get_plate(job_data.plate_idx);
|
||||
@@ -219,7 +211,7 @@ void SendJob::process(Ctl &ctl)
|
||||
|
||||
// local print access
|
||||
params.dev_ip = m_dev_ip;
|
||||
params.username = "bblp";
|
||||
params.username = agent->default_lan_username();
|
||||
params.password = m_access_code;
|
||||
params.use_ssl_for_ftp = m_local_use_ssl_for_ftp;
|
||||
params.use_ssl_for_mqtt = m_local_use_ssl;
|
||||
@@ -432,19 +424,6 @@ void SendJob::finalize(bool canceled, std::exception_ptr &eptr)
|
||||
eptr = std::current_exception();
|
||||
}
|
||||
|
||||
if (m_lifecycle_started && !m_lifecycle_finished) {
|
||||
LifecycleEventContext finish_ctx;
|
||||
finish_ctx.name = m_project_name;
|
||||
finish_ctx.device_id = m_dev_id;
|
||||
finish_ctx.source = "send_job";
|
||||
finish_ctx.code = canceled ? LifecycleEvtCode::Warn :
|
||||
(eptr ? LifecycleEvtCode::Error : (m_job_finished ? LifecycleEvtCode::Ok : LifecycleEvtCode::Error));
|
||||
finish_ctx.msg = canceled ? "cancelled" : (eptr ? "exception" :
|
||||
(m_job_finished ? "" : "failed"));
|
||||
fire_lifecycle_event(LifecycleEvent::SendJobFinished, finish_ctx);
|
||||
m_lifecycle_finished = true;
|
||||
}
|
||||
|
||||
if (canceled || eptr)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ class SendJob : public Job
|
||||
PrintPrepareData job_data;
|
||||
std::string m_dev_id;
|
||||
bool m_job_finished{ false };
|
||||
bool m_lifecycle_started{ false };
|
||||
bool m_lifecycle_finished{ false };
|
||||
int m_print_job_completed_id = 0;
|
||||
bool m_is_check_mode{false};
|
||||
bool m_check_and_continue{false};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user