diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml index 9927f5bef6..4e01051073 100644 --- a/.github/workflows/build_deps.yml +++ b/.github/workflows/build_deps.yml @@ -149,7 +149,7 @@ jobs: working-directory: ${{ github.workspace }} run: | if [ -z "${{ vars.SELF_HOSTED }}" ]; then - brew install automake texinfo libtool + brew install automake texinfo libtool pkgconf yasm nasm fi ./build_release_macos.sh -dx ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 (cd "${{ github.workspace }}/deps/build/${{ inputs.arch }}" && \ diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index 112c0b279b..e8dcef0b05 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -385,6 +385,13 @@ jobs: dir "C:/Program Files (x86)/Windows Kits/10/Include" choco install nsis + - name: Install pkg-config + # FFmpeg is discovered via pkg-config (pkg_check_modules LIBAV in + # src/slic3r/CMakeLists.txt); the Windows runners don't ship it. + if: runner.os == 'Windows' && !vars.SELF_HOSTED + run: | + choco install pkgconfiglite -y + - name: Build slicer Win if: runner.os == 'Windows' working-directory: ${{ github.workspace }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f0db669b8..c912cdd08f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,6 +298,8 @@ if (APPLE) SET(CMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.orcaslicer.OrcaSlicer") message(STATUS "Orca: IS_CROSS_COMPILE: ${IS_CROSS_COMPILE}") +elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_INSTALL_RPATH "$ORIGIN") endif () # Proposal for C++ unit tests and sandboxes @@ -474,7 +476,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory. # We pick it from environment if it is not defined in another way # ORCA: Removed Netfabb STL fixing service support in favor of CGAL. -# if(WIN32) +if(WIN32) + find_package(PkgConfig REQUIRED) # if(NOT DEFINED WIN10SDK_PATH) # if(DEFINED ENV{WIN10SDK_PATH}) # set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}") @@ -510,7 +513,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # else() # message("Building without Win10 Netfabb STL fixing service support") # endif() -# endif() +endif() if (APPLE) message("OS X SDK Path: ${CMAKE_OSX_SYSROOT}") @@ -1065,6 +1068,10 @@ function(orcaslicer_copy_dlls target config postfix output_dlls) ${CMAKE_PREFIX_PATH}/bin/occt/TKXDESTEP.dll ${CMAKE_PREFIX_PATH}/bin/occt/TKXSBase.dll ${CMAKE_PREFIX_PATH}/bin/freetype.dll + ${CMAKE_PREFIX_PATH}/bin/avcodec-61.dll + ${CMAKE_PREFIX_PATH}/bin/swresample-5.dll + ${CMAKE_PREFIX_PATH}/bin/swscale-8.dll + ${CMAKE_PREFIX_PATH}/bin/avutil-59.dll DESTINATION ${_out_dir}) set(${output_dlls} @@ -1100,12 +1107,58 @@ function(orcaslicer_copy_dlls target config postfix output_dlls) ${_out_dir}/TKXSBase.dll ${_out_dir}/freetype.dll - + ${_out_dir}/avcodec-61.dll + ${_out_dir}/swresample-5.dll + ${_out_dir}/swscale-8.dll + ${_out_dir}/avutil-59.dll PARENT_SCOPE ) endfunction() +function(orcaslicer_copy_sos target config postfix output_sos) + + get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + get_target_property(_alt_out_dir ${target} RUNTIME_OUTPUT_DIRECTORY) + + if (_alt_out_dir) + set(_out_dir "${_alt_out_dir}") + elseif (_is_multi) + set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}/${config}") + else () + set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}") + endif () + + file(COPY ${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 + ${CMAKE_PREFIX_PATH}/lib/libavutil.so.59 + ${CMAKE_PREFIX_PATH}/lib/libavutil.so.59.8.100 + ${CMAKE_PREFIX_PATH}/lib/libswscale.so + ${CMAKE_PREFIX_PATH}/lib/libswscale.so.8 + ${CMAKE_PREFIX_PATH}/lib/libswscale.so.8.1.100 + ${CMAKE_PREFIX_PATH}/lib/libswresample.so + ${CMAKE_PREFIX_PATH}/lib/libswresample.so.5 + ${CMAKE_PREFIX_PATH}/lib/libswresample.so.5.1.100 + DESTINATION ${_out_dir}) + + set(${output_sos} + ${_out_dir}/libavcodec.so + ${_out_dir}/libavcodec.so.61 + ${_out_dir}/libavcodec.so.61.3.100 + ${_out_dir}/libavutil.so + ${_out_dir}/libavutil.so.59 + ${_out_dir}/libavutil.so.59.8.100 + ${_out_dir}/libswscale.so + ${_out_dir}/libswscale.so.8 + ${_out_dir}/libswscale.so.8.1.100 + ${_out_dir}/libswresample.so + ${_out_dir}/libswresample.so.5 + ${_out_dir}/libswresample.so.5.1.100 + PARENT_SCOPE + ) +endfunction() # Bundled sources set their own warning flags, and a plain -Wall there means /Wall # (= -Weverything) under clang-cl. Target options are applied after the ones a target @@ -1217,6 +1270,20 @@ else () endif() endif () +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(LIBRARY_FILES + ${LIBDIR_BIN}/libavcodec.so.61 + ${LIBDIR_BIN}/libavcodec.so.61.3.100 + ${LIBDIR_BIN}/libavutil.so.59 + ${LIBDIR_BIN}/libavutil.so.59.8.100 + ${LIBDIR_BIN}/libswresample.so.5 + ${LIBDIR_BIN}/libswresample.so.5.1.100 + ${LIBDIR_BIN}/libswscale.so.8 + ${LIBDIR_BIN}/libswscale.so.8.1.100 + ) + install(FILES ${LIBRARY_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") +endif () + install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.txt DESTINATION ".") configure_file(${LIBDIR}/dev-utils/platform/unix/fhs.hpp.in ${LIBDIR_BIN}/dev-utils/platform/unix/fhs.hpp) diff --git a/build_release_vs.bat b/build_release_vs.bat index 78419dadf5..a52d940455 100644 --- a/build_release_vs.bat +++ b/build_release_vs.bat @@ -20,6 +20,18 @@ for %%a in (%*) do ( if "%%a"=="-x" set USE_NINJA=1 ) +@REM Check for clang-cl option (-l). Combined with -x it also builds the deps with +@REM clang-cl; on the Visual Studio generator it applies to the slicer only, because +@REM the dependency sub-builds have no toolset to inherit and stay on MSVC. +set CLANG_ARG= +set TOOLSET_ARG= +for %%a in (%*) do ( + if "%%a"=="-l" ( + set CLANG_ARG=-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl + set TOOLSET_ARG=-T ClangCL + ) +) + @REM Check for unit-tests option ("tests") set BUILD_TESTS=OFF for %%a in (%*) do ( @@ -127,12 +139,13 @@ if "%1"=="slicer" ( GOTO :slicer ) echo "building deps.." +if defined CLANG_ARG if "%USE_NINJA%"=="0" echo Note: -l needs -x for the dependencies; building them with MSVC. echo on REM Set minimum CMake policy to avoid <3.5 errors set CMAKE_POLICY_VERSION_MINIMUM=3.5 if "%USE_NINJA%"=="1" ( - cmake ../ -G %CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=%build_type% + cmake ../ -G %CMAKE_GENERATOR% %CLANG_ARG% -DCMAKE_BUILD_TYPE=%build_type% cmake --build . --config %build_type% --target deps ) else ( cmake ../ -G %CMAKE_GENERATOR% -A %arch% -DCMAKE_BUILD_TYPE=%build_type% @@ -151,10 +164,10 @@ cd %build_dir% echo on set CMAKE_POLICY_VERSION_MINIMUM=3.5 if "%USE_NINJA%"=="1" ( - cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% + cmake .. -G %CMAKE_GENERATOR% %CLANG_ARG% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% cmake --build . --config %build_type% --target all ) else ( - cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% + cmake .. -G %CMAKE_GENERATOR% -A %arch% %TOOLSET_ARG% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% cmake --build . --config %build_type% --target ALL_BUILD -- -m ) @echo off diff --git a/deps/Assimp/Assimp.cmake b/deps/Assimp/Assimp.cmake index 8b4de03b09..9b973a55d5 100644 --- a/deps/Assimp/Assimp.cmake +++ b/deps/Assimp/Assimp.cmake @@ -21,6 +21,9 @@ orcaslicer_add_cmake_project(Assimp URL ${_assimp_url} URL_HASH ${_assimp_hash} CMAKE_ARGS + # Assimp's ccache support sets the global RULE_LAUNCH_COMPILE, which breaks + # the Ninja RC rule. The superbuild forwards CMAKE__COMPILER_LAUNCHER. + -DASSIMP_BUILD_USE_CCACHE=OFF -DASSIMP_BUILD_TESTS=OFF -DASSIMP_BUILD_SAMPLES=OFF -DASSIMP_BUILD_ASSIMP_TOOLS=OFF diff --git a/deps/Boost/Boost.cmake b/deps/Boost/Boost.cmake index bdd801857e..08b62b9fb8 100644 --- a/deps/Boost/Boost.cmake +++ b/deps/Boost/Boost.cmake @@ -24,6 +24,13 @@ if (MSVC AND DEP_DEBUG) set(_options "FORWARD_CONFIG") endif () +# Boost.Container's bundled dlmalloc passes int* where the Win32 Interlocked API +# takes volatile long*; cl compiles that with a warning, clang errors out. +set(_boost_c_flags_line "") +if (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(_boost_c_flags_line "-DCMAKE_C_FLAGS:STRING=-Wno-incompatible-pointer-types") +endif () + orcaslicer_add_cmake_project(Boost ${_options} URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz" @@ -38,6 +45,7 @@ orcaslicer_add_cmake_project(Boost "${_context_abi_line}" "${_context_arch_line}" "${_context_impl_line}" + "${_boost_c_flags_line}" ) -set(DEP_Boost_DEPENDS ZLIB) \ No newline at end of file +set(DEP_Boost_DEPENDS ZLIB) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 8f4bc2a215..ed3af70d03 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -157,8 +157,16 @@ endif () function(orcaslicer_add_cmake_project projectname) cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "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 + # it the CMAKE_C_COMPILER / CMAKE_CXX_COMPILER forwarded below. + set(_dep_msvc_gen FALSE) + if (MSVC AND CMAKE_GENERATOR MATCHES "Visual Studio") + set(_dep_msvc_gen TRUE) + endif () + set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}) - if (_is_multi OR MSVC) + if (_is_multi OR _dep_msvc_gen) if (P_ARGS_FORWARD_CONFIG) set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}) elseif (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG) @@ -174,7 +182,7 @@ function(orcaslicer_add_cmake_project projectname) set(_target_config "Release") endif() - if (MSVC) + if (_dep_msvc_gen) set(_gen CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}") else() set(_gen "") @@ -182,7 +190,7 @@ function(orcaslicer_add_cmake_project projectname) if ($ENV{CMAKE_BUILD_PARALLEL_LEVEL}) set(_build_j "") # assume environment will control --build parallel setting - elseif(MSVC) + elseif(_dep_msvc_gen) set(_build_j "/m") else() set(_build_j "-j${NPROC}") @@ -367,7 +375,7 @@ include(libnoise/libnoise.cmake) include(Draco/Draco.cmake) -# Assimp: glTF/GLB/FBX import for the texture-to-color feature. +include(FFMPEG/FFMPEG.cmake) include(Assimp/Assimp.cmake) @@ -451,6 +459,7 @@ set(_dep_list dep_libnoise dep_python3 dep_wxInspector + dep_FFMPEG dep_Assimp ) diff --git a/deps/CURL/CURL.cmake b/deps/CURL/CURL.cmake index a5ae1b9d00..3d649dfdea 100644 --- a/deps/CURL/CURL.cmake +++ b/deps/CURL/CURL.cmake @@ -56,6 +56,18 @@ else() set(_curl_static ON) endif() +# curl 7.75's configure probes and code rely on C laxness cl allows but clang +# errors on (implicit function declarations, int* vs u_long* in ioctlsocket), +# which flips probe results and misconfigures nonblock.c into the AmigaOS +# IoctlSocket branch. Relax both diagnostics so the probes behave like cl, and +# pin the camel-case probes off since they only "pass" by implicit declaration. +set(_curl_c_flags_line "") +set(_curl_probe_overrides "") +if (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(_curl_c_flags_line "-DCMAKE_C_FLAGS:STRING=-Wno-implicit-function-declaration -Wno-incompatible-pointer-types") + set(_curl_probe_overrides -DHAVE_IOCTLSOCKET_CAMEL=0 -DHAVE_IOCTLSOCKET_CAMEL_FIONBIO=0) +endif () + orcaslicer_add_cmake_project(CURL # GIT_REPOSITORY https://github.com/curl/curl.git # GIT_TAG curl-7_75_0 @@ -69,6 +81,8 @@ orcaslicer_add_cmake_project(CURL -DBUILD_CURL_EXE:BOOL=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCURL_STATICLIB=${_curl_static} + "${_curl_c_flags_line}" + ${_curl_probe_overrides} ${_curl_platform_flags} ) diff --git a/deps/Eigen/Eigen.cmake b/deps/Eigen/Eigen.cmake index 599976debb..2a9cc7105c 100644 --- a/deps/Eigen/Eigen.cmake +++ b/deps/Eigen/Eigen.cmake @@ -7,5 +7,20 @@ orcaslicer_add_cmake_project(Eigen URL https://gitlab.com/libeigen/eigen/-/archive/5.0.1/eigen-5.0.1.zip URL_HASH SHA256=0dbb1f9e3aaad66f352c03227d8c983f6f0b49e0b07e71a7300f4abcc01aee12 CMAKE_ARGS "${_eigen_extra_flags}" + # Only the headers are consumed here. Everything below builds nothing we + # use, and all three enable_language(Fortran): test/CMakeLists.txt:9, + # lapack/CMakeLists.txt:6 and blas/testing/CMakeLists.txt:2. They default + # to ON because the dependency configures as its own top-level project. + # + # Whether that probe is harmless depends on what CMake finds. The Visual + # Studio generator supports no Fortran, so it finds nothing; clang-cl sits + # next to the LLVM toolset's flang, which works. MSVC with Ninja finds + # Strawberry Perl's MinGW gfortran instead, which the deps build already + # requires for OpenSSL, and hands it the MSVC-style /machine:x64 that + # MinGW's ld reads as a missing input file. The configure dies there and + # takes the rest of the superbuild with it. + -DEIGEN_BUILD_TESTING=OFF + -DEIGEN_BUILD_BLAS=OFF + -DEIGEN_BUILD_LAPACK=OFF DEPENDS dep_Boost dep_GMP dep_MPFR ) diff --git a/deps/FFMPEG/FFMPEG.cmake b/deps/FFMPEG/FFMPEG.cmake new file mode 100644 index 0000000000..38e952bbdd --- /dev/null +++ b/deps/FFMPEG/FFMPEG.cmake @@ -0,0 +1,87 @@ +set(_conf_cmd ./configure) + +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") + + ExternalProject_Add(dep_FFMPEG + URL ${PREBUILD_URL_${DEPS_ARCH}} + URL_HASH SHA256=${PREBUILD_HASH_${DEPS_ARCH}} + DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND + COMMAND ${CMAKE_COMMAND} -E copy_directory "${_source_dir}/bin" "${DESTDIR}/bin" + COMMAND ${CMAKE_COMMAND} -E copy_directory "${_source_dir}/lib" "${DESTDIR}/lib" + COMMAND ${CMAKE_COMMAND} -E copy_directory "${_source_dir}/include" "${DESTDIR}/include" + ) + +else () + if (APPLE) + set(_minos_cmd + "--extra-cflags=-mmacosx-version-min=${DEP_OSX_TARGET}" + "--extra-ldflags=-mmacosx-version-min=${DEP_OSX_TARGET}" + ) + # Static FFmpeg: nothing to bundle into the .app, no rpath handling. + # Disable the VideoToolbox/AudioToolbox HW-accel paths: the player decodes + # in software (swscale), and the auto-detected HW objects would drag in + # system frameworks that the static libs would then depend on. + set(_link_cmd --enable-static --disable-shared --disable-videotoolbox --disable-audiotoolbox) + if (IS_CROSS_COMPILE) + set(_cross_cmd --enable-cross-compile) + set(_pic_cmd --enable-pic) + if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64") + set(_arch_cmd --arch=arm64) + set(_cc_cmd "--cc=clang -arch arm64") + else() + set(_arch_cmd --arch=x86_64) + set(_cc_cmd "--cc=clang -arch x86_64") + endif() + endif() + else () + set(_link_cmd --enable-shared) + endif () + + set(_build_j -j) + if(DEFINED ENV{CMAKE_BUILD_PARALLEL_LEVEL}) + set(_build_j "-j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}") + endif() + + ExternalProject_Add(dep_FFMPEG + 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} + ${_cross_cmd} + ${_pic_cmd} + ${_arch_cmd} + ${_cc_cmd} + "--prefix=${DESTDIR}" + ${_link_cmd} + ${_minos_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 + --disable-muxers + --enable-muxer=rtp + --disable-encoders + --disable-decoders + --enable-decoder=*aac*,h264*,mp3*,mjpeg,rv* + --disable-demuxers + --enable-demuxer=h264,mp3,mov + --disable-zlib + --disable-avdevice + BUILD_IN_SOURCE ON + BUILD_COMMAND make ${_build_j} + INSTALL_COMMAND make install + ) + +endif() diff --git a/deps/OCCT/0001-OCCT-fix.patch b/deps/OCCT/0001-OCCT-fix.patch index 27f5db7e0f..d251cc7ab6 100644 --- a/deps/OCCT/0001-OCCT-fix.patch +++ b/deps/OCCT/0001-OCCT-fix.patch @@ -1,3 +1,20 @@ +diff --git a/adm/cmake/occt_defs_flags.cmake b/adm/cmake/occt_defs_flags.cmake +index 00000000..00000001 100644 +--- a/adm/cmake/occt_defs_flags.cmake ++++ b/adm/cmake/occt_defs_flags.cmake +@@ -134,7 +134,11 @@ + set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}") + endif() + # Optimize size of binaries +- set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-s ${CMAKE_SHARED_LINKER_FLAGS}") ++ # clang-cl reports the Clang compiler ID, and OCCT builds shared on Windows, ++ # where the MSVC-style linker gets this flag as an argument it does not know. ++ if (NOT WIN32) ++ set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-s ${CMAKE_SHARED_LINKER_FLAGS}") ++ endif() + elseif(MINGW) + add_definitions(-D_WIN32_WINNT=0x0601) + # _WIN32_WINNT=0x0601 (use Windows 7 SDK) diff --git a/CMakeLists.txt b/CMakeLists.txt index d98acc0f..28eb8eb4 100644 --- a/CMakeLists.txt @@ -168,6 +185,32 @@ index d98acc0f..28eb8eb4 100644 endforeach() if (BUILD_SAMPLES_QT) +diff --git a/adm/cmake/occt_macros.cmake b/adm/cmake/occt_macros.cmake +index 224c96b1..8c94a1c5 100644 +--- a/adm/cmake/occt_macros.cmake ++++ b/adm/cmake/occt_macros.cmake +@@ -608,7 +608,7 @@ macro (OCCT_INSERT_CODE_FOR_TARGET) + install(CODE "if (\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$\") + set (OCCT_INSTALL_BIN_LETTER \"\") + elseif (\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Rr][Ee][Ll][Ww][Ii][Tt][Hh][Dd][Ee][Bb][Ii][Nn][Ff][Oo])$\") +- set (OCCT_INSTALL_BIN_LETTER \"i\") ++ set (OCCT_INSTALL_BIN_LETTER \"\") + elseif (\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Dd][Ee][Bb][Uu][Gg])$\") + set (OCCT_INSTALL_BIN_LETTER \"d\") + endif()") +diff --git a/adm/cmake/occt_toolkit.cmake b/adm/cmake/occt_toolkit.cmake +index 550e0e2f..7ac1a3b8 100644 +--- a/adm/cmake/occt_toolkit.cmake ++++ b/adm/cmake/occt_toolkit.cmake +@@ -241,7 +241,7 @@ + else() + set (aReleasePdbConf) + endif() +- install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/bin\${OCCT_INSTALL_BIN_LETTER}/${PROJECT_NAME}.pdb ++ install (FILES $ + CONFIGURATIONS Debug ${aReleasePdbConf} RelWithDebInfo + DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}") + endif() diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx index 5ae9899f..0a17372b 100644 --- a/src/Font/Font_FTFont.cxx diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index e43997265b..ddeb680052 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -17,10 +17,20 @@ else() endif() if(WIN32) - set(_conf_cmd perl Configure ) + set(_openssl_msvc_env CC=cl CXX=cl RC=rc CL=/FS) + # OpenSSL's perl Configure honors the CC environment variable, but the + # VC-WIN64A makefile only works with cl (an unquoted clang-cl path with + # spaces, e.g. exported by CLion, silently produces no .obj files and the + # lib step fails with LNK1181). Pin the upstream toolchain. + # Keep rc.exe resolved from the MSVC developer environment as well. The + # absolute Windows SDK path contains spaces and OpenSSL 1.1.1 writes it to + # the generated nmake file without quoting, which skips .res generation. + # /FS serializes access to OpenSSL's shared generated PDB when cl is + # driven through nmake from a Ninja configure step. + set(_conf_cmd ${CMAKE_COMMAND} -E env ${_openssl_msvc_env} perl Configure ) set(_cross_comp_prefix_line "") - set(_make_cmd nmake) - set(_install_cmd nmake install_sw ) + set(_make_cmd ${CMAKE_COMMAND} -E env ${_openssl_msvc_env} nmake) + set(_install_cmd ${CMAKE_COMMAND} -E env ${_openssl_msvc_env} nmake install_sw ) else() if(APPLE) set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) diff --git a/deps/wxInspector/wxInspector.cmake b/deps/wxInspector/wxInspector.cmake index 97c3810809..4a5b28407f 100644 --- a/deps/wxInspector/wxInspector.cmake +++ b/deps/wxInspector/wxInspector.cmake @@ -1,3 +1,26 @@ +# wxInspector finds wxWidgets through CMake's FindwxWidgets module, which only +# searches lib/vc*_lib because _WX_TOOL is hardcoded to "vc". A superbuild driven +# by clang-cl installs wxWidgets into lib/clang_x64_lib, so hand the module the +# directory wxWidgets actually used, derived the same way wxWidgetsConfig.cmake +# derives it. +set(_wxinspector_wx_hints "") +if (MSVC) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(_wx_compiler_prefix "clang") + else () + set(_wx_compiler_prefix "vc") + endif () + set(_wx_arch_suffix "") + if (CMAKE_GENERATOR_PLATFORM AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "Win32") + string(TOLOWER "_${CMAKE_GENERATOR_PLATFORM}" _wx_arch_suffix) + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_wx_arch_suffix "_x64") + endif () + set(_wxinspector_wx_hints + "-DwxWidgets_ROOT_DIR=${DESTDIR}" + "-DwxWidgets_LIB_DIR=${DESTDIR}/lib/${_wx_compiler_prefix}${_wx_arch_suffix}_lib") +endif () + orcaslicer_add_cmake_project( wxInspector URL https://github.com/Noisyfox/wxInspector/archive/refs/tags/v1.0.0.zip @@ -6,6 +29,7 @@ orcaslicer_add_cmake_project( CMAKE_ARGS -DCMAKE_CXX_FLAGS="-DwxDEBUG_LEVEL=0" -DCMAKE_POSITION_INDEPENDENT_CODE=ON + ${_wxinspector_wx_hints} ) if (MSVC) diff --git a/deps/wxWidgets/0001-Clang-CL-fix.patch b/deps/wxWidgets/0001-Clang-CL-fix.patch deleted file mode 100644 index 23bf23b3f4..0000000000 --- a/deps/wxWidgets/0001-Clang-CL-fix.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- - build/cmake/wxWidgetsConfig.cmake.in | 10 +++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in -index 1a83f36..70ad8a4 100644 ---- a/build/cmake/wxWidgetsConfig.cmake.in -+++ b/build/cmake/wxWidgetsConfig.cmake.in -@@ -58,7 +58,16 @@ if(WIN32_MSVC_NAMING) - endif() - endif() - --include("${CMAKE_CURRENT_LIST_DIR}${wxPLATFORM_LIB_DIR}/@PROJECT_NAME@Targets.cmake") -+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") -+ if (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64" OR CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|arm64|aarch64)$") -+ set(_wx_clang_msvc_lib_dir "vc_arm64_lib") -+ else() -+ set(_wx_clang_msvc_lib_dir "vc_x64_lib") -+ endif() -+ include("${CMAKE_CURRENT_LIST_DIR}${wxPLATFORM_LIB_DIR}/${_wx_clang_msvc_lib_dir}/@PROJECT_NAME@Targets.cmake") -+else() -+ include("${CMAKE_CURRENT_LIST_DIR}${wxPLATFORM_LIB_DIR}/@PROJECT_NAME@Targets.cmake") -+endif() - - macro(wx_inherit_property source dest name) - # property name without _ --- -2.43.0 diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake index 07bb31d8be..1e2cc85f78 100644 --- a/deps/wxWidgets/wxWidgets.cmake +++ b/deps/wxWidgets/wxWidgets.cmake @@ -28,7 +28,6 @@ orcaslicer_add_cmake_project( GIT_SHALLOW ON GIT_SUBMODULES 3rdparty/catch 3rdparty/pcre 3rdparty/libwebp DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG} - PATCH_COMMAND git apply --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-Clang-CL-fix.patch CMAKE_ARGS -DwxBUILD_PRECOMP=ON ${_wx_toolkit} diff --git a/docs/superpowers/plans/2026-08-14-ffmpeg-player-macos.md b/docs/superpowers/plans/2026-08-14-ffmpeg-player-macos.md new file mode 100644 index 0000000000..811626fc8b --- /dev/null +++ b/docs/superpowers/plans/2026-08-14-ffmpeg-player-macos.md @@ -0,0 +1,376 @@ +# macOS FFmpeg Media Player Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make macOS use the same FFmpeg-based media player (`wxMediaCtrl3` + `AVVideoDecoder`) as Windows/Linux, linking the static FFmpeg libraries from the deps build, and remove the old `wxMediaCtrl2.mm` BambuPlayer-based player. + +**Architecture:** The new player is platform-neutral C++ already used on Linux/Windows. Enabling it on macOS is pure build wiring: compile `wxMediaCtrl3.cpp` + `AVVideoDecoder.cpp` on macOS, drop the `__WXMAC__` alias that redirects `wxMediaCtrl3` to the old `wxMediaCtrl2`, and link static FFmpeg (`libavcodec.a`/`libswscale.a`/`libavutil.a`) from the deps install. The Bambu stream API is dlsym'd at runtime from the network plugin (`libBambuSource.dylib`), which already exports it — no plugin changes needed. Rendering reuses the existing `wxImage` → `DrawBitmap` paint path (same as Linux). + +**Tech Stack:** C++17, wxWidgets, CMake, FFmpeg 7.0.3 (libavcodec/libswscale/libavutil), macOS (Xcode generator), `deps/` ExternalProject build system. + +## Global Constraints + +- Branch: `dev/ffmpeg-player-macos`. Commit after every task. +- **Linux and Windows builds must not change** — the FFmpeg deps flag change is guarded by `APPLE`; Linux keeps `--enable-shared`, Windows keeps its prebuilt DLL zips. +- Static FFmpeg only on macOS: deps produce `libavcodec.a`/`libswscale.a`/`libavutil.a`; the app links those explicitly — the app binary must have **no** `libav*` dylib references (`otool -L` check). +- Follow existing code style: PascalCase classes, snake_case functions, C++17. +- No changes to `StatusPanel.cpp`, `MediaPlayCtrl.*`, or the BambuTunnel interface — the app already creates `wxMediaCtrl3` and uses only its public interface. +- The player cannot be unit-tested (hardware/plugin-dependent GUI code); verification is build-level, link-level, and manual runtime on a Mac. +- `localization/i18n/list.txt` references only `wxMediaCtrl2.cpp` (Win/Linux, stays) — no translation-list changes needed. +- Build dirs on the dev machine: main app = `build_arm64/` (Xcode generator, multi-config), deps = `deps/build/arm64/` (Unix Makefiles). App target name: `OrcaSlicer`. Substitute your own configured build dirs where noted. + +--- + +### Task 1: Enable wxMediaCtrl3 on macOS and link static FFmpeg + +**Files:** +- Modify: `src/slic3r/GUI/wxMediaCtrl3.h` (lines 18–22: the `#ifdef __WXMAC__` alias branch) +- Modify: `src/slic3r/GUI/wxMediaCtrl3.cpp:13` (uncomment the event define) +- Modify: `src/slic3r/GUI/wxMediaCtrl2.cpp:101` (remove the event define) +- Modify: `src/slic3r/CMakeLists.txt` (APPLE source list ~lines 779–792; FFmpeg link block ~lines 905–910) + +**Interfaces:** +- Consumes: nothing new (all classes already exist). +- Produces: `wxMediaCtrl3` class compiled on macOS with the same interface as Linux/Windows — `Load(wxURI)`, `Play()`, `Stop()`, `SetIdleImage(wxString)`, `GetState()`, `GetLastError()`, `GetVideoSize()`, event `EVT_MEDIA_CTRL_STAT` defined once in the lib (from `wxMediaCtrl3.cpp`). + +- [ ] **Step 1: Remove the macOS alias in wxMediaCtrl3.h** + +Current (lines 16–23 of `src/slic3r/GUI/wxMediaCtrl3.h`): + +```cpp +void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height); + +#ifdef __WXMAC__ + +#include "wxMediaCtrl2.h" +#define wxMediaCtrl3 wxMediaCtrl2 + +#else + +#define BAMBU_DYNAMIC +``` + +New: + +```cpp +void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height); + +#define BAMBU_DYNAMIC +``` + +Also remove the matching `#endif` that closed the `#else` branch (the one before the final `#endif /* wxMediaCtrl3_h */`), so the file's `#ifndef`/`#endif` guard pair stays balanced. + +- [ ] **Step 2: Move the EVT_MEDIA_CTRL_STAT definition into wxMediaCtrl3.cpp** + +In `src/slic3r/GUI/wxMediaCtrl3.cpp:13`, uncomment: + +```cpp +//wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); +``` + +becomes: + +```cpp +wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); +``` + +In `src/slic3r/GUI/wxMediaCtrl2.cpp:101`, delete: + +```cpp +wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); +``` + +(One definition total in the lib — `MediaPlayCtrl.cpp:59` binds this event on the media ctrl.) + +- [ ] **Step 3: Update the APPLE source list in CMakeLists.txt** + +In `src/slic3r/CMakeLists.txt`, the APPLE branch (currently compiles `wxMediaCtrl2.mm`, which becomes dead on macOS): + +```cmake + GUI/wxMediaCtrl2.mm + GUI/wxMediaCtrl2.h + GUI/wxMediaCtrl3.h + ) +``` + +becomes: + +```cmake + GUI/AVVideoDecoder.cpp + GUI/AVVideoDecoder.hpp + GUI/wxMediaCtrl3.cpp + GUI/wxMediaCtrl3.h + ) +``` + +(The `else ()` branch — Win/Linux — stays exactly as it is.) + +- [ ] **Step 4: Link static FFmpeg on macOS** + +In `src/slic3r/CMakeLists.txt`, the FFmpeg block (currently `if (NOT APPLE)`): + +```cmake +if (NOT APPLE) + pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET + libavcodec + libswscale + libavutil + ) + target_link_libraries(libslic3r_gui PkgConfig::LIBAV) +endif() +``` + +becomes: + +```cmake +if (APPLE) + # Static FFmpeg from the deps install: nothing to bundle into the .app, + # no rpath/install_name handling. Order matters: avcodec -> swscale -> avutil. + 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) + target_link_libraries(libslic3r_gui ${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 + libavcodec + libswscale + libavutil + ) + target_link_libraries(libslic3r_gui PkgConfig::LIBAV) +endif() +``` + +The deps install (`${CMAKE_PREFIX_PATH}/lib`) already contains the three `.a` files from the existing arm64 deps build — no deps rebuild needed for this task. + +- [ ] **Step 5: Reconfigure and build the app** + +Run (Xcode generator; `cmake` re-runs automatically on build): + +```bash +cmake --build build_arm64 --config RelWithDebInfo --target OrcaSlicer +``` + +Expected: configure succeeds (no `pkg_check_modules` errors on macOS, `find_library` finds all three `.a` files), compile succeeds (`wxMediaCtrl3.cpp` and `AVVideoDecoder.cpp` compile on macOS without changes), link succeeds. + +If CMake complains that `wxMediaCtrl3.h` is included but not in the source list or similar IDE-only warnings — ignore; headers in the list are cosmetic. + +- [ ] **Step 6: Verify no dynamic FFmpeg dependency** + +```bash +otool -L build_arm64/src/RelWithDebInfo/OrcaSlicer.app/Contents/MacOS/OrcaSlicer | grep -i "libav" || echo "OK: no dynamic FFmpeg" +``` + +Expected: prints `OK: no dynamic FFmpeg` (empty grep output). This is the whole point of static linking — nothing to bundle into the `.app`. + +- [ ] **Step 7: Quick sanity — macOS unit tests still pass** + +```bash +ctest --test-dir build_arm64/tests/libslic3r --output-on-failure +``` + +Expected: passes (add `-C RelWithDebInfo` if the multi-config generator requires it). If no tests were built in this build dir, build target `tests` first (`cmake --build build_arm64 --config RelWithDebInfo --target tests`). + +- [ ] **Step 8: Commit** + +```bash +git add src/slic3r/CMakeLists.txt src/slic3r/GUI/wxMediaCtrl3.h src/slic3r/GUI/wxMediaCtrl3.cpp src/slic3r/GUI/wxMediaCtrl2.cpp +git commit -m "feat: use FFmpeg media player on macOS with static FFmpeg" +``` + +--- + +### Task 2: Static-only FFmpeg in the macOS deps build + +**Files:** +- Modify: `deps/FFMPEG/FFMPEG.cmake` (non-MSVC branch, APPLE section and CONFIGURE_COMMAND) + +**Interfaces:** +- Consumes: nothing. +- Produces: a deps install on macOS containing only `libavcodec.a`, `libswscale.a`, `libavutil.a` (+ headers) — no `libav*` dylibs, so no bundling/rpath machinery is ever needed on macOS. Linux and Windows output are unchanged. + +- [ ] **Step 1: Add the static flag variable** + +In `deps/FFMPEG/FFMPEG.cmake`, inside the non-MSVC `else ()` branch, in the existing `if (APPLE)` block: + +```cmake + if (APPLE) + set(_minos_cmd + "CFLAGS=-mmacosx-version-min=${DEP_OSX_TARGET}" + "LDFLAGS=-mmacosx-version-min=${DEP_OSX_TARGET}" + ) +``` + +add after the `_minos_cmd` set: + +```cmake + # Static FFmpeg: nothing to bundle into the .app, no rpath handling. + # Shared flags must come AFTER --enable-shared below so they win. + set(_link_cmd --enable-static --disable-shared) +``` + +and add a matching `else ()` after the `if (IS_CROSS_COMPILE) ... endif()` block inside that `if (APPLE)`, so non-Apple Unix keeps shared: + +```cmake + else () + set(_link_cmd --enable-shared) + endif () +``` + +(If the existing `if (IS_CROSS_COMPILE)` block is the last thing inside `if (APPLE)`, the new `else ()` closes the `if (APPLE)` itself.) + +- [ ] **Step 2: Use the variable in CONFIGURE_COMMAND** + +In the `ExternalProject_Add(dep_FFMPEG ...)` configure command: + +```cmake + "--prefix=${DESTDIR}" + --enable-shared +``` + +becomes: + +```cmake + "--prefix=${DESTDIR}" + --enable-shared + ${_link_cmd} +``` + +Order matters: `--enable-shared` comes first, then `--enable-static --disable-shared` (APPLE) or `--enable-shared` (Linux) — the last flag wins in FFmpeg configure. + +- [ ] **Step 3: Rebuild the FFmpeg dep (slow — several minutes, run in background)** + +The changed CONFIGURE_COMMAND invalidates the ExternalProject stamp, so this re-configures and rebuilds FFmpeg: + +```bash +cmake --build deps/build/arm64 --target dep_FFMPEG +``` + +For a fully clean static-only check (removes the previous shared build tree, which can leave stale `.dylib` files behind in the in-source build): + +```bash +rm -rf deps/build/arm64/dep_FFMPEG-prefix +cmake --build deps/build/arm64 --target dep_FFMPEG +``` + +- [ ] **Step 4: Verify the artifacts** + +```bash +ls deps/build/arm64/dep_FFMPEG-prefix/src/dep_FFMPEG/libavcodec/*.a +ls deps/build/arm64/dep_FFMPEG-prefix/src/dep_FFMPEG/libavcodec/*.dylib 2>/dev/null || echo "OK: no dylibs" +``` + +Expected: `libavcodec.a` present, second command prints `OK: no dylibs`. Check `libavutil` and `libswscale` the same way. + +- [ ] **Step 5: Verify the app still links against the static libs** + +```bash +cmake --build build_arm64 --config RelWithDebInfo --target OrcaSlicer +otool -L build_arm64/src/RelWithDebInfo/OrcaSlicer.app/Contents/MacOS/OrcaSlicer | grep -i "libav" || echo "OK: no dynamic FFmpeg" +``` + +Expected: build succeeds, `OK: no dynamic FFmpeg`. + +- [ ] **Step 6: Commit** + +```bash +git add deps/FFMPEG/FFMPEG.cmake +git commit -m "build: build static-only FFmpeg for macOS deps" +``` + +--- + +### Task 3: Remove the old macOS player + +**Files:** +- Delete: `src/slic3r/GUI/wxMediaCtrl2.mm` +- Delete: `src/slic3r/GUI/BambuPlayer/BambuPlayer.h` (and the empty `BambuPlayer/` dir) +- Modify: `src/slic3r/GUI/wxMediaCtrl2.h` (remove the `#ifdef __WXMAC__` section, lines 22–60) + +**Interfaces:** +- Consumes: Task 1 (macOS no longer references `wxMediaCtrl2` — nothing includes `wxMediaCtrl2.h` on macOS anymore; `wxMediaCtrl2` is never instantiated on any platform). +- Produces: a clean tree where the old BambuPlayer-based player is gone from macOS. The `BambuPlayer` ObjC class itself remains inside the network plugin (external prebuilt binary) — only the GUI-side consumer is removed. + +- [ ] **Step 1: Delete the old player files** + +```bash +git rm src/slic3r/GUI/wxMediaCtrl2.mm +git rm src/slic3r/GUI/BambuPlayer/BambuPlayer.h +rmdir src/slic3r/GUI/BambuPlayer 2>/dev/null || true +``` + +- [ ] **Step 2: Strip the __WXMAC__ section from wxMediaCtrl2.h** + +In `src/slic3r/GUI/wxMediaCtrl2.h`, remove the entire macOS branch of the `#ifdef __WXMAC__` guard — from `#ifdef __WXMAC__` (line 22) through the closing `};` of the mac class (line 60), and the `#else` marker — leaving only the non-mac `class wxMediaCtrl2 : public wxMediaCtrl { ... };` definition followed by the final `#endif /* wxMediaCtrl2_h */`. The resulting file keeps its `#ifndef`/`#endif` include guard pair balanced. + +The file stays on disk because Win/Linux compile `wxMediaCtrl2.cpp`, which includes it. + +- [ ] **Step 3: Grep for leftover references** + +```bash +grep -rn "wxMediaCtrl2.mm\|BambuPlayer/BambuPlayer.h\|BambuPlayer" src/slic3r --include="*.cpp" --include="*.h" --include="*.mm" --include="*.txt" +``` + +Expected: no hits in `src/slic3r/GUI` (ignore `localization/i18n/list.txt:196`, which lists the Win/Linux `wxMediaCtrl2.cpp` and stays). + +- [ ] **Step 4: Rebuild the app** + +```bash +cmake --build build_arm64 --config RelWithDebInfo --target OrcaSlicer +``` + +Expected: configure + compile + link succeed with the deleted files gone. + +- [ ] **Step 5: Commit** + +```bash +git add -A src/slic3r/GUI +git commit -m "refactor: remove old BambuPlayer-based media player from macOS" +``` + +--- + +### Task 4: Runtime verification on hardware + +**Files:** none — manual verification. + +**Interfaces:** consumes all prior tasks. Final gate: the new player must actually stream on a Mac. + +- [ ] **Step 1: Launch the freshly built app** + +```bash +open build_arm64/src/RelWithDebInfo/OrcaSlicer.app +``` + +Expected: app launches normally; no crash in the network/device subsystem. + +- [ ] **Step 2: Load the network plugin and open the Device tab** + +Log in / ensure the network plugin (`libBambuSource.dylib`) loads, select a printer, open the Device tab (camera monitoring panel). + +Expected: the camera preview area shows the idle image initially (no crash — this exercises `wxMediaCtrl3::SetIdleImage` and the `wxImage` load path on macOS for the first time). + +- [ ] **Step 3: Start the stream and watch it render** + +Click play / wait for `MediaPlayCtrl` to start the stream. + +Expected: live video renders in the panel. Check the console/log output (`BOOST_LOG` goes to the terminal if run from it, or check the log file): +- `stat_log ...` lines appear (the `EVT_MEDIA_CTRL_STAT` path is live — proves the Bambu C API dlsym worked from `libBambuSource.dylib`); +- no repeated decode/error messages like `AVVideoDecoder: ...` or `can not find function ...` (proves `StaticBambuLib::get` resolved all Bambu functions); +- Stop/Play toggle works; idle image reappears on stop; +- window resize keeps aspect ratio (exercises `DoSetSize`/`adjust_frame_size`/`paintEvent`). + +- [ ] **Step 4: Confirm the old player is really gone** + +Expected: nothing in the logs references `BambuPlayer` (the ObjC class is no longer dlsym'd); the video path is entirely `wxMediaCtrl3` + `AVVideoDecoder`. + +If a printer is unavailable, at minimum verify Steps 1–2 (launch + idle image) and note in the PR that live-stream verification needs hardware. + +- [ ] **Step 5: Final review pass** + +```bash +git log --oneline -6 +git show --stat HEAD # and each of the three task commits +``` + +Expected: the last 4 commits are the design doc + the 3 implementation tasks (each task commit touches only its listed files). Review the diff for scope: no Linux/Windows changes beyond the two `EVT_MEDIA_CTRL_STAT` lines in Task 1, no `StatusPanel`/`MediaPlayCtrl` changes. diff --git a/docs/superpowers/specs/2026-08-14-ffmpeg-player-macos-design.md b/docs/superpowers/specs/2026-08-14-ffmpeg-player-macos-design.md new file mode 100644 index 0000000000..812a7bf735 --- /dev/null +++ b/docs/superpowers/specs/2026-08-14-ffmpeg-player-macos-design.md @@ -0,0 +1,110 @@ +# FFmpeg Media Player for macOS — Design + +Date: 2026-08-14 +Branch: `dev/ffmpeg-player-macos` + +## Problem + +The branch's new FFmpeg-based media player (`wxMediaCtrl3` + `AVVideoDecoder`) is used on +Windows and Linux, but macOS still runs the old player: `wxMediaCtrl2.mm`, an ObjC +`BambuPlayer` class dlsym'd from the Bambu network plugin that renders via CALayer. +On macOS, `wxMediaCtrl3` is currently aliased to `wxMediaCtrl2` and FFmpeg is not linked +into the app at all. + +Goal: make macOS use the same FFmpeg player as Windows/Linux, linking the **static** +FFmpeg libraries from the deps build instead of dynamic ones. + +## Current state (verified) + +- New player (Win/Linux): `GUI/wxMediaCtrl3.cpp` + `GUI/AVVideoDecoder.cpp`. Decodes with + FFmpeg (libavcodec/libswscale/libavutil), renders frames into `wxImage` (non-Windows) / + `wxBitmap` (Windows) drawn in a `paintEvent`, feeds via the `Bambu_*` C API + (`BambuTunnel.h`, `BAMBU_DYNAMIC`) dlsym'd from the network plugin through + `StaticBambuLib::get()` (`GUI/Printer/PrinterFileSystem.cpp`, compiled on all platforms). +- Old player (macOS): `GUI/wxMediaCtrl2.mm` uses the ObjC `BambuPlayer` class found via + `dlsym(module, "OBJC_CLASS_$_BambuPlayer")` in `libBambuSource.dylib`. +- The macOS network plugin `libBambuSource.dylib` already exports the full Bambu C API + (verified with `nm`), so the new player needs zero plugin changes. +- FFmpeg linking in `src/slic3r/CMakeLists.txt` is guarded by `if (NOT APPLE)` — + macOS currently does not link FFmpeg. +- `deps/FFMPEG/FFMPEG.cmake`: non-MSVC branch builds FFmpeg from source with + `--enable-shared`. The existing arm64 deps build on the dev machine happened to be + configured with both static and shared enabled, so `libavcodec.a` / `libswscale.a` / + `libavutil.a` are already present at + `deps/build/arm64/OrcaSlicer_dep/usr/local/lib/`. +- `EVT_MEDIA_CTRL_STAT` is `wxDEFINE_EVENT`'d in `wxMediaCtrl2.cpp` (Win/Linux) and + `wxMediaCtrl2.mm` (macOS); the define in `wxMediaCtrl3.cpp` is commented out. +- `wxMediaCtrl2` is never instantiated anywhere on any platform — dead code. +- `StatusPanel` already creates `wxMediaCtrl3`; `MediaPlayCtrl` only uses the + `wxMediaCtrl3` interface (`Load/Play/Stop/GetState/GetVideoSize/GetLastError/SetIdleImage`), + so no UI-side changes are needed. + +## Approach (approved) + +**Reuse the shared player on macOS.** Compile the existing `wxMediaCtrl3.cpp` + +`AVVideoDecoder.cpp` on macOS so all three platforms run one implementation. +Rendering uses the existing `wxImage` → `DrawBitmap` paint path, identical to Linux. +Known trade-off: frames are scaled to the widget's logical (1x) size, so Retina is +slightly soft compared to the old CALayer player. Accepted for now; a Retina-aware +scaling follow-up is possible later. + +Rejected alternative: a native CGImage/CALayer renderer for macOS — faster and +Retina-crisp, but adds a second render implementation to maintain. + +## Changes + +### 1. Enable the FFmpeg player on macOS (source) + +- `GUI/wxMediaCtrl3.h`: remove the `#ifdef __WXMAC__` branch (lines 18–22) that aliases + `wxMediaCtrl3` → `wxMediaCtrl2`. macOS then compiles the real `wxMediaCtrl3` class, + including the `BAMBU_DYNAMIC` BambuTunnel path used on Linux. +- Event symbol fix: move `wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent)` into + `wxMediaCtrl3.cpp` (uncomment the existing line) and remove it from + `wxMediaCtrl2.cpp`. One definition total in the lib; all three platforms resolve it. + +### 2. Static FFmpeg linking (deps + app) + +- `deps/FFMPEG/FFMPEG.cmake`: in the non-MSVC branch, pass + `--disable-shared --enable-static` when `APPLE`. Linux keeps `--enable-shared`; + Windows keeps its prebuilt shared DLL zips. Fresh macOS deps builds install only + `libavcodec.a` / `libswscale.a` / `libavutil.a` — no dylibs to bundle, no + rpath/install_name handling. (The existing local arm64 deps build already contains + the `.a` files, so no deps rebuild is strictly needed to try the change locally, + but a fresh CI deps build must produce them.) +- `src/slic3r/CMakeLists.txt`: + - APPLE branch of `SLIC3R_GUI_SOURCES`: add `GUI/wxMediaCtrl3.cpp`, + `GUI/wxMediaCtrl3.h`, `GUI/AVVideoDecoder.cpp`, `GUI/AVVideoDecoder.hpp`; + remove `GUI/wxMediaCtrl2.mm` and `GUI/wxMediaCtrl2.h` (the `.h` stays on + disk for the Win/Linux build of `wxMediaCtrl2.cpp`, but nothing on macOS + includes it after this change). + - Add an APPLE mirror of the `NOT APPLE` FFmpeg block: `find_library` for + `libavcodec.a`, `libswscale.a`, `libavutil.a` under `${CMAKE_PREFIX_PATH}/lib` + with `NO_DEFAULT_PATH`, link them (order avcodec → swscale → avutil), and add + `${CMAKE_PREFIX_PATH}/include` as a SYSTEM include directory. Deps are built with + `--disable-zlib` and no external codecs, so the three static libs link cleanly. + +### 3. Remove the old player + +- Delete `GUI/wxMediaCtrl2.mm` and `GUI/BambuPlayer/BambuPlayer.h` (header used only + by the `.mm`; the real `BambuPlayer` lives inside the network plugin). +- Remove the now-dead `__WXMAC__` section of `GUI/wxMediaCtrl2.h`. +- `wxMediaCtrl2.cpp` (Win/Linux) stays in the build as-is (dead but harmless; out of + scope to remove on this branch). + +### 4. Verification + +- Build on macOS: `cmake --build build_arm64` (or `build/arm64`). +- Confirm no dynamic FFmpeg dependency: `otool -L` on the app binary shows no `libav*` + dylib references. +- Runtime: with the network plugin loaded, the Device tab camera preview streams via + the FFmpeg player (check the device page / `MediaPlayCtrl`). +- macOS `ctest` still passes — static linking means no test-executable `.so` copying + hacks (unlike the Linux shared-lib setup). + +## Out of scope + +- Linux (shared libs, AppImage/flatpak bundling) and Windows (prebuilt DLL zips) + keep their current FFmpeg setup. +- Retina-aware frame scaling / native CGImage rendering (follow-up if visual quality + is judged insufficient). +- Audio streaming (neither player plays audio in this UI path). diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index b9da59451f..121a9e1af2 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -7705,7 +7705,7 @@ msgstr "" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -10939,27 +10939,6 @@ msgstr "" msgid "Please choose the filament colour" msgstr "" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "" - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "" - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "" - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "" - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "" diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 74ed04532c..1b74b294c8 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2025-03-15 10:55+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -8273,7 +8273,7 @@ msgstr "Perfil personalitzat" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" # AI Translated @@ -11847,29 +11847,6 @@ msgstr "Volums de purga per al canvi de filament" msgid "Please choose the filament colour" msgstr "Trieu el color del filament" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "La visualització en directe nativa de Wayland requereix el sink de vídeo GTK de GStreamer. Instal·leu el connector gtksink per a GStreamer i reinicieu l'OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "No s'ha pogut inicialitzar el sink de vídeo natiu de GStreamer per a Wayland. Comproveu la instal·lació del connector GTK de GStreamer." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "El Windows Media Player és necessari per a aquesta tasca. Voleu habilitar el \"Windows Media Player\" per al vostre sistema operatiu?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource no s'ha registrat correctament per a la reproducció multimèdia! Premeu Sí per tornar-lo a registrar. Seràs promocionat dues vegades" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Falta el component BambuSource registrat per a la reproducció multimèdia! Reinstal·leu OrcaSlicer o cerqueu ajuda a la comunitat." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Utilitzar un BambuSource des d'una instal·lació diferent, la reproducció de vídeo pot no funcionar correctament! Premeu Sí per solucionar-ho." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Al vostre sistema li falten còdecs H.264 per al GStreamer, necessaris per reproduir vídeo. (Proveu d'instal·lar els paquets gstreamer1.0-plugins-bad o gstreamer1.0-libav i, a continuació, reinicieu Orca Slicer?)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "L'agent del núvol no està disponible. Reinicieu l'OrcaSlicer i torneu-ho a provar." @@ -22178,6 +22155,29 @@ msgstr "" "Evitar la deformació( warping )\n" "Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "La visualització en directe nativa de Wayland requereix el sink de vídeo GTK de GStreamer. Instal·leu el connector gtksink per a GStreamer i reinicieu l'OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "No s'ha pogut inicialitzar el sink de vídeo natiu de GStreamer per a Wayland. Comproveu la instal·lació del connector GTK de GStreamer." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "El Windows Media Player és necessari per a aquesta tasca. Voleu habilitar el \"Windows Media Player\" per al vostre sistema operatiu?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource no s'ha registrat correctament per a la reproducció multimèdia! Premeu Sí per tornar-lo a registrar. Seràs promocionat dues vegades" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Falta el component BambuSource registrat per a la reproducció multimèdia! Reinstal·leu OrcaSlicer o cerqueu ajuda a la comunitat." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Utilitzar un BambuSource des d'una instal·lació diferent, la reproducció de vídeo pot no funcionar correctament! Premeu Sí per solucionar-ho." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Al vostre sistema li falten còdecs H.264 per al GStreamer, necessaris per reproduir vídeo. (Proveu d'instal·lar els paquets gstreamer1.0-plugins-bad o gstreamer1.0-libav i, a continuació, reinicieu Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index 28396811c5..de4098f18f 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: Jakub Hencl\n" "Language-Team: \n" @@ -8235,7 +8235,7 @@ msgstr "Přizpůsobená předvolba" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11829,34 +11829,6 @@ msgstr "Objemy čištění při výměně filamentu" msgid "Please choose the filament colour" msgstr "Vyberte prosím barvu filamentu" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Nativní živý náhled ve Waylandu vyžaduje video sink GStreamer GTK. Nainstalujte prosím plugin gtksink pro GStreamer a poté restartujte OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Nepodařilo se inicializovat nativní video sink GStreamer pro Wayland. Zkontrolujte prosím instalaci pluginu GStreamer GTK." - -# AI Translated -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Pro tuto úlohu je vyžadován Windows Media Player! Chcete ve svém operačním systému povolit „Windows Media Player“?" - -# AI Translated -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource nebyl správně zaregistrován pro přehrávání médií! Stisknutím Ano jej znovu zaregistrujete. Budete vyzváni dvakrát" - -# AI Translated -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Chybí komponenta BambuSource registrovaná pro přehrávání médií! Přeinstalujte prosím OrcaSlicer nebo požádejte o pomoc komunitu." - -# AI Translated -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Používá se BambuSource z jiné instalace, přehrávání videa nemusí fungovat správně! Stisknutím Ano to opravíte." - -# AI Translated -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Ve vašem systému chybí kodeky H.264 pro GStreamer, které jsou nutné k přehrávání videa. (Zkuste nainstalovat balíčky gstreamer1.0-plugins-bad nebo gstreamer1.0-libav a poté restartovat Orca Slicer?)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Cloudový agent není dostupný. Restartujte prosím OrcaSlicer a zkuste to znovu." @@ -22164,6 +22136,34 @@ msgstr "" "Zamezte kroucení\n" "Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Nativní živý náhled ve Waylandu vyžaduje video sink GStreamer GTK. Nainstalujte prosím plugin gtksink pro GStreamer a poté restartujte OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Nepodařilo se inicializovat nativní video sink GStreamer pro Wayland. Zkontrolujte prosím instalaci pluginu GStreamer GTK." + +# AI Translated +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Pro tuto úlohu je vyžadován Windows Media Player! Chcete ve svém operačním systému povolit „Windows Media Player“?" + +# AI Translated +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource nebyl správně zaregistrován pro přehrávání médií! Stisknutím Ano jej znovu zaregistrujete. Budete vyzváni dvakrát" + +# AI Translated +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Chybí komponenta BambuSource registrovaná pro přehrávání médií! Přeinstalujte prosím OrcaSlicer nebo požádejte o pomoc komunitu." + +# AI Translated +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Používá se BambuSource z jiné instalace, přehrávání videa nemusí fungovat správně! Stisknutím Ano to opravíte." + +# AI Translated +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Ve vašem systému chybí kodeky H.264 pro GStreamer, které jsou nutné k přehrávání videa. (Zkuste nainstalovat balíčky gstreamer1.0-plugins-bad nebo gstreamer1.0-libav a poté restartovat Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index 0e3fc99a39..8518900a02 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: Heiko Liebscher \n" "Language-Team: \n" @@ -8105,7 +8105,7 @@ msgstr "Benutzerdefinierte Profile" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11592,27 +11592,6 @@ msgstr "Reinigungsvolumen für Filamentwechsel" msgid "Please choose the filament colour" msgstr "Bitte wählen Sie die Filamentfarbe" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Native Wayland Liveview erfordert das GStreamer GTK Video Sink. Bitte installieren Sie das gtksink-Plugin für GStreamer und starten Sie OrcaSlicer neu." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Fehler beim Initialisieren des nativen Wayland GStreamer Video Sinks. Bitte überprüfen Ihre GStreamer GTK-Plugin-Installation." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Windows Media Player wird für diese Aufgabe benötigt! Möchten Sie 'Windows Media Player' für Ihr Betriebssystem aktivieren?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource wurde nicht korrekt für das Abspielen von Medien registriert! Drücken Sie Ja, um es erneut zu registrieren. Sie werden zweimal aufgefordert" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Fehlende BambuSource-Komponente, die für das Abspielen von Medien registriert ist! Bitte installieren Sie OrcaSlicer neu oder suchen Sie Hilfe in der Community." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Verwendung eines BambuSource aus einer anderen Installation, das Abspielen von Videos funktioniert möglicherweise nicht korrekt! Drücken Sie Ja, um es zu beheben." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Ihr System fehlt H.264-Codecs für GStreamer, die zum Abspielen von Videos erforderlich sind. (Versuchen Sie, die Pakete gstreamer1.0-plugins-bad oder gstreamer1.0-libav zu installieren und starten Sie Orca Slicer neu?)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Cloud-Agent ist nicht verfügbar. Bitte starten Sie OrcaSlicer neu und versuchen Sie es erneut." @@ -21577,6 +21556,27 @@ msgstr "" "Verwerfungen vermeiden\n" "Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Native Wayland Liveview erfordert das GStreamer GTK Video Sink. Bitte installieren Sie das gtksink-Plugin für GStreamer und starten Sie OrcaSlicer neu." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Fehler beim Initialisieren des nativen Wayland GStreamer Video Sinks. Bitte überprüfen Ihre GStreamer GTK-Plugin-Installation." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Windows Media Player wird für diese Aufgabe benötigt! Möchten Sie 'Windows Media Player' für Ihr Betriebssystem aktivieren?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource wurde nicht korrekt für das Abspielen von Medien registriert! Drücken Sie Ja, um es erneut zu registrieren. Sie werden zweimal aufgefordert" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Fehlende BambuSource-Komponente, die für das Abspielen von Medien registriert ist! Bitte installieren Sie OrcaSlicer neu oder suchen Sie Hilfe in der Community." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Verwendung eines BambuSource aus einer anderen Installation, das Abspielen von Videos funktioniert möglicherweise nicht korrekt! Drücken Sie Ja, um es zu beheben." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Ihr System fehlt H.264-Codecs für GStreamer, die zum Abspielen von Videos erforderlich sind. (Versuchen Sie, die Pakete gstreamer1.0-plugins-bad oder gstreamer1.0-libav zu installieren und starten Sie Orca Slicer neu?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index 8a679894fa..56ca287e68 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-06-17 15:44-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: \n" @@ -7701,7 +7701,7 @@ msgstr "" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -10935,27 +10935,6 @@ msgstr "" msgid "Please choose the filament colour" msgstr "" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "" - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "" - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "" - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "" - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "" diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index 8a435af73e..e744cb66eb 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: Ian A. Bassi <>\n" "Language-Team: \n" @@ -7919,7 +7919,7 @@ msgstr "Perfil Personalizado" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11313,27 +11313,6 @@ msgstr "Volúmenes de purgado para el cambio de filamentos" msgid "Please choose the filament colour" msgstr "Por favor, elija el color del filamento" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "La función de visualización en directo nativa de Wayland requiere el receptor de vídeo GTK de GStreamer. Instale el plugin gtksink para GStreamer y, a continuación, reinicie OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "No se pudo inicializar el receptor de vídeo nativo de Wayland GStreamer. Compruebe la instalación del plugin GTK de GStreamer." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Para esta tarea se necesita el Reproductor de Windows Media. ¿Desea activar el \"Reproductor de Windows Media\" en su sistema operativo?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource no se ha registrado correctamente para la reproducción multimedia. Pulse Sí para volver a registrarlo. Será promocionado dos veces" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "¡Falta el componente BambuSource para la reproducción de medios! Reinstale OrcaSlicer o busque ayuda en la comunidad." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Si utiliza una BambuSource de una instalación diferente, es posible que la reproducción de vídeo no funcione correctamente. Pulsa Sí para solucionarlo." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "A tu sistema le faltan los codecs H.264 para GStreamer, necesarios para reproducir vídeo. (Prueba a instalar los paquetes gstreamer1.0-plugins-bad o gstreamer1.0-libav y, a continuación, reinicia Orca Slicer...)." - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "El proveedor de servicios en la nube no está disponible. Reinicia OrcaSlicer e inténtalo de nuevo." @@ -21152,6 +21131,27 @@ msgstr "" "Evita la deformación\n" "¿Sabías que al imprimir materiales propensos a la deformación como el ABS, aumentar adecuadamente la temperatura de la cama térmica puede reducir la probabilidad de deformaciones?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "La función de visualización en directo nativa de Wayland requiere el receptor de vídeo GTK de GStreamer. Instale el plugin gtksink para GStreamer y, a continuación, reinicie OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "No se pudo inicializar el receptor de vídeo nativo de Wayland GStreamer. Compruebe la instalación del plugin GTK de GStreamer." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Para esta tarea se necesita el Reproductor de Windows Media. ¿Desea activar el \"Reproductor de Windows Media\" en su sistema operativo?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource no se ha registrado correctamente para la reproducción multimedia. Pulse Sí para volver a registrarlo. Será promocionado dos veces" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "¡Falta el componente BambuSource para la reproducción de medios! Reinstale OrcaSlicer o busque ayuda en la comunidad." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Si utiliza una BambuSource de una instalación diferente, es posible que la reproducción de vídeo no funcione correctamente. Pulsa Sí para solucionarlo." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "A tu sistema le faltan los codecs H.264 para GStreamer, necesarios para reproducir vídeo. (Prueba a instalar los paquetes gstreamer1.0-plugins-bad o gstreamer1.0-libav y, a continuación, reinicia Orca Slicer...)." + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/eu/OrcaSlicer_eu.po b/localization/i18n/eu/OrcaSlicer_eu.po index b0aadc66e4..e0d1b274f5 100644 --- a/localization/i18n/eu/OrcaSlicer_eu.po +++ b/localization/i18n/eu/OrcaSlicer_eu.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-07-20 13:33+0200\n" "Last-Translator: Manu Goiogana \n" "Language-Team: \n" @@ -7987,7 +7987,7 @@ msgstr "Aurrezarpen pertsonalizatua" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11406,27 +11406,6 @@ msgstr "Filamentua aldatzeko purgatze-bolumenak" msgid "Please choose the filament colour" msgstr "Hautatu filamentuen kolorea" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Waylanden jatorrizko zuzeneko ikuspegiak GStreamer GTK bideo-hustubidea behar du. Instalatu GStreamerrerako gtksink plugina eta berrabiarazi OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Ezin izan da Waylanden jatorrizko GStreamer bideo-hustubidea hasieratu. Egiaztatu GStreamer GTK pluginaren instalazioa." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Windows Media Player behar da zeregin honetarako! 'Windows Media Player' gaitu nahi duzu zure sistema eragilean?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource ez da behar bezala erregistratu multimedia erreproduzitzeko! Sakatu Bai berriro erregistratzeko. Bi aldiz galdetuko zaizu" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Multimedia erreproduzitzeko erregistratutako BambuSource osagaia falta da! Berrinstalatu OrcaSlicer edo eskatu laguntza komunitateari." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Beste instalazio bateko BambuSource erabiltzen ari zara; baliteke bideo-erreprodukzioak behar bezala ez funtzionatzea! Sakatu Bai konpontzeko." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Zure sisteman GStreamer-erako H.264 kodekak falta dira, eta beharrezkoak dira bideoa erreproduzitzeko. (Saiatu gstreamer1.0-plugins-bad edo gstreamer1.0-libav paketeak instalatzen, eta berrabiarazi OrcaSlicer?)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Hodeiko agentea ez dago erabilgarri. Berrabiarazi OrcaSlicer eta saiatu berriro." @@ -21307,6 +21286,27 @@ msgstr "" "Saihestu okertzea\n" "Ba al zenekien ABS bezalako okertzeko joera duten materialak inprimatzean ohe beroaren tenperatura egoki igotzeak okertzeko probabilitatea murriztu dezakeela?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Waylanden jatorrizko zuzeneko ikuspegiak GStreamer GTK bideo-hustubidea behar du. Instalatu GStreamerrerako gtksink plugina eta berrabiarazi OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Ezin izan da Waylanden jatorrizko GStreamer bideo-hustubidea hasieratu. Egiaztatu GStreamer GTK pluginaren instalazioa." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Windows Media Player behar da zeregin honetarako! 'Windows Media Player' gaitu nahi duzu zure sistema eragilean?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource ez da behar bezala erregistratu multimedia erreproduzitzeko! Sakatu Bai berriro erregistratzeko. Bi aldiz galdetuko zaizu" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Multimedia erreproduzitzeko erregistratutako BambuSource osagaia falta da! Berrinstalatu OrcaSlicer edo eskatu laguntza komunitateari." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Beste instalazio bateko BambuSource erabiltzen ari zara; baliteke bideo-erreprodukzioak behar bezala ez funtzionatzea! Sakatu Bai konpontzeko." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Zure sisteman GStreamer-erako H.264 kodekak falta dira, eta beharrezkoak dira bideoa erreproduzitzeko. (Saiatu gstreamer1.0-plugins-bad edo gstreamer1.0-libav paketeak instalatzen, eta berrabiarazi OrcaSlicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index f0085ff16d..c20240a23a 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: Guislain Cyril, Thomas Lété\n" @@ -8042,7 +8042,7 @@ msgstr "Préréglage personnalisé" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11501,27 +11501,6 @@ msgstr "Volumes de purge pour le changement de filament" msgid "Please choose the filament colour" msgstr "Veuillez choisir la couleur du filament" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "L’aperçu en direct natif sous Wayland nécessite le récepteur vidéo GStreamer GTK. Veuillez installer le plugin gtksink pour GStreamer, puis redémarrer OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Échec de l’initialisation du récepteur vidéo GStreamer natif sous Wayland. Veuillez vérifier l’installation de votre plugin GStreamer GTK." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Windows Media Player est nécessaire pour cette tâche ! Voulez-vous activer ‘Windows Media Player’ pour votre système d’exploitation ?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource n’a pas été correctement enregistré pour la lecture de médias ! Appuyez sur Oui pour le réenregistrer. Vous recevrez deux fois la demande de permission" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Composant BambuSource manquant pour la lecture multimédia ! Veuillez réinstaller OrcaSlicer ou demander de l'aide à la communauté." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Si vous utilisez une BambuSource provenant d’une autre installation, la lecture de la vidéo peut ne pas fonctionner correctement ! Appuyez sur Oui pour résoudre le problème." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Il manque à votre système les codecs H.264 pour GStreamer, qui sont nécessaires pour lire la vidéo. (Essayez d’installer les paquets gstreamer1.0-plugins-bad ou gstreamer1.0-libav, puis redémarrez Orca Slicer)." - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "L’agent cloud n’est pas disponible. Veuillez redémarrer OrcaSlicer et réessayer." @@ -21467,6 +21446,27 @@ msgstr "" "Éviter la déformation\n" "Saviez-vous que lors de l’impression de matériaux susceptibles de se déformer, tels que l’ABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "L’aperçu en direct natif sous Wayland nécessite le récepteur vidéo GStreamer GTK. Veuillez installer le plugin gtksink pour GStreamer, puis redémarrer OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Échec de l’initialisation du récepteur vidéo GStreamer natif sous Wayland. Veuillez vérifier l’installation de votre plugin GStreamer GTK." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Windows Media Player est nécessaire pour cette tâche ! Voulez-vous activer ‘Windows Media Player’ pour votre système d’exploitation ?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource n’a pas été correctement enregistré pour la lecture de médias ! Appuyez sur Oui pour le réenregistrer. Vous recevrez deux fois la demande de permission" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Composant BambuSource manquant pour la lecture multimédia ! Veuillez réinstaller OrcaSlicer ou demander de l'aide à la communauté." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Si vous utilisez une BambuSource provenant d’une autre installation, la lecture de la vidéo peut ne pas fonctionner correctement ! Appuyez sur Oui pour résoudre le problème." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Il manque à votre système les codecs H.264 pour GStreamer, qui sont nécessaires pour lire la vidéo. (Essayez d’installer les paquets gstreamer1.0-plugins-bad ou gstreamer1.0-libav, puis redémarrez Orca Slicer)." + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index e6dc44afcb..e0107db74f 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -8157,7 +8157,7 @@ msgstr "Egyedi beállítás" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11684,27 +11684,6 @@ msgstr "Filamentcsere öblítési mennyisége" msgid "Please choose the filament colour" msgstr "Kérlek, válaszd ki a filament színét" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "A natív Wayland élőképhez a GStreamer GTK videonyelő szükséges. Telepítsd a gtksink beépülő modult a GStreamerhez, majd indítsd újra az OrcaSlicert." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Nem sikerült inicializálni a natív Wayland GStreamer videonyelőt. Ellenőrizd a GStreamer GTK bővítmény telepítését." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Ehhez a művelethez Windows Media Player szükséges. Szeretnéd engedélyezni a \"Windows Media Player\"-t az operációs rendszerben?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "A BambuSource nincs megfelelően regisztrálva médialejátszáshoz. Kattints az Igen gombra az újbóli regisztráláshoz. Kétszer kapsz majd megerősítési kérést." - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "A médialejátszáshoz szükséges BambuSource-összetevő hiányzik. Kérlek, telepítsd újra az OrcaSlicert, vagy kérj segítséget a közösségtől." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Ha egy másik telepítésből származó BambuSource van használatban, előfordulhat, hogy a videólejátszás nem működik megfelelően. Kattints az Igen gombra a javításhoz." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "A rendszerből hiányoznak a GStreamer H.264 kodekjei, amelyek szükségesek a videolejátszáshoz. (Próbáld telepíteni a gstreamer1.0-plugins-bad vagy a gstreamer1.0-libav csomagokat, majd indítsd újra az Orca Slicert.)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "A felhőszolgáltatás nem érhető el. Indítsd újra az OrcaSlicert, majd próbáld újra." @@ -21898,6 +21877,27 @@ msgstr "" "Kunkorodás elkerülése\n" "Tudtad, hogy a kunkorodásra hajlamos anyagok (például ABS) nyomtatásakor az asztal hőmérsékletének növelése csökkentheti a kunkorodás valószínűségét?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "A natív Wayland élőképhez a GStreamer GTK videonyelő szükséges. Telepítsd a gtksink beépülő modult a GStreamerhez, majd indítsd újra az OrcaSlicert." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Nem sikerült inicializálni a natív Wayland GStreamer videonyelőt. Ellenőrizd a GStreamer GTK bővítmény telepítését." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Ehhez a művelethez Windows Media Player szükséges. Szeretnéd engedélyezni a \"Windows Media Player\"-t az operációs rendszerben?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "A BambuSource nincs megfelelően regisztrálva médialejátszáshoz. Kattints az Igen gombra az újbóli regisztráláshoz. Kétszer kapsz majd megerősítési kérést." + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "A médialejátszáshoz szükséges BambuSource-összetevő hiányzik. Kérlek, telepítsd újra az OrcaSlicert, vagy kérj segítséget a közösségtől." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Ha egy másik telepítésből származó BambuSource van használatban, előfordulhat, hogy a videólejátszás nem működik megfelelően. Kattints az Igen gombra a javításhoz." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "A rendszerből hiányoznak a GStreamer H.264 kodekjei, amelyek szükségesek a videolejátszáshoz. (Próbáld telepíteni a gstreamer1.0-plugins-bad vagy a gstreamer1.0-libav csomagokat, majd indítsd újra az Orca Slicert.)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 9c6edebbb7..26614fb5f4 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -8161,7 +8161,7 @@ msgstr "Profilo personalizzato" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11703,27 +11703,6 @@ msgstr "Volumi di spurgo per cambio filamento" msgid "Please choose the filament colour" msgstr "Scegliere il colore del filamento" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "La funzione di visualizzazione in tempo reale nativa di Wayland richiede il ricevitore video GTK di GStreamer. Installare il modulo gtksink per GStreamer e riavviare OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Impossibile inizializzare il ricevitore video nativo di Wayland GStreamer. Verificare l'installazione del modulo GTK di GStreamer." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Per questa operazione è necessario Windows Media Player! Desideri abilitare 'Windows Media Player' sul il tuo sistema operativo?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource non è stato registrato correttamente per la riproduzione multimediale! Fare clic su Sì per effettuare nuovamente la registrazione. Sarai promosso due volte" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Componente BambuSource mancante per la riproduzione multimediale! Reinstallare OrcaSlicer o cercare aiuto nella comunità." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "È in uso una versione di BambuSource da un'installazione diversa. La riproduzione video potrebbe non funzionare correttamente! Fare clic su Sì per risolvere il problema." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Nel tuo sistema mancano i codec H.264 per GStreamer, necessari per riprodurre i video. (Provare a installare i pacchetti gstreamer1.0-plugins-bad o gstreamer1.0-libav e riavviare OrcaSlicer?)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Il fornitore di servizi cloud non è disponibile. Riavviare OrcaSlicer e riprovare." @@ -21922,6 +21901,27 @@ msgstr "" "Evita le deformazioni\n" "Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "La funzione di visualizzazione in tempo reale nativa di Wayland richiede il ricevitore video GTK di GStreamer. Installare il modulo gtksink per GStreamer e riavviare OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Impossibile inizializzare il ricevitore video nativo di Wayland GStreamer. Verificare l'installazione del modulo GTK di GStreamer." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Per questa operazione è necessario Windows Media Player! Desideri abilitare 'Windows Media Player' sul il tuo sistema operativo?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource non è stato registrato correttamente per la riproduzione multimediale! Fare clic su Sì per effettuare nuovamente la registrazione. Sarai promosso due volte" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Componente BambuSource mancante per la riproduzione multimediale! Reinstallare OrcaSlicer o cercare aiuto nella comunità." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "È in uso una versione di BambuSource da un'installazione diversa. La riproduzione video potrebbe non funzionare correttamente! Fare clic su Sì per risolvere il problema." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Nel tuo sistema mancano i codec H.264 per GStreamer, necessari per riprodurre i video. (Provare a installare i pacchetti gstreamer1.0-plugins-bad o gstreamer1.0-libav e riavviare OrcaSlicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 25d81e9ccc..40f6e29686 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -8175,7 +8175,7 @@ msgstr "カスタマイズされたプリセット" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11723,33 +11723,6 @@ msgstr "フィラメントを入替える為のフラッシュ量" msgid "Please choose the filament colour" msgstr "フィラメントの色を選択してください" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "ネイティブWaylandのライブビューにはGStreamer GTKビデオシンクが必要です。GStreamer用のgtksinkプラグインをインストールし、OrcaSlicerを再起動してください。" - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "ネイティブWaylandのGStreamerビデオシンクの初期化に失敗しました。GStreamer GTKプラグインのインストール状況をご確認ください。" - -# AI Translated -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "このタスクにはWindows Media Playerが必要です!お使いのOSで「Windows Media Player」を有効にしますか?" - -# AI Translated -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "メディア再生用のBambuSourceが正しく登録されていません!「はい」を押して再登録してください。確認が2回表示されます" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "メディア再生用のBambuSourceコンポーネントが見つかりません!OrcaSlicerを再インストールするかコミュニティに助けを求めてください。" - -# AI Translated -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "別のインストール環境のBambuSourceを使用しているため、動画が正しく再生されない可能性があります!「はい」を押して修正してください。" - -# AI Translated -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "お使いのシステムには、動画再生に必要なGStreamer用のH.264コーデックがありません。(gstreamer1.0-plugins-badまたはgstreamer1.0-libavパッケージをインストールし、Orca Slicerを再起動してみてください)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "クラウドエージェントが利用できません。OrcaSlicerを再起動して再試行してください。" @@ -22485,6 +22458,33 @@ msgstr "" "反りを避ける\n" "ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "ネイティブWaylandのライブビューにはGStreamer GTKビデオシンクが必要です。GStreamer用のgtksinkプラグインをインストールし、OrcaSlicerを再起動してください。" + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "ネイティブWaylandのGStreamerビデオシンクの初期化に失敗しました。GStreamer GTKプラグインのインストール状況をご確認ください。" + +# AI Translated +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "このタスクにはWindows Media Playerが必要です!お使いのOSで「Windows Media Player」を有効にしますか?" + +# AI Translated +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "メディア再生用のBambuSourceが正しく登録されていません!「はい」を押して再登録してください。確認が2回表示されます" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "メディア再生用のBambuSourceコンポーネントが見つかりません!OrcaSlicerを再インストールするかコミュニティに助けを求めてください。" + +# AI Translated +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "別のインストール環境のBambuSourceを使用しているため、動画が正しく再生されない可能性があります!「はい」を押して修正してください。" + +# AI Translated +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "お使いのシステムには、動画再生に必要なGStreamer用のH.264コーデックがありません。(gstreamer1.0-plugins-badまたはgstreamer1.0-libavパッケージをインストールし、Orca Slicerを再起動してみてください)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index 3c2a65c4e7..4206d88f7a 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2025-06-02 17:12+0900\n" "Last-Translator: crwusiz \n" "Language-Team: \n" @@ -8193,7 +8193,7 @@ msgstr "사용자 정의 프리셋" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" # AI Translated @@ -11855,30 +11855,6 @@ msgstr "필라멘트 교체를 위한 버리기 볼륨" msgid "Please choose the filament colour" msgstr "필라멘트 색상을 선택하세요" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "네이티브 Wayland 실시간 보기에는 GStreamer GTK 비디오 싱크가 필요합니다. GStreamer용 gtksink 플러그인을 설치한 후 OrcaSlicer를 다시 시작하십시오." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "네이티브 Wayland GStreamer 비디오 싱크를 초기화하지 못했습니다. GStreamer GTK 플러그인 설치 상태를 확인하십시오." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "이 작업에는 Windows Media Player가 필요합니다! 운영 체제에서 Windows Media Player를 활성화하시겠습니까?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "뱀부소스가 미디어 재생에 올바르게 등록되지 않았습니다! 다시 등록하려면 예를 누르세요. 두 번 승격됩니다" - -# AI Translated -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "미디어 재생용으로 등록된 BambuSource 구성 요소가 없습니다! OrcaSlicer를 다시 설치하거나 커뮤니티에 도움을 요청하십시오." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "다른 설치 버전의 뱀부소스를 사용하면 동영상 재생이 제대로 작동하지 않을 수 있습니다! 예를 눌러 문제를 해결하세요." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "시스템에 동영상 재생을 위해 필요한 GStreamer용 H.264 코덱이 존재하지 않습니다. (gstreamer1.0-plugins-bad 또는 gstreamer1.0-libav 패키지를 설치한 다음 Orca Slicer를 다시 실행하십시오.)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "클라우드 에이전트를 사용할 수 없습니다. OrcaSlicer를 다시 시작한 후 다시 시도하십시오." @@ -22348,6 +22324,30 @@ msgstr "" "뒤틀림 방지\n" "ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "네이티브 Wayland 실시간 보기에는 GStreamer GTK 비디오 싱크가 필요합니다. GStreamer용 gtksink 플러그인을 설치한 후 OrcaSlicer를 다시 시작하십시오." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "네이티브 Wayland GStreamer 비디오 싱크를 초기화하지 못했습니다. GStreamer GTK 플러그인 설치 상태를 확인하십시오." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "이 작업에는 Windows Media Player가 필요합니다! 운영 체제에서 Windows Media Player를 활성화하시겠습니까?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "뱀부소스가 미디어 재생에 올바르게 등록되지 않았습니다! 다시 등록하려면 예를 누르세요. 두 번 승격됩니다" + +# AI Translated +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "미디어 재생용으로 등록된 BambuSource 구성 요소가 없습니다! OrcaSlicer를 다시 설치하거나 커뮤니티에 도움을 요청하십시오." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "다른 설치 버전의 뱀부소스를 사용하면 동영상 재생이 제대로 작동하지 않을 수 있습니다! 예를 눌러 문제를 해결하세요." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "시스템에 동영상 재생을 위해 필요한 GStreamer용 H.264 코덱이 존재하지 않습니다. (gstreamer1.0-plugins-bad 또는 gstreamer1.0-libav 패키지를 설치한 다음 Orca Slicer를 다시 실행하십시오.)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index c36a3aba40..a36ecd5cab 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -195,7 +195,6 @@ src/slic3r/GUI/ObjColorDialog.cpp src/slic3r/GUI/SyncAmsInfoDialog.cpp src/slic3r/GUI/WipeTowerDialog.cpp src/slic3r/GUI/wxExtensions.cpp -src/slic3r/GUI/wxMediaCtrl2.cpp src/slic3r/GUI/WebUserLoginDialog.cpp src/slic3r/GUI/WebGuideDialog.cpp src/slic3r/GUI/KBShortcutsDialog.hpp diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index e6fdc28d40..6dd82b476b 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-07-02 14:13+0300\n" "Last-Translator: Gintaras Kučinskas \n" "Language-Team: \n" @@ -8152,7 +8152,7 @@ msgstr "Pritaikytas profilis" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11630,27 +11630,6 @@ msgstr "Išmetimo tūris keičiant gijas" msgid "Please choose the filament colour" msgstr "Pasirinkite gijos spalvą" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Tiesioginei „Native Wayland“ peržiūrai reikalingas „GStreamer GTK“ vaizdo sinchronizatorius (video sink). Įdiekite „GStreamer“ skirtą „gtksink“ papildinį, tada iš naujo paleiskite „OrcaSlicer“." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Nepavyko inicijuoti „native Wayland GStreamer“ vaizdo sinchronizatoriaus (video sink). Patikrinkite „GStreamer GTK“ papildinio įdiegimą." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Šiai užduočiai atlikti reikalingas \"Windows Media Player\"! Ar norite įjungti \"Windows Media Player\" savo operacinėje sistemoje?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "„BambuSource“ neteisingai užregistruotas medijos atkūrimui! Paspauskite „Taip“, kad jį perregistruotumėte. Jums reikės patvirtinti du kartus." - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Trūksta BambuSource komponento, užregistruoto medijos atkūrimui! Iš naujo įdiekite OrcaSlicer arba kreipkitės pagalbos į bendruomenę." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Naudojant \"BambuSource\" iš kito diegimo šaltinio, vaizdo įrašų atkūrimas gali būti neteisingas! Paspauskite Taip, kad tai ištaisytumėte." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Jūsų sistemoje nėra \"GStreamer\" H.264 kodekų, reikalingų vaizdo įrašams atkurti. (Pabandykite įdiegti gstreamer1.0-plugins-bad arba gstreamer1.0-libav paketus, tada iš naujo paleiskite \"Orca Slicer\")" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Debesies agentas nepasiekiamas. Iš naujo paleiskite „OrcaSlicer“ ir bandykite vėl." @@ -21625,6 +21604,27 @@ msgstr "" "Venkite deformacijų (warping)\n" "Ar žinojote, kad spausdinant medžiagas, kurios yra linkusios trauktis ir riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas gali sumažinti deformacijų (warping) tikimybę?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Tiesioginei „Native Wayland“ peržiūrai reikalingas „GStreamer GTK“ vaizdo sinchronizatorius (video sink). Įdiekite „GStreamer“ skirtą „gtksink“ papildinį, tada iš naujo paleiskite „OrcaSlicer“." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Nepavyko inicijuoti „native Wayland GStreamer“ vaizdo sinchronizatoriaus (video sink). Patikrinkite „GStreamer GTK“ papildinio įdiegimą." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Šiai užduočiai atlikti reikalingas \"Windows Media Player\"! Ar norite įjungti \"Windows Media Player\" savo operacinėje sistemoje?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "„BambuSource“ neteisingai užregistruotas medijos atkūrimui! Paspauskite „Taip“, kad jį perregistruotumėte. Jums reikės patvirtinti du kartus." + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Trūksta BambuSource komponento, užregistruoto medijos atkūrimui! Iš naujo įdiekite OrcaSlicer arba kreipkitės pagalbos į bendruomenę." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Naudojant \"BambuSource\" iš kito diegimo šaltinio, vaizdo įrašų atkūrimas gali būti neteisingas! Paspauskite Taip, kad tai ištaisytumėte." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Jūsų sistemoje nėra \"GStreamer\" H.264 kodekų, reikalingų vaizdo įrašams atkurti. (Pabandykite įdiegti gstreamer1.0-plugins-bad arba gstreamer1.0-libav paketus, tada iš naujo paleiskite \"Orca Slicer\")" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index fd1aec7c3f..5ab0b10f55 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -8902,7 +8902,7 @@ msgstr "Aangepaste voorinstelling" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -12750,33 +12750,6 @@ msgstr "Volumes reinigen voor filament wijziging" msgid "Please choose the filament colour" msgstr "Kies de filamentkleur" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Voor de native Wayland-liveview is de GStreamer GTK-videosink nodig. Installeer de gtksink-plug-in voor GStreamer en start OrcaSlicer opnieuw." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Initialiseren van de native Wayland GStreamer-videosink is mislukt. Controleer de installatie van uw GStreamer GTK-plug-in." - -# AI Translated -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Voor deze taak is Windows Media Player vereist! Wilt u 'Windows Media Player' inschakelen voor uw besturingssysteem?" - -# AI Translated -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource is niet correct geregistreerd voor het afspelen van media! Klik op Ja om het opnieuw te registreren. U krijgt twee keer een melding" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Ontbrekend BambuSource-component geregistreerd voor media afspelen! Installeer OrcaSlicer opnieuw of zoek hulp in de community." - -# AI Translated -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Er wordt een BambuSource van een andere installatie gebruikt; het afspelen van video werkt mogelijk niet correct! Klik op Ja om dit te herstellen." - -# AI Translated -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Op uw systeem ontbreken H.264-codecs voor GStreamer, die nodig zijn om video af te spelen. (Probeer de pakketten gstreamer1.0-plugins-bad of gstreamer1.0-libav te installeren en Orca Slicer opnieuw te starten.)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "De cloudagent is niet beschikbaar. Start OrcaSlicer opnieuw en probeer het nogmaals." @@ -24072,6 +24045,33 @@ msgstr "" "Kromtrekken voorkomen\n" "Wist je dat bij het printen van materialen die gevoelig zijn voor kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het warmtebed de kans op kromtrekken kan verkleinen?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Voor de native Wayland-liveview is de GStreamer GTK-videosink nodig. Installeer de gtksink-plug-in voor GStreamer en start OrcaSlicer opnieuw." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Initialiseren van de native Wayland GStreamer-videosink is mislukt. Controleer de installatie van uw GStreamer GTK-plug-in." + +# AI Translated +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Voor deze taak is Windows Media Player vereist! Wilt u 'Windows Media Player' inschakelen voor uw besturingssysteem?" + +# AI Translated +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource is niet correct geregistreerd voor het afspelen van media! Klik op Ja om het opnieuw te registreren. U krijgt twee keer een melding" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Ontbrekend BambuSource-component geregistreerd voor media afspelen! Installeer OrcaSlicer opnieuw of zoek hulp in de community." + +# AI Translated +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Er wordt een BambuSource van een andere installatie gebruikt; het afspelen van video werkt mogelijk niet correct! Klik op Ja om dit te herstellen." + +# AI Translated +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Op uw systeem ontbreken H.264-codecs voor GStreamer, die nodig zijn om video af te spelen. (Probeer de pakketten gstreamer1.0-plugins-bad of gstreamer1.0-libav te installeren en Orca Slicer opnieuw te starten.)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index 7fa43e8993..fa92589e38 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer 2.3.0-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: \n" "Last-Translator: Krzysztof Morga <>\n" "Language-Team: \n" @@ -8351,7 +8351,7 @@ msgstr "Dostosowany profil" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -12028,30 +12028,6 @@ msgstr "Objętości płukania przy zmianie filamentu" msgid "Please choose the filament colour" msgstr "Proszę wybrać kolor filamentu" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Natywny podgląd na żywo w Wayland wymaga ujścia wideo GStreamer GTK. Zainstaluj wtyczkę gtksink dla GStreamer, a następnie uruchom ponownie OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Nie udało się zainicjować natywnego ujścia wideo GStreamer dla Wayland. Sprawdź instalację wtyczki GStreamer GTK." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Do wykonania tego zadania wymagany jest Windows Media Player! Czy włączyć „Windows Media Player” dla systemu operacyjnego?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource nie został poprawnie zarejestrowany do odtwarzania mediów! Naciśnij Tak, aby ponownie go zarejestrować. Będziesz poproszony dwa razy." - -# AI Translated -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Brak zarejestrowanego komponentu BambuSource do odtwarzania multimediów! Zainstaluj ponownie OrcaSlicer lub poszukaj pomocy w społeczności." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Jeśli używasz BambuSource z innej instalacji programu, odtwarzanie wideo może nie działać poprawnie! Naciśnij Tak, aby to naprawić." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Twój system nie posiada kodeków H.264 dla GStreamer, które są wymagane do odtwarzania wideo. (Spróbuj zainstalować pakiety gstreamer1.0-plugins-bad lub gstreamer1.0-libav, a następnie zrestartuj Orca Slicer?)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Agent chmury jest niedostępny. Uruchom ponownie OrcaSlicer i spróbuj jeszcze raz." @@ -22525,6 +22501,30 @@ msgstr "" "Unikaj odkształceń\n" "Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Natywny podgląd na żywo w Wayland wymaga ujścia wideo GStreamer GTK. Zainstaluj wtyczkę gtksink dla GStreamer, a następnie uruchom ponownie OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Nie udało się zainicjować natywnego ujścia wideo GStreamer dla Wayland. Sprawdź instalację wtyczki GStreamer GTK." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Do wykonania tego zadania wymagany jest Windows Media Player! Czy włączyć „Windows Media Player” dla systemu operacyjnego?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource nie został poprawnie zarejestrowany do odtwarzania mediów! Naciśnij Tak, aby ponownie go zarejestrować. Będziesz poproszony dwa razy." + +# AI Translated +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Brak zarejestrowanego komponentu BambuSource do odtwarzania multimediów! Zainstaluj ponownie OrcaSlicer lub poszukaj pomocy w społeczności." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Jeśli używasz BambuSource z innej instalacji programu, odtwarzanie wideo może nie działać poprawnie! Naciśnij Tak, aby to naprawić." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Twój system nie posiada kodeków H.264 dla GStreamer, które są wymagane do odtwarzania wideo. (Spróbuj zainstalować pakiety gstreamer1.0-plugins-bad lub gstreamer1.0-libav, a następnie zrestartuj Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index ceb095306d..f228caa195 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-07-26 11:14-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: Portuguese, Brazilian\n" @@ -7939,7 +7939,7 @@ msgstr "Predefinição Personalizada" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11387,27 +11387,6 @@ msgstr "Volumes de purga para troca de filamento" msgid "Please choose the filament colour" msgstr "Escolha a cor do filamento" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "A visualização ao vivo nativa do Wayland requer o receptor de vídeo GTK do GStreamer. Instale o plugin gtksink para GStreamer e reinicie o OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Falha ao inicializar o receptor de vídeo nativo do Wayland GStreamer. Verifique a instalação do plugin GStreamer GTK." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "O Windows Media Player é necessário para esta tarefa! Você quer habilitar o 'Windows Media Player' para seu sistema operacional?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource não foi registrado corretamente para reprodução de mídia! Pressione Sim para registrá-lo novamente. Você será promovido duas vezes" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Componente BambuSource registrado para reprodução de mídia não encontrado! Por favor, reinstale o OrcaSlicer ou procure ajuda da comunidade." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Usando um BambuSource de uma instalação diferente, a reprodução de vídeo pode não funcionar corretamente! Pressione Sim para consertar." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Seu sistema não possui codecs H.264 para o GStreamer, que são necessários para reproduzir vídeos. (Tente instalar os pacotes gstreamer1.0-plugins-bad ou gstreamer1.0-libav e depois reinicie o OrcaSlicer?)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "O agente na nuvem não está disponível. Reinicie o OrcaSlicer e tente novamente." @@ -21236,6 +21215,27 @@ msgstr "" "Evitar empenamento\n" "Você sabia que ao imprimir materiais propensos ao empenamento como ABS, aumentar adequadamente a temperatura da mesa aquecida pode reduzir a probabilidade de empenamento?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "A visualização ao vivo nativa do Wayland requer o receptor de vídeo GTK do GStreamer. Instale o plugin gtksink para GStreamer e reinicie o OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Falha ao inicializar o receptor de vídeo nativo do Wayland GStreamer. Verifique a instalação do plugin GStreamer GTK." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "O Windows Media Player é necessário para esta tarefa! Você quer habilitar o 'Windows Media Player' para seu sistema operacional?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource não foi registrado corretamente para reprodução de mídia! Pressione Sim para registrá-lo novamente. Você será promovido duas vezes" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Componente BambuSource registrado para reprodução de mídia não encontrado! Por favor, reinstale o OrcaSlicer ou procure ajuda da comunidade." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Usando um BambuSource de uma instalação diferente, a reprodução de vídeo pode não funcionar corretamente! Pressione Sim para consertar." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Seu sistema não possui codecs H.264 para o GStreamer, que são necessários para reproduzir vídeos. (Tente instalar os pacotes gstreamer1.0-plugins-bad ou gstreamer1.0-libav e depois reinicie o OrcaSlicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index fc26e99615..814a7e466d 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer V2.5.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+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 \n" @@ -8210,7 +8210,7 @@ msgstr "Пользовательский профиль" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11718,27 +11718,6 @@ msgstr "Объёмы прочистки при смене материала" msgid "Please choose the filament colour" msgstr "Изменение цвета" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Для нативного отображения трансляции в Wayland требуется gtksink (плагин для GStreamer). Установите необходимый пакет плагинов и перезапустите OrcaSlicer." - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Не удалось запустить нативную трансляцию GSteramer через Wayland. Проверьте наличие установленного пакета плагинов GStreamer." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Для этой задачи требуется Windows Media Player! Хотите включить его в своей ОС?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "Компонент BambuSource неправильно зарегистрирован для воспроизведения медиафайлов! Нажмите «Да», чтобы повторно зарегистрировать его" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Отсутствует компонент BambuSource для воспроизведения медиа. Переустановите OrcaSlicer или обратитесь за помощью к сообществу." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "При использовании компонентов BambuSource из другого инсталлятора, воспроизведение видео может работать некорректно! Нажмите «Да», чтобы исправить это." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "В вашей системе отсутствуют кодеки H.264 для GStreamer, которые необходимы для воспроизведения видео (попробуйте установить пакеты gstreamer1.0-plugins-bad или gstreamer1.0-libav, а затем перезапустить Orca Slicer)." - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Облачный агент недоступен. Перезапустите OrcaSlicer и повторите попытку." @@ -22270,6 +22249,27 @@ msgstr "" "Предотвращение коробления материала\n" "Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Для нативного отображения трансляции в Wayland требуется gtksink (плагин для GStreamer). Установите необходимый пакет плагинов и перезапустите OrcaSlicer." + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Не удалось запустить нативную трансляцию GSteramer через Wayland. Проверьте наличие установленного пакета плагинов GStreamer." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Для этой задачи требуется Windows Media Player! Хотите включить его в своей ОС?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "Компонент BambuSource неправильно зарегистрирован для воспроизведения медиафайлов! Нажмите «Да», чтобы повторно зарегистрировать его" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Отсутствует компонент BambuSource для воспроизведения медиа. Переустановите OrcaSlicer или обратитесь за помощью к сообществу." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "При использовании компонентов BambuSource из другого инсталлятора, воспроизведение видео может работать некорректно! Нажмите «Да», чтобы исправить это." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "В вашей системе отсутствуют кодеки H.264 для GStreamer, которые необходимы для воспроизведения видео (попробуйте установить пакеты gstreamer1.0-plugins-bad или gstreamer1.0-libav, а затем перезапустить Orca Slicer)." + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index 0e42c18f84..c15d4d5dad 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -8994,7 +8994,7 @@ msgstr "Anpassad inställning" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -12915,33 +12915,6 @@ msgstr "Rensnings volym för filament byte" msgid "Please choose the filament colour" msgstr "Välj filamentfärg" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Liveview i Wayland kräver GStreamers GTK-videosink. Installera insticksmodulen gtksink för GStreamer och starta sedan om OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Det gick inte att initiera Waylands GStreamer-videosink. Kontrollera installationen av din GStreamer GTK-insticksmodul." - -# AI Translated -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Windows Media Player krävs för den här uppgiften! Vill du aktivera 'Windows Media Player' i ditt operativsystem?" - -# AI Translated -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource har inte registrerats korrekt för mediauppspelning! Tryck på Ja för att registrera om den. Du får två frågor" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Saknad BambuSource-komponent registrerad för mediauppspelning! Installera om OrcaSlicer eller sök hjälp i gemenskapen." - -# AI Translated -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Du använder en BambuSource från en annan installation, videouppspelningen kanske inte fungerar korrekt! Tryck på Ja för att åtgärda det." - -# AI Translated -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Ditt system saknar H.264-kodekar för GStreamer, som krävs för att spela upp video. (Prova att installera paketen gstreamer1.0-plugins-bad eller gstreamer1.0-libav och starta sedan om Orca Slicer.)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Molnagenten är inte tillgänglig. Starta om OrcaSlicer och försök igen." @@ -24360,6 +24333,33 @@ msgstr "" "Undvik vridning\n" "Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Liveview i Wayland kräver GStreamers GTK-videosink. Installera insticksmodulen gtksink för GStreamer och starta sedan om OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Det gick inte att initiera Waylands GStreamer-videosink. Kontrollera installationen av din GStreamer GTK-insticksmodul." + +# AI Translated +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Windows Media Player krävs för den här uppgiften! Vill du aktivera 'Windows Media Player' i ditt operativsystem?" + +# AI Translated +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource har inte registrerats korrekt för mediauppspelning! Tryck på Ja för att registrera om den. Du får två frågor" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Saknad BambuSource-komponent registrerad för mediauppspelning! Installera om OrcaSlicer eller sök hjälp i gemenskapen." + +# AI Translated +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Du använder en BambuSource från en annan installation, videouppspelningen kanske inte fungerar korrekt! Tryck på Ja för att åtgärda det." + +# AI Translated +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Ditt system saknar H.264-kodekar för GStreamer, som krävs för att spela upp video. (Prova att installera paketen gstreamer1.0-plugins-bad eller gstreamer1.0-libav och starta sedan om Orca Slicer.)" + # AI Translated #~ msgid "" #~ "Layer height is too small.\n" diff --git a/localization/i18n/th/OrcaSlicer_th.po b/localization/i18n/th/OrcaSlicer_th.po index ec74d28213..52d6dc4a06 100644 --- a/localization/i18n/th/OrcaSlicer_th.po +++ b/localization/i18n/th/OrcaSlicer_th.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-06-19 13:40+0700\n" "Last-Translator: Icezaza\n" "Language-Team: Thai\n" @@ -8116,7 +8116,7 @@ msgstr "ค่าที่ตั้งไว้ล่วงหน้าที่ msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11601,27 +11601,6 @@ msgstr "ปริมาณการไล่เส้นชิ่งสำหร msgid "Please choose the filament colour" msgstr "กรุณาเลือกสีเส้นพลาสติก" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Native Wayland liveview ต้องใช้ GStreamer GTK video sink โปรดติดตั้งปลั๊กอิน gtksink สำหรับ GStreamer จากนั้นรีสตาร์ท OrcaSlicer" - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "ไม่สามารถเริ่มต้น sink วิดีโอ Wayland GStreamer ดั้งเดิมได้ โปรดตรวจสอบการติดตั้งปลั๊กอิน GStreamer GTK ของคุณ" - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "งานนี้ต้องใช้ Windows Media Player! คุณต้องการเปิดใช้งาน 'Windows Media Player' สำหรับระบบปฏิบัติการของคุณหรือไม่?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource ยังไม่ได้รับการลงทะเบียนอย่างถูกต้องสำหรับการเล่นสื่อ! กดใช่เพื่อลงทะเบียนใหม่ คุณจะได้รับการเลื่อนตำแหน่งสองครั้ง" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "ไม่มีส่วนประกอบ BambuSource ที่ลงทะเบียนสำหรับการเล่นสื่อ! โปรดติดตั้ง OrcaSlicer ใหม่หรือขอความช่วยเหลือจากชุมชน" - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "การใช้ BambuSource จากการติดตั้งอื่น การเล่นวิดีโออาจทำงานไม่ถูกต้อง! กดใช่เพื่อแก้ไข" - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "ระบบของคุณไม่มีตัวแปลงสัญญาณ H.264 สำหรับ GStreamer ซึ่งจำเป็นในการเล่นวิดีโอ (ลองติดตั้งแพ็คเกจ gstreamer1.0-plugins-bad หรือ gstreamer1.0-libav จากนั้นรีสตาร์ท Orca Slicer หรือไม่)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "ตัวแทนระบบคลาวด์ไม่พร้อมใช้งาน โปรดรีสตาร์ท OrcaSlicer แล้วลองอีกครั้ง" @@ -21652,6 +21631,27 @@ msgstr "" "หลีกเลี่ยงการบิดเบี้ยว\n" "คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Native Wayland liveview ต้องใช้ GStreamer GTK video sink โปรดติดตั้งปลั๊กอิน gtksink สำหรับ GStreamer จากนั้นรีสตาร์ท OrcaSlicer" + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "ไม่สามารถเริ่มต้น sink วิดีโอ Wayland GStreamer ดั้งเดิมได้ โปรดตรวจสอบการติดตั้งปลั๊กอิน GStreamer GTK ของคุณ" + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "งานนี้ต้องใช้ Windows Media Player! คุณต้องการเปิดใช้งาน 'Windows Media Player' สำหรับระบบปฏิบัติการของคุณหรือไม่?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource ยังไม่ได้รับการลงทะเบียนอย่างถูกต้องสำหรับการเล่นสื่อ! กดใช่เพื่อลงทะเบียนใหม่ คุณจะได้รับการเลื่อนตำแหน่งสองครั้ง" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "ไม่มีส่วนประกอบ BambuSource ที่ลงทะเบียนสำหรับการเล่นสื่อ! โปรดติดตั้ง OrcaSlicer ใหม่หรือขอความช่วยเหลือจากชุมชน" + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "การใช้ BambuSource จากการติดตั้งอื่น การเล่นวิดีโออาจทำงานไม่ถูกต้อง! กดใช่เพื่อแก้ไข" + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "ระบบของคุณไม่มีตัวแปลงสัญญาณ H.264 สำหรับ GStreamer ซึ่งจำเป็นในการเล่นวิดีโอ (ลองติดตั้งแพ็คเกจ gstreamer1.0-plugins-bad หรือ gstreamer1.0-libav จากนั้นรีสตาร์ท Orca Slicer หรือไม่)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index c3812dd93f..749c832a61 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-08-21 23:18+0300\n" "Last-Translator: GlauTech\n" "Language-Team: \n" @@ -8213,7 +8213,7 @@ msgstr "Özel Ayar" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11785,29 +11785,6 @@ msgstr "Filament değişimi için temizleme hacmi" msgid "Please choose the filament colour" msgstr "Lütfen filament rengini seçin" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Yerel Wayland canlı görüntüsü, GStreamer GTK video alıcısını gerektirir. Lütfen GStreamer için gtksink eklentisini yükleyin ve ardından OrcaSlicer'ı yeniden başlatın." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Yerel Wayland GStreamer video alıcısı başlatılamadı. Lütfen GStreamer GTK eklentisi kurulumunuzu denetleyin." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Bu görev için Windows Media Player gereklidir! İşletim sisteminiz için ‘Windows Media Player’ı etkinleştirmek istiyor musunuz?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource medya oynatımı için doğru şekilde kaydedilmemiş! Yeniden kaydetmek için Evet’e basın" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Medya oynatma için kayıtlı BambuSource bileşeni eksik! Lütfen OrcaSlicer'ı yeniden yükleyin veya topluluk yardımı isteyin." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Farklı bir kurulumdan bir BambuSource kullanıyorsunuz, video oynatma doğru çalışmayabilir! Düzeltmek için Evet’e basın." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Sisteminizde video oynatmak için gerekli olan GStreamer H.264 codec bileşenleri eksik. (gstreamer1.0-plugins-bad veya gstreamer1.0-libav paketlerini kurmayı deneyin, ardından Orca Slicer’ı yeniden başlatın)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Bulut aracısı kullanılamıyor. Lütfen OrcaSlicer'ı yeniden başlatıp yeniden deneyin." @@ -22109,6 +22086,29 @@ msgstr "" "Eğilmeyi önleyin\n" "ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Yerel Wayland canlı görüntüsü, GStreamer GTK video alıcısını gerektirir. Lütfen GStreamer için gtksink eklentisini yükleyin ve ardından OrcaSlicer'ı yeniden başlatın." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Yerel Wayland GStreamer video alıcısı başlatılamadı. Lütfen GStreamer GTK eklentisi kurulumunuzu denetleyin." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Bu görev için Windows Media Player gereklidir! İşletim sisteminiz için ‘Windows Media Player’ı etkinleştirmek istiyor musunuz?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource medya oynatımı için doğru şekilde kaydedilmemiş! Yeniden kaydetmek için Evet’e basın" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Medya oynatma için kayıtlı BambuSource bileşeni eksik! Lütfen OrcaSlicer'ı yeniden yükleyin veya topluluk yardımı isteyin." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Farklı bir kurulumdan bir BambuSource kullanıyorsunuz, video oynatma doğru çalışmayabilir! Düzeltmek için Evet’e basın." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Sisteminizde video oynatmak için gerekli olan GStreamer H.264 codec bileşenleri eksik. (gstreamer1.0-plugins-bad veya gstreamer1.0-libav paketlerini kurmayı deneyin, ardından Orca Slicer’ı yeniden başlatın)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index e8dd6dde4b..a282ce06cb 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: orcaslicerua\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-07-17 16:25+0300\n" "Last-Translator: Andrij Mizyk \n" "Language-Team: Ukrainian\n" @@ -8221,7 +8221,7 @@ msgstr "Пристосований пресет" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" # AI Translated @@ -11849,30 +11849,6 @@ msgstr "Обʼєми промивки для зміни філаменту" msgid "Please choose the filament colour" msgstr "Будь ласка, виберіть колір філаменту" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Нативний перегляд у Wayland потребує відеоприймача GStreamer GTK. Встановіть плагін gtksink для GStreamer, а потім перезапустіть OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Не вдалося ініціалізувати нативний відеоприймач GStreamer для Wayland. Перевірте встановлення плагіна GStreamer GTK." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Для виконання цього завдання потрібен Windows Media Player! Бажаєте увімкнути 'Windows Media Player' для вашої операційної системи?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource не було правильно зареєстровано для відтворення медіафайлів! Натисніть \"Так\", щоб зареєструвати його повторно. Вас буде сповіщено двічі" - -# AI Translated -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Відсутній компонент BambuSource, зареєстрований для відтворення медіа! Перевстановіть OrcaSlicer або зверніться по допомогу до спільноти." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Використовується BambuSource з іншої інсталяції, відтворення відео може працювати неправильно! Натисніть \"Так\", щоб виправити це." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Вашій системі бракує кодеків H.264 для GStreamer, які необхідні для відтворення відео. (Спробуйте встановити пакети gstreamer1.0-plugins-bad або gstreamer1.0-libav, а потім перезапустіть Orca Slicer?)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Хмарний агент недоступний. Перезапустіть OrcaSlicer і спробуйте ще раз." @@ -22270,6 +22246,30 @@ msgstr "" "Уникнення деформації\n" "Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури столу може зменшити ймовірність деформації?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Нативний перегляд у Wayland потребує відеоприймача GStreamer GTK. Встановіть плагін gtksink для GStreamer, а потім перезапустіть OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Не вдалося ініціалізувати нативний відеоприймач GStreamer для Wayland. Перевірте встановлення плагіна GStreamer GTK." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Для виконання цього завдання потрібен Windows Media Player! Бажаєте увімкнути 'Windows Media Player' для вашої операційної системи?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource не було правильно зареєстровано для відтворення медіафайлів! Натисніть \"Так\", щоб зареєструвати його повторно. Вас буде сповіщено двічі" + +# AI Translated +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Відсутній компонент BambuSource, зареєстрований для відтворення медіа! Перевстановіть OrcaSlicer або зверніться по допомогу до спільноти." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Використовується BambuSource з іншої інсталяції, відтворення відео може працювати неправильно! Натисніть \"Так\", щоб виправити це." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Вашій системі бракує кодеків H.264 для GStreamer, які необхідні для відтворення відео. (Спробуйте встановити пакети gstreamer1.0-plugins-bad або gstreamer1.0-libav, а потім перезапустіть Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/OrcaSlicer_vi.po index b5e5a5dc5f..d56f402d90 100644 --- a/localization/i18n/vi/OrcaSlicer_vi.po +++ b/localization/i18n/vi/OrcaSlicer_vi.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2025-10-02 17:43+0700\n" "Last-Translator: \n" "Language-Team: hainguyen.ts13@gmail.com\n" @@ -8627,7 +8627,7 @@ msgstr "Preset tùy chỉnh" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -12398,29 +12398,6 @@ msgstr "Khối lượng xả khi thay filament" msgid "Please choose the filament colour" msgstr "Vui lòng chọn màu filament" -# AI Translated -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "Xem trực tiếp trên Wayland thuần cần GStreamer GTK video sink. Vui lòng cài đặt plugin gtksink cho GStreamer, sau đó khởi động lại OrcaSlicer." - -# AI Translated -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "Khởi tạo GStreamer video sink trên Wayland thuần thất bại. Vui lòng kiểm tra việc cài đặt plugin GStreamer GTK của bạn." - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "Windows Media Player là cần thiết cho tác vụ này! Bạn có muốn bật 'Windows Media Player' cho hệ điều hành của bạn?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource chưa được đăng ký chính xác để phát media! Nhấn Có để đăng ký lại. Bạn sẽ được nhắc hai lần" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "Thiếu thành phần BambuSource đã đăng ký để phát media! Vui lòng cài đặt lại OrcaSlicer hoặc tìm kiếm sự giúp đỡ từ cộng đồng." - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "Đang sử dụng BambuSource từ cài đặt khác, phát video có thể không hoạt động đúng! Nhấn Có để sửa nó." - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "Hệ thống của bạn thiếu codec H.264 cho GStreamer, cần thiết để phát video. (Hãy thử cài đặt gói gstreamer1.0-plugins-bad hoặc gstreamer1.0-libav, sau đó khởi động lại Orca Slicer?)" - # AI Translated msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "Tác nhân cloud không khả dụng. Vui lòng khởi động lại OrcaSlicer rồi thử lại." @@ -22993,6 +22970,29 @@ msgstr "" "Tránh cong vênh\n" "Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?" +# AI Translated +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "Xem trực tiếp trên Wayland thuần cần GStreamer GTK video sink. Vui lòng cài đặt plugin gtksink cho GStreamer, sau đó khởi động lại OrcaSlicer." + +# AI Translated +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "Khởi tạo GStreamer video sink trên Wayland thuần thất bại. Vui lòng kiểm tra việc cài đặt plugin GStreamer GTK của bạn." + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "Windows Media Player là cần thiết cho tác vụ này! Bạn có muốn bật 'Windows Media Player' cho hệ điều hành của bạn?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource chưa được đăng ký chính xác để phát media! Nhấn Có để đăng ký lại. Bạn sẽ được nhắc hai lần" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "Thiếu thành phần BambuSource đã đăng ký để phát media! Vui lòng cài đặt lại OrcaSlicer hoặc tìm kiếm sự giúp đỡ từ cộng đồng." + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "Đang sử dụng BambuSource từ cài đặt khác, phát video có thể không hoạt động đúng! Nhấn Có để sửa nó." + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "Hệ thống của bạn thiếu codec H.264 cho GStreamer, cần thiết để phát video. (Hãy thử cài đặt gói gstreamer1.0-plugins-bad hoặc gstreamer1.0-libav, sau đó khởi động lại Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index 4787976785..622c27282d 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+0800\n" "PO-Revision-Date: 2026-06-11 12:37-0300\n" "Last-Translator: Handle \n" "Language-Team: \n" @@ -7947,7 +7947,7 @@ msgstr "自定义的预设" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11390,27 +11390,6 @@ msgstr "耗材丝更换时的冲刷体积" msgid "Please choose the filament colour" msgstr "请选择耗材丝颜色" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "原生 Wayland 实时画面需要 GStreamer GTK 视频接收器。请安装 GStreamer 的 gtksink 插件,然后重启 OrcaSlicer。" - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "原生 Wayland GStreamer 视频接收器初始化失败。请检查您的 GStreamer GTK 插件安装情况。" - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "此任务需要 Windows Media Player!您是否要为您的操作系统启用'Windows Media Player'?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "BambuSource 未正确注册用于媒体播放!按是重新注册它。您将被提示两次" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "缺少用于媒体播放的已注册 BambuSource 组件!请重新安装 OrcaSlicer 或寻求社区帮助。" - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "使用来自不同安装的 BambuSource,视频播放可能无法正常工作!按是修复它。" - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "您的系统缺少 GStreamer 所需的 H.264 编解码器,这是播放视频所必需的。(尝试安装 gstreamer1.0-plugins-bad 或 gstreamer1.0-libav 软件包,然后重新启动 Orca Slicer?)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "云代理不可用。请重启 OrcaSlicer 后重试。" @@ -21400,6 +21379,27 @@ msgstr "" "避免翘曲\n" "您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "原生 Wayland 实时画面需要 GStreamer GTK 视频接收器。请安装 GStreamer 的 gtksink 插件,然后重启 OrcaSlicer。" + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "原生 Wayland GStreamer 视频接收器初始化失败。请检查您的 GStreamer GTK 插件安装情况。" + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "此任务需要 Windows Media Player!您是否要为您的操作系统启用'Windows Media Player'?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "BambuSource 未正确注册用于媒体播放!按是重新注册它。您将被提示两次" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "缺少用于媒体播放的已注册 BambuSource 组件!请重新安装 OrcaSlicer 或寻求社区帮助。" + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "使用来自不同安装的 BambuSource,视频播放可能无法正常工作!按是修复它。" + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "您的系统缺少 GStreamer 所需的 H.264 编解码器,这是播放视频所必需的。(尝试安装 gstreamer1.0-plugins-bad 或 gstreamer1.0-libav 软件包,然后重新启动 Orca Slicer?)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index f9287d0886..b241a1aa58 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-28 12:15+0800\n" +"POT-Creation-Date: 2026-08-31 11:46+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" @@ -8108,7 +8108,7 @@ msgstr "自訂預設" msgid "Some published settings could not be applied:" msgstr "" -msgid "Some filament slots were changed to match the published materials:" +msgid "Some filament slots were changed:" msgstr "" msgid "Component name(s) inside step file not in UTF8 format!" @@ -11598,27 +11598,6 @@ msgstr "線材更換時產生的廢料體積" msgid "Please choose the filament colour" msgstr "請選擇線材顏色" -msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "原生 Wayland 即時檢視需要 GStreamer GTK 視訊接收器。請為 GStreamer 安裝 gtksink 外掛程式,然後重新啟動 OrcaSlicer。" - -msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "無法初始化原生 Wayland GStreamer 視訊接收器。請檢查您的 GStreamer GTK 外掛程式安裝。" - -msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" -msgstr "執行此設定需要 Windows Media Player!您是否要啟用 Windows Media Player?" - -msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" -msgstr "「BambuSource 未正確註冊為媒體播放模組!請點選『是』進行重新註冊,過程中會有兩次提示" - -msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." -msgstr "缺少用於媒體播放的已註冊 BambuSource 元件!請重新安裝 OrcaSlicer 或尋求社群協助。" - -msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." -msgstr "BambuSource 來自其他安裝版本,可能導致影片播放異常!請點選『是』進行修復。" - -msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" -msgstr "您的系統缺少 GStreamer 的 H.264 編解碼器,這是播放影片所必需的。(請嘗試安裝 gstreamer1.0-plugins-bad 或 gstreamer1.0-libav 套件,然後重新啟動 Orca Slicer。)" - msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "雲端代理無法使用。請重新啟動 OrcaSlicer 後再試一次。" @@ -21614,6 +21593,27 @@ msgstr "" "避免翹曲\n" "您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度可以降低翹曲的機率。" +#~ msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." +#~ msgstr "原生 Wayland 即時檢視需要 GStreamer GTK 視訊接收器。請為 GStreamer 安裝 gtksink 外掛程式,然後重新啟動 OrcaSlicer。" + +#~ msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." +#~ msgstr "無法初始化原生 Wayland GStreamer 視訊接收器。請檢查您的 GStreamer GTK 外掛程式安裝。" + +#~ msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" +#~ msgstr "執行此設定需要 Windows Media Player!您是否要啟用 Windows Media Player?" + +#~ msgid "BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice" +#~ msgstr "「BambuSource 未正確註冊為媒體播放模組!請點選『是』進行重新註冊,過程中會有兩次提示" + +#~ msgid "Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help." +#~ msgstr "缺少用於媒體播放的已註冊 BambuSource 元件!請重新安裝 OrcaSlicer 或尋求社群協助。" + +#~ msgid "Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it." +#~ msgstr "BambuSource 來自其他安裝版本,可能導致影片播放異常!請點選『是』進行修復。" + +#~ msgid "Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)" +#~ msgstr "您的系統缺少 GStreamer 的 H.264 編解碼器,這是播放影片所必需的。(請嘗試安裝 gstreamer1.0-plugins-bad 或 gstreamer1.0-libav 套件,然後重新啟動 Orca Slicer。)" + #~ msgid "" #~ "Layer height is too small.\n" #~ "It will set to min_layer_height\n" diff --git a/resources/images/live_stream_default.png b/resources/images/live_stream_default.png index 326ceaf994..c1aa90bf17 100644 Binary files a/resources/images/live_stream_default.png and b/resources/images/live_stream_default.png differ diff --git a/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml index d081e2f997..a3efaced8c 100644 --- a/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml +++ b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml @@ -318,6 +318,12 @@ modules: sha256: 0ba163956f2d468b19a91b96c5aba66ee9610843ea41dda628ea44cdafde7db7 dest: external-packages/wxInspector + # FFmpeg n7.0.3 + - type: file + url: https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.0.3.tar.gz + sha256: deedcabe339165214a3637df4c86a507aef0d793cf8774ff68735f4737e8ddbc + dest: external-packages/FFMPEG + # --------------------------------------------------------------- # Fallback archives for deps normally provided by the GNOME SDK. # These are only used if find_package() fails to locate them. diff --git a/scripts/linux.d/arch b/scripts/linux.d/arch index ead963e9a6..dc554b10b5 100644 --- a/scripts/linux.d/arch +++ b/scripts/linux.d/arch @@ -25,6 +25,9 @@ export REQUIRED_DEV_PACKAGES=( wayland-protocols webkit2gtk-4.1 wget + pkgconf + yasm + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/cachyos b/scripts/linux.d/cachyos index d491747ace..6137a3ef5c 100644 --- a/scripts/linux.d/cachyos +++ b/scripts/linux.d/cachyos @@ -25,6 +25,9 @@ export REQUIRED_DEV_PACKAGES=( wayland-protocols webkit2gtk wget + pkgconf + yasm + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/clear-linux-os b/scripts/linux.d/clear-linux-os index 149e805549..41ca68e835 100644 --- a/scripts/linux.d/clear-linux-os +++ b/scripts/linux.d/clear-linux-os @@ -20,6 +20,7 @@ export REQUIRED_BUNDLES=( perl-basic texinfo wget + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/debian b/scripts/linux.d/debian index f4d500760e..c33b24d2b7 100644 --- a/scripts/linux.d/debian +++ b/scripts/linux.d/debian @@ -27,6 +27,9 @@ REQUIRED_DEV_PACKAGES=( ninja-build texinfo wget + pkgconf + yasm + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/fedora b/scripts/linux.d/fedora index ca4eceaee3..993ea0b10a 100644 --- a/scripts/linux.d/fedora +++ b/scripts/linux.d/fedora @@ -31,6 +31,9 @@ REQUIRED_DEV_PACKAGES=( webkit2gtk4.1-devel wget libcurl-devel + pkgconf + yasm + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/gentoo b/scripts/linux.d/gentoo index f172ac92c3..f8554542ff 100644 --- a/scripts/linux.d/gentoo +++ b/scripts/linux.d/gentoo @@ -32,6 +32,9 @@ REQUIRED_DEV_PACKAGES=( sys-devel/m4 virtual/libudev x11-libs/gtk+:3 + dev-util/pkgconf + dev-lang/yasm + dev-lang/nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/scripts/linux.d/suse b/scripts/linux.d/suse index 1f4db45f46..682960650b 100644 --- a/scripts/linux.d/suse +++ b/scripts/linux.d/suse @@ -30,6 +30,9 @@ REQUIRED_DEV_PACKAGES=( webkit2gtk4-devel wget libcurl-devel + pkgconf + yasm + nasm ) if [[ -n "$UPDATE_LIB" ]] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0082b29831..0036af0a8c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,7 @@ if (SLIC3R_GUI) list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX expat) list(APPEND wxWidgets_LIBRARIES ${EXPAT_LIBRARIES}) endif () - + # This is an issue in the new wxWidgets cmake build, doesn't deal with librt find_library(LIBRT rt) if(LIBRT) @@ -294,6 +294,16 @@ if (WIN32) endif() else () + if (NOT APPLE) + set(output_sos_Release "") + set(output_sos_Debug "") + add_custom_target(OrcaSlicerSosCopy ALL DEPENDS OrcaSlicer) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + orcaslicer_copy_sos(OrcaSlicerSosCopy "Debug" "d" output_sos_Debug) + else() + orcaslicer_copy_sos(OrcaSlicerSosCopy "Release" "" output_sos_Release) + endif() + endif() if (APPLE AND NOT CMAKE_MACOSX_BUNDLE) # On OSX, the name of the binary matches the name of the Application. add_custom_command(TARGET OrcaSlicer POST_BUILD @@ -372,5 +382,9 @@ if (WIN32) install(FILES ${output_dlls_${build_type}} DESTINATION ".") install(DIRECTORY "${CMAKE_PREFIX_PATH}/libpython/" DESTINATION "python") else () + if (APPLE) + else() + install(FILES ${output_sos_${build_type}} DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() install(TARGETS OrcaSlicer RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}) endif () diff --git a/src/dev-utils/platform/unix/build_linux_image.sh.in b/src/dev-utils/platform/unix/build_linux_image.sh.in index 85134b764d..873cf2e1b1 100755 --- a/src/dev-utils/platform/unix/build_linux_image.sh.in +++ b/src/dev-utils/platform/unix/build_linux_image.sh.in @@ -83,6 +83,10 @@ copy_shared_object_to_dir() { src_real="$(readlink -f "$src")" dst_name="$(basename "$src_real")" mkdir -p "$dst_dir" + if [ "$src_real" = "$dst_dir/$dst_name" ]; then + # Already bundled; the dependency resolved from the bundle directory. + return 0 + fi cp -fL "$src_real" "$dst_dir/$dst_name" if [ -L "$src" ]; then @@ -96,12 +100,23 @@ copy_shared_object_to_dir() { } bundle_dependency_closure() { - local dst_dir="$1" + local dst_dir + dst_dir="$(cd -- "$1" && pwd)" shift local -a queue=("$@") - local target dep dep_real copied_path + local target dep dep_real dep_key copied_path declare -A seen=() + # Dependencies are resolved with ldd, which only searches the default + # loader path. Deps-built shared libraries (e.g. the FFmpeg stack) are not + # installed there and carry no RUNPATH of their own, so once copied into + # the bundle ldd can no longer resolve one sibling from another + # (libavcodec -> libavutil) and reports it as missing. Extend the loader + # path with the bundle directory plus the source directories of files + # already bundled, so every library that was resolved once keeps resolving + # for its own dependencies. The audit script does the same + # (scripts/check_appimage_libs.sh). + local -a search_dirs=("$dst_dir") while [ ${#queue[@]} -gt 0 ]; do target="${queue[0]}" @@ -122,17 +137,24 @@ bundle_dependency_closure() { continue fi - if [ -n "${seen[$dep_real]}" ]; then + # Key dedup on the bundled file rather than the source path: once + # ldd resolves a library from the bundle directory (via the + # LD_LIBRARY_PATH above) its path is a dst_dir path, which differs + # from the source path the first resolution returned. Keying on + # the source path would re-copy the file onto itself. + dep_key="$dst_dir/$(basename "$dep_real")" + if [ -n "${seen[$dep_key]}" ]; then continue fi - seen[$dep_real]=1 + seen[$dep_key]=1 copy_shared_object_to_dir "$dep" "$dst_dir" + search_dirs+=("$(dirname "$dep_real")") copied_path="$dst_dir/$(basename "$dep_real")" if [ -e "$copied_path" ]; then queue+=("$copied_path") fi - done < <(appimage_list_direct_dependencies "$target") + done < <(LD_LIBRARY_PATH="$(IFS=:; printf '%s' "${search_dirs[*]}")${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" appimage_list_direct_dependencies "$target") done } diff --git a/src/libslic3r/ArcFitter.cpp b/src/libslic3r/ArcFitter.cpp index cdfd708b10..46dd12931e 100644 --- a/src/libslic3r/ArcFitter.cpp +++ b/src/libslic3r/ArcFitter.cpp @@ -57,24 +57,24 @@ void ArcFitter::do_arc_fitting(const Points& points, std::vector 2) { //BBS: althought current point_stack can't be fit as arc, //but previous must can be fit if removing the top in stack, so save last arc - result.emplace_back(std::move(PathFittingData{ front_index, + result.emplace_back(PathFittingData{ front_index, back_index - 1, last_arc.direction == ArcDirection::Arc_Dir_CCW ? EMovePathType::Arc_move_ccw : EMovePathType::Arc_move_cw, - last_arc })); + last_arc }); } else { //BBS: save the first segment as line move when 3 point-line can't be fit as arc move if (result.empty() || result.back().path_type != EMovePathType::Linear_move) - result.emplace_back(std::move(PathFittingData{front_index, front_index + 1, EMovePathType::Linear_move, ArcSegment()})); + result.emplace_back(PathFittingData{front_index, front_index + 1, EMovePathType::Linear_move, ArcSegment()}); else if(result.back().path_type == EMovePathType::Linear_move) result.back().end_point_index = front_index + 1; } @@ -87,7 +87,7 @@ void ArcFitter::do_arc_fitting(const Points& points, std::vectorNbNodes(); ++aNodeIter) { gp_Pnt aPnt = aTriangulation->Node(aNodeIter); aPnt.Transform(aTrsf); - points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + points.emplace_back(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z())); } // BBS: copy triangles const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 1d901dad6f..ed88511d9c 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -8995,7 +8995,7 @@ private: BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " inital and interval = " << m_interval; m_next_backup = boost::get_system_time() + boost::posix_time::seconds(m_interval); boost::unique_lock lock(m_mutex); - m_thread = std::move(boost::thread(boost::ref(*this))); + m_thread = boost::thread(boost::ref(*this)); } ~_BBS_Backup_Manager() { diff --git a/src/libslic3r/Format/svg.cpp b/src/libslic3r/Format/svg.cpp index 7bfd73b987..7b720e62ef 100644 --- a/src/libslic3r/Format/svg.cpp +++ b/src/libslic3r/Format/svg.cpp @@ -352,7 +352,7 @@ bool load_svg(const char *path, Model *model, std::string &message) for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { gp_Pnt aPnt = aTriangulation->Node(aNodeIter); aPnt.Transform(aTrsf); - points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + points.emplace_back(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z())); } // BBS: copy triangles const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f28918f05d..e947be47a1 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -9079,7 +9079,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp continue; Polygons temp; - temp.emplace_back(std::move(instance_bbox.polygon())); + temp.emplace_back(instance_bbox.polygon()); if (intersection_pl(travel, temp).empty()) continue; diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp index 8b50681370..7497f92abf 100644 --- a/src/libslic3r/MeshBoolean.cpp +++ b/src/libslic3r/MeshBoolean.cpp @@ -352,7 +352,7 @@ void segment(CGALMesh& src, std::vector& dst, double smoothing_alpha = //} //else { - dst.emplace_back(std::move(CGALMesh(out))); + dst.emplace_back(CGALMesh(out)); } } //if (mesh_merged.is_empty() == false) { @@ -371,7 +371,7 @@ std::vector segment(const TriangleMesh& src, double smoothing_alph std::vector out_meshes; for (auto& outf_cgal_mesh: out_cgal_meshes) { - out_meshes.emplace_back(std::move(cgal_to_triangle_mesh(outf_cgal_mesh.m))); + out_meshes.emplace_back(cgal_to_triangle_mesh(outf_cgal_mesh.m)); } return out_meshes; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 995302e220..bfe88122cb 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -261,7 +261,7 @@ static void add_textured_mesh_to_model(Model& model, const TexturedMesh& tex_mes its_remove_degenerate_faces(its); its_compactify_vertices(its); - model.add_object(object_name.c_str(), input_file.c_str(), std::move(TriangleMesh(std::move(its)))); + model.add_object(object_name.c_str(), input_file.c_str(), TriangleMesh(std::move(its))); } Model Model::read_from_file(const std::string& input_file, diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 0e82046ce9..2a7e97a34e 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -5548,8 +5548,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, mixed_moves.emplace_back(size_t(authored_slot), size_t(entry.slot)); published_config->mixed_slot_relocations.emplace(authored_slot, entry.slot); published_config->material_replacements.emplace_back("slot " + std::to_string(authored_slot) + " -> slot " + - std::to_string(entry.slot) + - ": mixed filament relocated (would have replaced a physical filament)"); + std::to_string(entry.slot) + ": mixed filament"); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": published 3MF relocated mixed filament slot " << authored_slot << " -> " << entry.slot; ++entry_it; @@ -5570,8 +5569,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, (dest_slot != authored_slot ? "slot " + std::to_string(authored_slot) + " -> slot " + std::to_string(dest_slot) : "slot " + std::to_string(dest_slot)) + - ": " + material_label + " placed as an unassigned mixed filament (printer supports only " + - std::to_string(physical_capacity) + " filaments)"); + ": unassigned mixed filament (printer supports only " + std::to_string(physical_capacity) + " filaments)"); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": published 3MF material from slot " << authored_slot << " placed as an unassigned mixed filament at slot " << dest_slot << " (printer supports only " << physical_capacity << " filaments)"; @@ -5715,8 +5713,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, << entry.preset_name << "\", type \"" << entry.publish_type_value << "\")"; if (best_score >= 0 && best_score < 2 && (!entry.filament_id.empty() || !entry.filament_vendor.empty())) published_config->material_replacements.emplace_back("slot " + std::to_string(new_slot_idx) + ": " + - initial_preset + - " (substitute: no exact material match)"); + initial_preset + " (substitute)"); break; } // ...otherwise any visible preset not already used by another slot, @@ -5845,7 +5842,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, material_applied = true; // The re-point used to be silent; surface it like the other slot changes. published_config->material_replacements.emplace_back("slot " + std::to_string(slot) + ": " + aliased_name + " -> " + - replacement + " (de-aliased: shared profile)"); + replacement); } // Grow the per-slot colour/type/map project vectors to the new slot count and // seed the new entries so the slots render with colours instead of blank chips @@ -6118,7 +6115,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, this->filament_presets[slot] = new_name; material_applied = true; published_config->material_replacements.emplace_back("slot " + std::to_string(slot) + ": " + old_name + " -> " + - new_name + " (published material imported)"); + new_name); // Colour is slot-scoped and project-visible: sync into project_config // (the copy already baked it, this makes the chips render). if (entry.publish_color && !entry.color.empty()) { @@ -6241,7 +6238,7 @@ void PresetBundle::load_config_file_config(const std::string& name_or_path, // A pick that is not the exact published material is a substitute; // an entry without identity fields cannot be judged, so it stays plain. if (score < 2 && (!entry.filament_id.empty() || !entry.filament_vendor.empty())) - replacement_line += " (substitute: no exact material match)"; + replacement_line += " (substitute)"; published_config->material_replacements.emplace_back(std::move(replacement_line)); } else { // Partial publish with no replacement: keep the receiver's diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1bc1015477..40764342fb 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -3790,7 +3790,7 @@ std::vector Print::get_extruder_printable_polygons() const Polygons ploys = {Polygon::new_scale(e_printable_area)}; extruder_printable_polys.emplace_back(ploys); } - return std::move(extruder_printable_polys); + return extruder_printable_polys; } std::vector Print::get_extruder_unprintable_polygons() const @@ -3803,7 +3803,7 @@ std::vector Print::get_extruder_unprintable_polygons() const Polygons ploys = diff(printable_poly, Polygon::new_scale(e_printable_area)); extruder_unprintable_polys.emplace_back(ploys); } - return std::move(extruder_unprintable_polys); + return extruder_unprintable_polys; } size_t Print::get_extruder_id(unsigned int filament_id) const diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 8368de1a4f..7bc18f6b86 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -906,7 +906,7 @@ void PrintObject::detect_overhangs_for_lift() Layer& lower_layer = *layer.lower_layer; ExPolygons overhangs = diff_ex(layer.lslices, offset_ex(lower_layer.lslices, scale_(min_overlap))); - layer.loverhangs = std::move(offset2_ex(overhangs, -0.1f * scale_(line_width), 0.1f * scale_(line_width))); + layer.loverhangs = offset2_ex(overhangs, -0.1f * scale_(line_width), 0.1f * scale_(line_width)); layer.loverhangs_bbox = get_extents(layer.loverhangs); } }); diff --git a/src/libslic3r/Shape/TextShape.cpp b/src/libslic3r/Shape/TextShape.cpp index dce731af19..4f32b9d857 100644 --- a/src/libslic3r/Shape/TextShape.cpp +++ b/src/libslic3r/Shape/TextShape.cpp @@ -199,7 +199,7 @@ static void MakeMesh(TopoDS_Shape& theSolid, TriangleMesh& theMesh) for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { gp_Pnt aPnt = aTriangulation->Node(aNodeIter); aPnt.Transform(aTrsf); - points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + points.emplace_back(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z())); } //BBS: copy triangles const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index d4a43a4767..de08870216 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -842,7 +842,7 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/) // normal overhang ExPolygons lower_layer_offseted = offset_ex(lower_polys, support_offset_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS); - overhangs_all_layers[layer_nr] = std::move(diff_ex(curr_polys, lower_layer_offseted)); + overhangs_all_layers[layer_nr] = diff_ex(curr_polys, lower_layer_offseted); double duration{ std::chrono::duration_cast(clock_::now() - t0).count() }; if (duration > 30 || overhangs_all_layers[layer_nr].size() > 100) { @@ -1396,7 +1396,7 @@ void TreeSupport::generate_toolpaths() raft_areas.push_back(expoly); } - raft_areas = std::move(offset_ex(raft_areas, scale_(object_config.raft_first_layer_expansion))); + raft_areas = offset_ex(raft_areas, scale_(object_config.raft_first_layer_expansion)); size_t layer_nr = 0; for (; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) { @@ -1522,9 +1522,9 @@ void TreeSupport::generate_toolpaths() erSupportMaterialInterface : erSupportMaterial; make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow, brim_role); - polys = std::move(offset_ex(poly, -flow.scaled_spacing())); + polys = offset_ex(poly, -flow.scaled_spacing()); } else if (area_group.type == SupportLayer::Roof1stLayer) { - polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width())); + polys = offset_ex(poly, 0.5*support_flow.scaled_width()); } else { polys.push_back(poly); @@ -2269,7 +2269,7 @@ void TreeSupport::draw_circles() // Inside the gap: remove only the part overlapping the contact surface, keep the rest. if (bottom_gap_height > EPSILON && layer_bottom_z < band_gap_top - EPSILON) { any_gap_cleared = true; - comp_poly = std::move(diff_ex(comp_poly, band.surfaces)); + comp_poly = diff_ex(comp_poly, band.surfaces); } // Overlaps interface band @@ -2304,7 +2304,7 @@ void TreeSupport::draw_circles() ExPolygons comp_interface = band_ex.empty() ? ExPolygons {} : intersection_ex(comp_poly, band_ex); if (!comp_interface.empty()) { append(new_floor_areas, comp_interface); - comp_poly = std::move(diff_ex(comp_poly, offset_ex(comp_interface, 10))); + comp_poly = diff_ex(comp_poly, offset_ex(comp_interface, 10)); } } @@ -2396,7 +2396,7 @@ void TreeSupport::draw_circles() ts_layer->lslices.emplace_back(*expoly); } - ts_layer->lslices = std::move(union_ex(ts_layer->lslices)); + ts_layer->lslices = union_ex(ts_layer->lslices); //Must update bounding box which is used in avoid crossing perimeter ts_layer->lslices_bboxes.clear(); ts_layer->lslices_bboxes.reserve(ts_layer->lslices.size()); @@ -2474,7 +2474,7 @@ void TreeSupport::draw_circles() if (global_lightning_infill) { //search overhangs globally - overhang = std::move(diff_ex(offset_ex(base_areas_lower, -2.0 * scale_(support_extrusion_width)), base_areas)); + overhang = diff_ex(offset_ex(base_areas_lower, -2.0 * scale_(support_extrusion_width)), base_areas); } else { @@ -2485,13 +2485,13 @@ void TreeSupport::draw_circles() Polygon rev_hole = hole; rev_hole.make_counter_clockwise(); ExPolygons ex_hole; - ex_hole.emplace_back(std::move(ExPolygon(rev_hole))); + ex_hole.emplace_back(ExPolygon(rev_hole)); for (auto& other_area : base_areas) //if (&other_area != &base_area) - ex_hole = std::move(diff_ex(ex_hole, other_area)); - overhang = std::move(union_ex(overhang, ex_hole)); + ex_hole = diff_ex(ex_hole, other_area); + overhang = union_ex(overhang, ex_hole); } - overhang = std::move(intersection_ex(overhang, offset_ex(base_areas_lower, -0.5 * scale_(support_extrusion_width)))); + overhang = intersection_ex(overhang, offset_ex(base_areas_lower, -0.5 * scale_(support_extrusion_width))); } overhangs.emplace_back(to_polygons(overhang)); @@ -2746,7 +2746,7 @@ void TreeSupport::drop_nodes() m_object->print()->set_status(60 + int(10 * (1 - float(layer_nr) / contact_nodes.size())), _u8L("Generating support"));// (boost::format(_u8L("Support: propagate branches at layer %d")) % layer_nr).str()); - Polygons layer_contours = std::move(m_ts_data->get_contours_with_holes(obj_layer_nr)); + Polygons layer_contours = m_ts_data->get_contours_with_holes(obj_layer_nr); //std::unordered_map& mst_line_x_layer_contour_cache = m_mst_line_x_layer_contour_caches[layer_nr]; tbb::concurrent_unordered_map mst_line_x_layer_contour_cache; auto is_line_cut_by_contour = [&mst_line_x_layer_contour_cache,&layer_contours](Point a, Point b) @@ -3763,7 +3763,7 @@ const ExPolygons& TreeSupportData::calculate_avoidance(const RadiusLayerPair& ke } const ExPolygons &collision = get_collision(radius, layer_nr); avoidance_areas.insert(avoidance_areas.end(), collision.begin(), collision.end()); - avoidance_areas = std::move(union_ex(avoidance_areas)); + avoidance_areas = union_ex(avoidance_areas); auto ret = m_avoidance_cache.insert({key, std::move(avoidance_areas)}); //assert(ret.second); return ret.first->second; diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 6d505a231c..6ec5c92494 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -38,6 +38,8 @@ set(SLIC3R_GUI_SOURCES GUI/AuxiliaryDataViewModel.hpp GUI/AuxiliaryDialog.cpp GUI/AuxiliaryDialog.hpp + GUI/AVVideoDecoder.cpp + GUI/AVVideoDecoder.hpp GUI/Auxiliary.hpp GUI/BackgroundSlicingProcess.cpp GUI/BackgroundSlicingProcess.hpp @@ -615,6 +617,8 @@ set(SLIC3R_GUI_SOURCES GUI/WipeTowerDialog.cpp GUI/wxExtensions.cpp GUI/wxExtensions.hpp + GUI/wxMediaCtrl3.cpp + GUI/wxMediaCtrl3.h plugin/PythonInterpreter.cpp plugin/PythonInterpreter.hpp plugin/PythonPluginBridge.cpp @@ -803,21 +807,8 @@ if (APPLE) GUI/DeepLinkHandlerMac.mm GUI/DeepLinkHandlerMac.h GUI/GUI_UtilsMac.mm - GUI/wxMediaCtrl2.mm - GUI/wxMediaCtrl2.h ) FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration) -else () - list(APPEND SLIC3R_GUI_SOURCES - GUI/wxMediaCtrl2.cpp - GUI/wxMediaCtrl2.h - ) -endif () - -if (UNIX AND NOT APPLE) - list(APPEND SLIC3R_GUI_SOURCES - GUI/Printer/gstbambusrc.c - ) endif () set(ORCA_UPDATER_SIG_KEY_B64 "${ORCA_UPDATER_SIG_KEY}") @@ -917,6 +908,26 @@ if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY) add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE) 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. + 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.") + endif () + target_link_libraries(libslic3r_gui ${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 + libavcodec + libswscale + libavutil + ) + target_link_libraries(libslic3r_gui PkgConfig::LIBAV) +endif() + # We need to implement some hacks for wxWidgets and touch the underlying GTK # layer and sub-libraries. This forces us to use the include locations and # link these libraries. @@ -943,11 +954,6 @@ if (UNIX AND NOT APPLE) target_compile_definitions(libslic3r_gui PRIVATE wxHAVE_GDK_WAYLAND) endif () - # We add GStreamer for bambu:/// support. - pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0) - pkg_check_modules(GST_BASE REQUIRED gstreamer-base-1.0) - target_link_libraries(libslic3r_gui ${GSTREAMER_LIBRARIES} ${GST_BASE_LIBRARIES}) - target_include_directories(libslic3r_gui SYSTEM PRIVATE ${GSTREAMER_INCLUDE_DIRS} ${GST_BASE_INCLUDE_DIRS}) endif () # Add a definition so that we can tell we are compiling slic3r. diff --git a/src/slic3r/GUI/AVVideoDecoder.cpp b/src/slic3r/GUI/AVVideoDecoder.cpp new file mode 100644 index 0000000000..d7b8432bd3 --- /dev/null +++ b/src/slic3r/GUI/AVVideoDecoder.cpp @@ -0,0 +1,170 @@ +#include "AVVideoDecoder.hpp" + +#include + +extern "C" +{ + #include + #include +} + +AVVideoDecoder::AVVideoDecoder() +{ + codec_ctx_ = avcodec_alloc_context3(nullptr); +} + +AVVideoDecoder::~AVVideoDecoder() +{ + if (sws_ctx_) + sws_freeContext(sws_ctx_); + if (frame_) + av_frame_free(&frame_); + if (codec_ctx_) + avcodec_free_context(&codec_ctx_); +} + +int AVVideoDecoder::open(Bambu_StreamInfo const &info) +{ + auto codec_id = info.sub_type == AVC1 ? AV_CODEC_ID_H264 : AV_CODEC_ID_MJPEG; + auto codec = avcodec_find_decoder(codec_id); + if (codec == nullptr) { + fprintf(stderr, "AVVideoDecoder: unsupported codec!\n"); + return -1; // Codec not found + } + /* open the coderc */ + if (avcodec_open2(codec_ctx_, codec, nullptr) < 0) { + fprintf(stderr, "AVVideoDecoder: could not open codec\n"); + return -1; + } + + // Allocate an AVFrame structure + frame_ = av_frame_alloc(); + if (frame_ == nullptr) + return -1; + + return 0; +} + +int AVVideoDecoder::decode(const Bambu_Sample &sample) +{ + int ret = -1; + AVPacket *pkt = av_packet_alloc(); + if (!pkt) { + return ret; + } + + ret = av_new_packet(pkt, sample.size); + if (ret != 0) { + av_packet_free(&pkt); + return ret; + } + + memcpy(pkt->data, sample.buffer, size_t(sample.size)); + + ret = avcodec_send_packet(codec_ctx_, pkt); + if (ret == 0) { + got_frame_ = avcodec_receive_frame(codec_ctx_, frame_) == 0; + } + + av_packet_unref(pkt); + av_packet_free(&pkt); + return ret; +} + +int AVVideoDecoder::flush() +{ + int ret = avcodec_send_packet(codec_ctx_, nullptr); + got_frame_ = avcodec_receive_frame(codec_ctx_, frame_) == 0; + return ret; +} + +void AVVideoDecoder::close() +{ +} + +bool AVVideoDecoder::toWxImage(wxImage &image, wxSize const &size2) +{ + if (!got_frame_) + return false; + + auto size1 = size2; + if (!size1.IsFullySpecified()) + size1 = {frame_->width, frame_->height }; + auto size = size1; + if (size.GetWidth() & 0x0f) { + size.SetWidth((size.GetWidth() & ~0x0f) + 0x10); + if (size.GetWidth() != width_) { + std::fill(bits_.begin(), bits_.end(), 0); + width_ = size.GetWidth(); + } + } + AVPixelFormat wxFmt = AV_PIX_FMT_RGB24; + sws_ctx_ = sws_getCachedContext(sws_ctx_, + frame_->width, frame_->height, AVPixelFormat(frame_->format), + size1.GetWidth(), size1.GetHeight(), wxFmt, + SWS_GAUSS, + nullptr, nullptr, nullptr); + if (sws_ctx_ == nullptr) + return false; + int length = size.GetWidth() * size.GetHeight() * 3; + if (bits_.size() < length) + bits_.resize(length); + uint8_t * datas[] = { bits_.data() }; + int strides[] = { size.GetWidth() * 3 }; + int result_h = sws_scale(sws_ctx_, frame_->data, frame_->linesize, 0, frame_->height, datas, strides); + if (result_h != size.GetHeight()) { + return false; + } + // Copy: the frame outlives this decoder and is painted by the GUI thread while the + // next sws_scale is already overwriting bits_, so it must own its pixels. The Windows + // path below needs no equivalent, wxBitmap copies the bits into GDI. + image = wxImage(size.GetWidth(), size.GetHeight(), bits_.data(), true).Copy(); + if (!image.IsOk()) { + fprintf(stderr, "AVVideoDecoder: image not ok %dx%d\n", size.GetWidth(), size.GetHeight()); + return false; + } + return true; +} + +bool AVVideoDecoder::toWxBitmap(wxBitmap &bitmap, wxSize const &size2) +{ + if (!got_frame_) + return false; + + auto size1 = size2; + if (!size1.IsFullySpecified()) + size1 = {frame_->width, frame_->height }; + auto size = size1; + if (size.GetWidth() & 0x0f) { + size.SetWidth((size.GetWidth() & ~0x0f) + 0x10); + if (size.GetWidth() != width_) { + std::fill(bits_.begin(), bits_.end(), 0); + width_ = size.GetWidth(); + } + } + AVPixelFormat wxFmt = AV_PIX_FMT_RGB32; + sws_ctx_ = sws_getCachedContext(sws_ctx_, + frame_->width, frame_->height, AVPixelFormat(frame_->format), + size1.GetWidth(), size1.GetHeight(), wxFmt, + SWS_GAUSS, + nullptr, nullptr, nullptr); + if (sws_ctx_ == nullptr) + return false; + int length = size.GetWidth() * size.GetHeight() * 4; + if (bits_.size() < length) + bits_.resize(length); + uint8_t *datas[] = { bits_.data() }; + int strides[] = { size.GetWidth() * 4 }; + int result_h = sws_scale(sws_ctx_, frame_->data, frame_->linesize, 0, frame_->height, datas, strides); + if (result_h != size.GetHeight()) { + fprintf(stderr, "AVVideoDecoder: result_h %d %d\n", result_h, size.GetHeight()); + return false; + } + bitmap = wxBitmap((char const *) bits_.data(), size.GetWidth(), size.GetHeight(), 32); + assert(bitmap.IsOk()); + if (!bitmap.IsOk()) { + fprintf(stderr, "AVVideoDecoder: bitmap not ok %dx%d\n", size.GetWidth(), size.GetHeight()); + return false; + } + return true; +} diff --git a/src/slic3r/GUI/AVVideoDecoder.hpp b/src/slic3r/GUI/AVVideoDecoder.hpp new file mode 100644 index 0000000000..4111e860a2 --- /dev/null +++ b/src/slic3r/GUI/AVVideoDecoder.hpp @@ -0,0 +1,46 @@ +#ifndef AVVIDEODECODER_HPP +#define AVVIDEODECODER_HPP + +#include "Printer/BambuTunnel.h" + +extern "C" { + #include + #include +} +#include +#include +#include +#include + +class wxBitmap; + +class AVVideoDecoder +{ +public: + AVVideoDecoder(); + + ~AVVideoDecoder(); + +public: + int open(Bambu_StreamInfo const &info); + + int decode(Bambu_Sample const &sample); + + int flush(); + + void close(); + + bool toWxImage(wxImage &image, wxSize const &size); + + bool toWxBitmap(wxBitmap &bitmap, wxSize const & size); + +private: + AVCodecContext *codec_ctx_ = nullptr; + AVFrame * frame_ = nullptr; + SwsContext * sws_ctx_ = nullptr; + bool got_frame_ = false; + int width_ { 0 }; // scale result width + std::vector bits_; +}; + +#endif // AVVIDEODECODER_HPP diff --git a/src/slic3r/GUI/BambuPlayer/BambuPlayer.h b/src/slic3r/GUI/BambuPlayer/BambuPlayer.h deleted file mode 100644 index fe5f0d049a..0000000000 --- a/src/slic3r/GUI/BambuPlayer/BambuPlayer.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// BambuPlayer.h -// BambuPlayer -// -// Created by cmguo on 2021/12/6. -// - -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface BambuPlayer : NSObject - -+ (void) initialize; - -- (instancetype) initWithDisplayLayer: (AVSampleBufferDisplayLayer*) layer; -- (instancetype) initWithImageView: (NSView*) view; -- (int) open: (char const *) url; -- (NSSize) videoSize; -- (int) play; -- (void) stop; -- (void) close; - -- (void) setLogger: (void (*)(void const * context, int level, char const * msg)) logger withContext: (void const *) context; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 5850161a3e..eeaadd0cbd 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -2482,6 +2482,19 @@ static const ImWchar ranges_keyboard_shortcuts[] = }; #endif // __APPLE__ +// Names drawn through the atlas come from file names and CAD data, not from the UI language. +// GetGlyphRangesDefault() already gives every language the CJK ideographs, which is why a +// Chinese file name renders under an English UI; these are the alphabetic scripts it omits. +// Codepoints the font lacks are skipped at build time, so only existing glyphs cost anything. +static const ImWchar ranges_language_independent[] = +{ + 0x0100, 0x024F, // Latin Extended-A and Extended-B + 0x0370, 0x03FF, // Greek and Coptic + 0x0400, 0x04FF, // Cyrillic + 0x1E00, 0x1EFF, // Latin Extended Additional (Vietnamese) + 0, +}; + std::vector ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight) { @@ -2792,6 +2805,7 @@ void ImGuiWrapper::init_font(bool compress) ImFontAtlas::GlyphRangesBuilder builder; builder.AddRanges(m_glyph_ranges); builder.AddRanges(ImGui::GetIO().Fonts->GetGlyphRangesDefault()); + builder.AddRanges(ranges_language_independent); #ifdef __APPLE__ if (m_font_cjk) // Apple keyboard shortcuts are only contained in the CJK fonts. @@ -2813,12 +2827,17 @@ void ImGuiWrapper::init_font(bool compress) // Orca: temp fix for Korean font auto font_name_regular = "HarmonyOS_Sans_SC_Regular.ttf"; auto font_name_bold = "HarmonyOS_Sans_SC_Bold.ttf"; + // The Korean and Thai fonts cover their own script and little else, so they need the + // default font merged in behind them to reach the full range. + bool needs_glyph_fallback = false; if(m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesKorean()) { font_name_regular = "NanumGothic-Regular.ttf"; font_name_bold = "NanumGothic-Bold.ttf"; + needs_glyph_fallback = true; } else if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) { font_name_regular = "Sarabun-Medium.ttf"; font_name_bold = "Sarabun-SemiBold.ttf"; + needs_glyph_fallback = true; } default_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + font_name_regular).c_str(), m_font_size, &cfg, ranges.Data); if (default_font == nullptr) { @@ -2828,11 +2847,12 @@ void ImGuiWrapper::init_font(bool compress) } } - if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) { + // A merged font only supplies glyphs the font ahead of it lacks, so this fills the gaps + // without restyling anything the script font already covers. + if (needs_glyph_fallback) { ImFontConfig fallback_cfg = cfg; fallback_cfg.MergeMode = true; - static constexpr ImWchar celsius_range[] = { 0x2103, 0x2103, 0 }; - io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &fallback_cfg, celsius_range); + io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &fallback_cfg, ranges.Data); } bold_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + font_name_bold).c_str(), m_font_size, &cfg, ranges.Data); @@ -2841,11 +2861,10 @@ void ImGuiWrapper::init_font(bool compress) if (bold_font == nullptr) { throw Slic3r::RuntimeError("ImGui: Could not load deafult font"); } } - if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) { + if (needs_glyph_fallback) { ImFontConfig fallback_cfg = cfg; fallback_cfg.MergeMode = true; - static constexpr ImWchar celsius_range[] = { 0x2103, 0x2103, 0 }; - io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &fallback_cfg, celsius_range); + io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &fallback_cfg, ranges.Data); } if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) { @@ -2897,13 +2916,18 @@ void ImGuiWrapper::init_font(bool compress) glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_tex_size)); constexpr int max_retries = 6; for (int attempt = 0; attempt < max_retries && io.Fonts->TexHeight > gl_max_tex_size; ++attempt) { - io.Fonts->TexDesiredWidth = (io.Fonts->TexDesiredWidth > 0 ? io.Fonts->TexDesiredWidth : io.Fonts->TexWidth) * 2; + const int width = io.Fonts->TexDesiredWidth > 0 ? io.Fonts->TexDesiredWidth : io.Fonts->TexWidth; + // Both dimensions share the same limit, so widening past it would only trade an + // illegal height for an illegal width. + if (width * 2 > gl_max_tex_size) + break; + io.Fonts->TexDesiredWidth = width * 2; io.Fonts->Build(); } if (io.Fonts->TexHeight > gl_max_tex_size) { - // Shouldn't really happen - BOOST_LOG_TRIVIAL(error) << "Font atlas height " << io.Fonts->TexHeight - << " still exceeds GL_MAX_TEXTURE_SIZE (" << gl_max_tex_size << ")" + // Needs both a very large glyph set and a small GL_MAX_TEXTURE_SIZE. + BOOST_LOG_TRIVIAL(error) << "Font atlas " << io.Fonts->TexWidth << "x" << io.Fonts->TexHeight + << " does not fit GL_MAX_TEXTURE_SIZE (" << gl_max_tex_size << ")" << " after " << max_retries << " attempts; rendering may be incomplete"; } diff --git a/src/slic3r/GUI/ImageDPIFrame.cpp b/src/slic3r/GUI/ImageDPIFrame.cpp index 2133f18784..8dad9c44da 100644 --- a/src/slic3r/GUI/ImageDPIFrame.cpp +++ b/src/slic3r/GUI/ImageDPIFrame.cpp @@ -74,7 +74,7 @@ bool ImageDPIFrame::Show(bool show) } void ImageDPIFrame::set_bitmap(const wxBitmap &bit_map) { - if (&bit_map && bit_map.IsOk()) { + if (bit_map.IsOk()) { m_bitmap->SetBitmap(bit_map); } } diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 90e956be69..71fbcb054b 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -39,13 +39,14 @@ static std::map error_messages = { namespace Slic3r { namespace GUI { -MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const wxPoint &pos, const wxSize &size) +MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const wxPoint &pos, const wxSize &size) : wxPanel(parent, wxID_ANY, pos, size) , m_media_ctrl(media_ctrl) { SetLabel("MediaPlayCtrl"); SetBackgroundColour(*wxWHITE); m_media_ctrl->Bind(wxEVT_MEDIA_STATECHANGED, &MediaPlayCtrl::onStateChanged, this); + m_media_ctrl->SetIdleImage(from_u8(resources_dir() + "/images/live_stream_default.png")); m_button_play = new Button(this, "", "media_play", wxBORDER_NONE); m_button_play->SetCanFocus(false); @@ -177,13 +178,6 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj) if (machine == m_machine) { if (m_last_state == MEDIASTATE_IDLE && IsEnabled()) Play(); - else if (m_last_state == MEDIASTATE_LOADING && m_tutk_state == "disable" - && m_last_user_play + wxTimeSpan::Seconds(3) < wxDateTime::Now()) { - // resend ttcode to printer - if (auto agent = wxGetApp().getAgent()) - agent->get_camera_url(machine, [](auto) {}, wxGetApp().get_printer_cloud_provider()); - m_last_user_play = wxDateTime::Now(); - } return; } m_machine = machine; @@ -313,7 +307,7 @@ void MediaPlayCtrl::Play() // !m_lan_mode && !m_remote_proto && m_lan_proto == LVL_None (x) if (m_lan_proto <= MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto)) { - Stop(m_lan_proto == MachineObject::LVL_None + Stop(m_lan_proto == MachineObject::LVL_None ? _L("A problem occurred. Please update the printer firmware and try again.") : _L("LAN Only Liveview is off. Please turn on the liveview on printer screen.")); return; @@ -351,7 +345,7 @@ void MediaPlayCtrl::Play() url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_ver=" + std::string(SLIC3R_VERSION); } - BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: " << hide_passwd(url, + BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: " << hide_passwd(url, {"?uid=", "authkey=", "passwd=", "license=", "token="}); CallAfter([this, m, url] { if (m != m_machine) { @@ -426,7 +420,7 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2) auto tunnel = m_url.empty() ? "" : into_u8(wxURI(m_url).GetPath()).substr(1); if (auto n = tunnel.find_first_of("/_"); n != std::string::npos) tunnel = tunnel.substr(0, n); - if (last_state != wxMEDIASTATE_PLAYING && m_failed_code != 0 + if (last_state != wxMEDIASTATE_PLAYING && m_failed_code != 0 && m_last_failed_codes.find(m_failed_code) == m_last_failed_codes.end() && (m_user_triggered || m_failed_retry > 3)) { m_last_failed_codes.insert(m_failed_code); @@ -560,7 +554,7 @@ void MediaPlayCtrl::ToggleStream() url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_ver=" + std::string(SLIC3R_VERSION); } - BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::ToggleStream: " << hide_passwd(url, + BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::ToggleStream: " << hide_passwd(url, {"?uid=", "authkey=", "passwd=", "license=", "token="}); CallAfter([this, m, url] { if (m != m_machine) return; @@ -580,8 +574,8 @@ void MediaPlayCtrl::ToggleStream() }, wxGetApp().get_printer_cloud_provider()); } -void MediaPlayCtrl::msw_rescale() { - m_button_play->Rescale(); +void MediaPlayCtrl::msw_rescale() { + m_button_play->Rescale(); } void MediaPlayCtrl::jump_to_play() @@ -715,7 +709,9 @@ void MediaPlayCtrl::media_proc() break; } else if (url == "") { + BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start play"; m_media_ctrl->Play(); + BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: end play"; } else { BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start load"; @@ -771,15 +767,15 @@ bool MediaPlayCtrl::start_stream_service(bool *need_install) if (!boost::filesystem::exists(file_dll) || boost::filesystem::last_write_time(file_dll) != boost::filesystem::last_write_time(file_dll2)) boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_options::overwrite_existing); } - boost::process::child process_source(file_source, file_url2.ToStdWstring(), boost::process::start_dir(tools_dir), - boost::process::windows::create_no_window, + boost::process::child process_source(file_source, file_url2.ToStdWstring(), boost::process::start_dir(tools_dir), + boost::process::windows::create_no_window, boost::process::std_out > intermediate, boost::process::limit_handles); - boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::windows::create_no_window, + boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::windows::create_no_window, boost::process::std_in < intermediate, boost::process::limit_handles); #else boost::filesystem::permissions(file_source, boost::filesystem::owner_exe | boost::filesystem::add_perms); boost::filesystem::permissions(file_ffmpeg, boost::filesystem::owner_exe | boost::filesystem::add_perms); - boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir), + boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir), boost::process::std_out > intermediate, boost::process::limit_handles); boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate, boost::process::limit_handles); #endif @@ -830,27 +826,16 @@ bool MediaPlayCtrl::get_stream_url(std::string *url) }} -void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) +void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height) { -#ifdef __WXMAC__ - wxWindow::DoSetSize(x, y, width, height, sizeFlags); -#else - wxMediaCtrl::DoSetSize(x, y, width, height, sizeFlags); -#endif -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_gtk_video_window) { - const wxSize client_size = GetClientSize(); - m_gtk_video_window->SetSize(0, 0, client_size.GetWidth(), client_size.GetHeight()); - } -#endif - if (sizeFlags & wxSIZE_USE_EXISTING) return; - wxSize size = m_video_size; + wxSize size = videoSize; + if (!size.IsFullySpecified()) size = {16, 9}; int maxHeight = (width * size.GetHeight() + size.GetHeight() - 1) / size.GetWidth(); - if (maxHeight != GetMaxHeight()) { - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; - SetMaxSize({-1, maxHeight}); - CallAfter([this] { - if (auto p = GetParent()) { + if (maxHeight != ctrl->GetMaxHeight()) { + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl_OnSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; + ctrl->SetMaxSize({-1, maxHeight}); + ctrl->CallAfter([ctrl] { + if (auto p = ctrl->GetParent()) { p->Layout(); p->Refresh(); } diff --git a/src/slic3r/GUI/MediaPlayCtrl.h b/src/slic3r/GUI/MediaPlayCtrl.h index f5e5dcddfc..0a01daefc9 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.h +++ b/src/slic3r/GUI/MediaPlayCtrl.h @@ -8,7 +8,7 @@ #ifndef MediaPlayCtrl_h #define MediaPlayCtrl_h -#include "wxMediaCtrl2.h" +#include "wxMediaCtrl3.h" #include @@ -30,7 +30,7 @@ namespace GUI { class MediaPlayCtrl : public wxPanel { public: - MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); + MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); ~MediaPlayCtrl(); @@ -75,7 +75,7 @@ private: // token std::shared_ptr m_token = std::make_shared(0); - wxMediaCtrl2 * m_media_ctrl; + wxMediaCtrl3 * m_media_ctrl; wxMediaState m_last_state = MEDIASTATE_IDLE; std::string m_machine; int m_lan_proto = 0; @@ -90,7 +90,7 @@ private: bool m_device_busy = false; bool m_disable_lan = false; wxString m_url; - + std::deque m_tasks; boost::mutex m_mutex; boost::condition_variable m_cond; diff --git a/src/slic3r/GUI/MonitorBasePanel.h b/src/slic3r/GUI/MonitorBasePanel.h index c5c76acec3..42424a7187 100644 --- a/src/slic3r/GUI/MonitorBasePanel.h +++ b/src/slic3r/GUI/MonitorBasePanel.h @@ -34,7 +34,6 @@ #include "Widgets/AxisCtrlButton.hpp" #include "Widgets/TextInput.hpp" #include "Widgets/StaticLine.hpp" -#include "wxMediaCtrl2.h" #include "MediaPlayCtrl.h" /////////////////////////////////////////////////////////////////////////// diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 5e83ad845f..bfb9f50130 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -3360,9 +3360,9 @@ void NotificationManager::bbl_close_3mf_warn_notification() } } -void NotificationManager::bbl_show_3mf_warn_notification(const std::string &text) +void NotificationManager::bbl_show_3mf_warn_notification(const std::string &text, NotificationLevel level) { - NotificationData data{NotificationType::BBL3MFInfo, NotificationLevel::ErrorNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text}; + NotificationData data{NotificationType::BBL3MFInfo, level, BBL_NOTICE_MAX_INTERVAL, text}; for (std::unique_ptr ¬ification : m_pop_notifications) { if (notification->get_type() == NotificationType::BBL3MFInfo) { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index bf0a5cfe1a..d7a5d49977 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -378,7 +378,9 @@ public: void bbl_close_plateinfo_notification(); //BBS-- 3mf warning - void bbl_show_3mf_warn_notification(const std::string &text); + // level defaults to the historical error styling; callers reporting informational + // 3MF load notices (published settings) pass WarningNotificationLevel instead. + void bbl_show_3mf_warn_notification(const std::string &text, NotificationLevel level = NotificationLevel::ErrorNotificationLevel); void bbl_close_3mf_warn_notification(); //BBS--preview only mode diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3cadcae4b9..d2c9c3589f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3931,7 +3931,7 @@ bool Sidebar::reset_bed_type_combox_choices(bool is_sidebar_init) } } m_last_combo_bedtype_count = p->combo_printer_bed->GetCount(); - if (!is_sidebar_init && &p->plater->get_partplate_list()) { + if (!is_sidebar_init) { p->plater->get_partplate_list().check_all_plate_local_bed_type(m_cur_combox_bed_types); } return true; @@ -9062,25 +9062,25 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (load_model && !published_config.mixed_slot_relocations.empty()) Slic3r::remap_model_filament_slots(model, published_config.mixed_slot_relocations); - // BBS: notify the user about published settings that could not be applied. - // BBS: notify the user about published settings that could not be applied. if (!published_config.skipped_keys.empty()) { NotificationManager* notify_manager = q->get_notification_manager(); std::string message = _u8L("Some published settings could not be applied:"); for (const std::string& key : published_config.skipped_keys) message += "\n-" + key; - notify_manager->bbl_show_3mf_warn_notification(message); + // Informational: the load succeeded, these keys were skipped. + notify_manager->bbl_show_3mf_warn_notification(message, NotificationManager::NotificationLevel::WarningNotificationLevel); } // BBS: notify the user about slot materials that were replaced while // loading a published project (type mismatch / no same-type match). if (!published_config.material_replacements.empty()) { NotificationManager* notify_manager = q->get_notification_manager(); - std::string message = _u8L("Some filament slots were changed to match the published materials:"); + std::string message = _u8L("Some filament slots were changed:"); for (const std::string& replacement : published_config.material_replacements) message += "\n-" + replacement; - notify_manager->bbl_show_3mf_warn_notification(message); + // Informational: the load succeeded, the slots were adapted. + notify_manager->bbl_show_3mf_warn_notification(message, NotificationManager::NotificationLevel::WarningNotificationLevel); } ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type"); @@ -21869,9 +21869,9 @@ void Plater::show_object_info() int non_manifold_edges = 0; auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges); - if (non_manifold_edges > 0) { - info_manifold += into_u8("\n" + _L("Tips:") + "\n" + _L("Use \"Fix Model\" to repair the mesh.")); - } + if (non_manifold_edges > 0) { + info_manifold += "\n" + _L("Tips:") + "\n" + _L("Use \"Fix Model\" to repair the mesh."); + } info_manifold = "" + info_manifold + ""; info_text += into_u8(info_manifold); diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp index 8ecbe87391..0b280fe923 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp @@ -662,10 +662,10 @@ PrinterFileSystem::File const &PrinterFileSystem::GetFile(size_t index, bool &se void PrinterFileSystem::Attached() { boost::unique_lock lock(m_mutex); - m_recv_thread = std::move(boost::thread([w = weak_from_this()] { + m_recv_thread = boost::thread([w = weak_from_this()] { boost::shared_ptr s = w.lock(); if (s) s->RecvMessageThread(); - })); + }); } void PrinterFileSystem::Start() diff --git a/src/slic3r/GUI/Printer/gstbambusrc.c b/src/slic3r/GUI/Printer/gstbambusrc.c deleted file mode 100644 index d3f4ab112a..0000000000 --- a/src/slic3r/GUI/Printer/gstbambusrc.c +++ /dev/null @@ -1,657 +0,0 @@ -/* bambusrc for gstreamer - * integration with proprietary Bambu Lab blob for getting raw h.264 video - * - * Copyright (C) 2023 Joshua Wise - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "gstbambusrc.h" - -#include -#include -#ifndef EXTERNAL_GST_PLUGIN -#define BAMBU_DYNAMIC -#endif -#include "BambuTunnel.h" - -#ifdef BAMBU_DYNAMIC -// From PrinterFileSystem. -#ifdef __cplusplus -extern "C" -#else -extern -#endif -BambuLib *bambulib_get(); -BambuLib *_lib = NULL; -#define BAMBULIB(x) (_lib->x) - -#else -#define BAMBULIB(x) (x) -#endif - -GST_DEBUG_CATEGORY_STATIC (gst_bambusrc_debug); -#define GST_CAT_DEFAULT gst_bambusrc_debug - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - //GST_STATIC_CAPS("video/x-h264,framerate=0/1,parsed=(boolean)false,stream-format=(string)byte-stream")); - -enum -{ - PROP_0, - PROP_LOCATION, -}; - -static void gst_bambusrc_uri_handler_init (gpointer g_iface, - gpointer iface_data); -static void gst_bambusrc_finalize (GObject * gobject); -static void gst_bambusrc_dispose (GObject * gobject); - -static void gst_bambusrc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_bambusrc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstStateChangeReturn gst_bambusrc_change_state (GstElement * - element, GstStateChange transition); -static GstFlowReturn gst_bambusrc_create (GstPushSrc * psrc, - GstBuffer ** outbuf); -static gboolean gst_bambusrc_start (GstBaseSrc * bsrc); -static gboolean gst_bambusrc_stop (GstBaseSrc * bsrc); -static gboolean gst_bambusrc_is_seekable (GstBaseSrc * bsrc); -static gboolean gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query); -static gboolean gst_bambusrc_unlock (GstBaseSrc * bsrc); -static gboolean gst_bambusrc_unlock_stop (GstBaseSrc * bsrc); -static gboolean gst_bambusrc_set_location (GstBambuSrc * src, - const gchar * uri, GError ** error); - -#define gst_bambusrc_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (GstBambuSrc, gst_bambusrc, GST_TYPE_PUSH_SRC, - G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, - gst_bambusrc_uri_handler_init)); - -static void -gst_bambusrc_class_init (GstBambuSrcClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; - GstPushSrcClass *gstpushsrc_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; - gstpushsrc_class = (GstPushSrcClass *) klass; - - gobject_class->set_property = gst_bambusrc_set_property; - gobject_class->get_property = gst_bambusrc_get_property; - gobject_class->finalize = gst_bambusrc_finalize; - gobject_class->dispose = gst_bambusrc_dispose; - - g_object_class_install_property (gobject_class, - PROP_LOCATION, - g_param_spec_string ("location", "Location", - "URI to pass to Bambu Lab blobs", "", - (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - - gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); - - gst_element_class_set_static_metadata (gstelement_class, "Bambu Lab source", - "Source/Network", - "Receive data as a client over the network using the proprietary Bambu Lab blobs", - "Joshua Wise "); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_bambusrc_change_state); - - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_bambusrc_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_bambusrc_stop); - gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_bambusrc_unlock); - gstbasesrc_class->unlock_stop = - GST_DEBUG_FUNCPTR (gst_bambusrc_unlock_stop); - gstbasesrc_class->is_seekable = - GST_DEBUG_FUNCPTR (gst_bambusrc_is_seekable); - gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_bambusrc_query); - - gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_bambusrc_create); - - GST_DEBUG_CATEGORY_INIT (gst_bambusrc_debug, "bambusrc", 0, - "Bambu Lab src"); -} - -static void -gst_bambusrc_reset (GstBambuSrc * src) -{ - gst_caps_replace (&src->src_caps, NULL); - if (src->tnl) { - BAMBULIB(Bambu_Close)(src->tnl); - BAMBULIB(Bambu_Destroy)(src->tnl); - src->tnl = NULL; - } -} - -static void -gst_bambusrc_init (GstBambuSrc * src) -{ - src->location = NULL; - src->tnl = NULL; - - gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE); - gst_base_src_set_live(GST_BASE_SRC(src), TRUE); - - gst_bambusrc_reset (src); -} - -static void -gst_bambusrc_dispose (GObject * gobject) -{ - GstBambuSrc *src = GST_BAMBUSRC (gobject); - - GST_DEBUG_OBJECT (src, "dispose"); - - G_OBJECT_CLASS (parent_class)->dispose (gobject); -} - -static void -gst_bambusrc_finalize (GObject * gobject) -{ - GstBambuSrc *src = GST_BAMBUSRC (gobject); - - GST_DEBUG_OBJECT (src, "finalize"); - - g_free (src->location); - if (src->tnl) { - BAMBULIB(Bambu_Close)(src->tnl); - BAMBULIB(Bambu_Destroy)(src->tnl); - } - - G_OBJECT_CLASS (parent_class)->finalize (gobject); -} - -static void -gst_bambusrc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstBambuSrc *src = GST_BAMBUSRC (object); - - switch (prop_id) { - case PROP_LOCATION: - { - const gchar *location; - - location = g_value_get_string (value); - - if (location == NULL) { - GST_WARNING ("location property cannot be NULL"); - goto done; - } - if (!gst_bambusrc_set_location (src, location, NULL)) { - GST_WARNING ("badly formatted location"); - goto done; - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -done: - return; -} - -static void -gst_bambusrc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstBambuSrc *src = GST_BAMBUSRC (object); - - switch (prop_id) { - case PROP_LOCATION: - g_value_set_string (value, src->location); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -int gst_bambu_last_error = 0; - -static GstFlowReturn -gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf) -{ - GstBambuSrc *src; - - src = GST_BAMBUSRC (psrc); - - (void) src; - GST_DEBUG_OBJECT (src, "create()"); - - int rv; - Bambu_Sample sample; - - if (!src->tnl) { - return GST_FLOW_ERROR; - } - - while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) { - GST_DEBUG_OBJECT(src, "create would block"); - usleep(33333); /* 30Hz */ - } - - if (rv == Bambu_stream_end) { - return GST_FLOW_EOS; - } - - if (rv != Bambu_success) { - gst_bambu_last_error = rv; - return GST_FLOW_ERROR; - } - -#if GLIB_CHECK_VERSION(2,68,0) - gpointer sbuf = g_memdup2(sample.buffer, sample.size); -#else - gpointer sbuf = g_memdup(sample.buffer, sample.size); -#endif - *outbuf = gst_buffer_new_wrapped_full(0, sbuf, sample.size, 0, sample.size, sbuf, g_free); - - /* Synthesize monotonic timestamps at the announced frame rate, anchored - * to the first frame's arrival time. The X1C's RTSPS server emits - * unreliable decode timestamps (wildly non-monotonic jumps, or sometimes - * none at all); forwarding them directly froze the pipeline after a few - * seconds. Pacing on a synthesized clock — the same trick mpv uses when - * it reports "No video PTS! Making something up." — gives smooth - * playback regardless of network jitter, and only drops late frames if - * the printer can't keep up. A snap-back resets the anchor if real - * arrival drifts more than two frame periods from the synthesized - * timeline (e.g. announced framerate was wrong). - */ - GstClock *clock = GST_ELEMENT_CLOCK(psrc); - GstClockTime base_time = gst_element_get_base_time((GstElement *)psrc); - GstClockTime running_now = GST_CLOCK_TIME_NONE; - if (clock) { - GstClockTime now = gst_clock_get_time(clock); - if (now != GST_CLOCK_TIME_NONE && now >= base_time) - running_now = now - base_time; - } - - /* Adapt the period to actual inter-arrival time via EWMA. The announced - * frame_rate is unreliable on Bambu printers (X1C announces 30 but - * delivers ~28), so trusting it causes the synthesized timeline to drift - * relative to real time, which makes the sink consider frames late and - * skip pacing entirely. Measuring the real rate keeps PTS in step with - * arrival on average, so the sink can pace inside bursts while still - * tracking the printer's actual frame cadence. - */ - if (src->avg_period == 0) { - int fps = src->frame_rate > 0 ? src->frame_rate : 30; - src->avg_period = GST_SECOND / fps; - } - if (running_now != GST_CLOCK_TIME_NONE && src->last_arrival != 0) { - GstClockTimeDiff delta = GST_CLOCK_DIFF(src->last_arrival, running_now); - /* clamp to plausible video frame periods (5..200 ms) so a one-off - * burst-of-zero or long stall doesn't poison the average */ - if (delta > 5 * GST_MSECOND && delta < 200 * GST_MSECOND) { - src->avg_period = (src->avg_period * 15 + (GstClockTime)delta) / 16; - } - } - src->last_arrival = (running_now != GST_CLOCK_TIME_NONE) ? running_now : src->last_arrival; - GstClockTime period = src->avg_period; - - /* Lead time: schedule frames a few periods in the future of their - * arrival, so the sink has a small jitter buffer. Without this, frames - * arriving slightly later than expected land behind the running clock - * and the sink renders them immediately, producing visible stutter. - * 100ms is invisible for a live print-monitor view. - */ - const GstClockTime LEAD = 100 * GST_MSECOND; - - if (!src->sttime) { - src->sttime = (running_now != GST_CLOCK_TIME_NONE) ? running_now + LEAD : LEAD; - src->frame_count = 0; - } - - GstClockTime pts = src->sttime + src->frame_count * period; - - /* Safety net: with the lead applied, expected drift is roughly -LEAD - * (pts sits LEAD ns ahead of running_now). Re-anchor only if the - * synthesized timeline diverges from that expectation by several frame - * periods, which indicates a real disturbance (printer paused, stream - * resumed, large fps change) rather than ordinary jitter. - */ - if (running_now != GST_CLOCK_TIME_NONE) { - GstClockTimeDiff drift = GST_CLOCK_DIFF(pts, running_now); - GstClockTimeDiff expected = -(GstClockTimeDiff)LEAD; - GstClockTimeDiff slack = (GstClockTimeDiff)(4 * period); - if (drift > expected + slack || drift < expected - slack) { - GST_DEBUG_OBJECT(src, "ts drift %" G_GINT64_FORMAT " ns; re-anchoring", drift); - src->sttime = running_now + LEAD; - src->frame_count = 0; - pts = src->sttime; - } - } - - GST_BUFFER_PTS(*outbuf) = pts; - GST_BUFFER_DTS(*outbuf) = pts; - GST_BUFFER_DURATION(*outbuf) = period; - src->frame_count++; - GST_DEBUG_OBJECT(src, - "sttime:%lu, DTS:%lu, PTS: %lu~", - src->sttime, GST_BUFFER_DTS(*outbuf), GST_BUFFER_PTS(*outbuf)); - - return GST_FLOW_OK; -} - -static void _log(void *ctx, int lvl, const char *msg) { - GstBambuSrc *src = (GstBambuSrc *) ctx; - GST_DEBUG_OBJECT(src, "bambu: %s", msg); - BAMBULIB(Bambu_FreeLogMsg)(msg); -} - -static gboolean -gst_bambusrc_start (GstBaseSrc * bsrc) -{ - GstBambuSrc *src = GST_BAMBUSRC (bsrc); - - GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location); - - if (src->tnl) { - BAMBULIB(Bambu_Close)(src->tnl); - BAMBULIB(Bambu_Destroy)(src->tnl); - src->tnl = NULL; - } - -#ifdef BAMBU_DYNAMIC - if (!_lib) { - _lib = bambulib_get(); - if (!_lib->Bambu_Open) { - return FALSE; - } - } -#endif - if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) { - return FALSE; - } - - int rv = 0; - BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src); - if ((rv = BAMBULIB(Bambu_Open)(src->tnl)) != Bambu_success) { - BAMBULIB(Bambu_Destroy)(src->tnl); - src->tnl = NULL; - gst_bambu_last_error = rv; - return FALSE; - } - - int n = 0; - while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) { - usleep(100000); - } - if (rv != Bambu_success) { - BAMBULIB(Bambu_Close)(src->tnl); - BAMBULIB(Bambu_Destroy)(src->tnl); - src->tnl = NULL; - gst_bambu_last_error = rv; - return FALSE; - } - - src->video_type = AVC1; - n = BAMBULIB(Bambu_GetStreamCount)(src->tnl); - GST_INFO_OBJECT (src, "Bambu_GetStreamCount returned stream count=%d",n); - for (int i = 0; i < n; ++i) { - Bambu_StreamInfo info; - BAMBULIB(Bambu_GetStreamInfo)(src->tnl, i, &info); - - GST_INFO_OBJECT (src, "stream %d type=%d, sub_type=%d", i, info.type, info.sub_type); - if (info.type == VIDE) { - src->video_type = info.sub_type; - src->frame_rate = info.format.video.frame_rate; - GST_INFO_OBJECT (src, " width %d height=%d, frame_rate=%d", - info.format.video.width, info.format.video.height, info.format.video.frame_rate); - } - } - - src->sttime = 0; - src->frame_count = 0; - src->last_arrival = 0; - src->avg_period = 0; - return TRUE; -} - -static gboolean -gst_bambusrc_stop (GstBaseSrc * bsrc) -{ - GstBambuSrc *src; - - src = GST_BAMBUSRC (bsrc); - GST_DEBUG_OBJECT (src, "stop()"); - if (src->tnl) { - BAMBULIB(Bambu_Close)(src->tnl); - BAMBULIB(Bambu_Destroy)(src->tnl); - src->tnl = NULL; - } - - return TRUE; -} - -static GstStateChangeReturn -gst_bambusrc_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret; - GstBambuSrc *src; - - src = GST_BAMBUSRC (element); - - (void) src; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - //gst_bambusrc_session_close (src); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - return ret; -} - -/* Interrupt a blocking request. */ -static gboolean -gst_bambusrc_unlock (GstBaseSrc * bsrc) -{ - GstBambuSrc *src; - - src = GST_BAMBUSRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock()"); - - return TRUE; -} - -/* Interrupt interrupt. */ -static gboolean -gst_bambusrc_unlock_stop (GstBaseSrc * bsrc) -{ - GstBambuSrc *src; - - src = GST_BAMBUSRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock_stop()"); - - return TRUE; -} - -static gboolean -gst_bambusrc_is_seekable (GstBaseSrc * bsrc) -{ - GstBambuSrc *src = GST_BAMBUSRC (bsrc); - - (void) src; - - return FALSE; -} - -static gboolean -gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query) -{ - GstBambuSrc *src = GST_BAMBUSRC (bsrc); - gboolean ret; - GstSchedulingFlags flags; - gint minsize, maxsize, align; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_URI: - gst_query_set_uri (query, src->location); - ret = TRUE; - break; - default: - ret = FALSE; - break; - } - - if (!ret) - ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_SCHEDULING: - gst_query_parse_scheduling (query, &flags, &minsize, &maxsize, &align); - flags = (GstSchedulingFlags)((int)flags | (int)GST_SCHEDULING_FLAG_SEQUENTIAL); - gst_query_set_scheduling (query, flags, minsize, maxsize, align); - break; - default: - break; - } - - return ret; -} - -static gboolean -gst_bambusrc_set_location (GstBambuSrc * src, const gchar * uri, - GError ** error) -{ - if (src->location) { - g_free (src->location); - src->location = NULL; - } - - if (uri == NULL) - return FALSE; - - src->location = g_strdup (uri); - - return TRUE; -} - -static GstURIType -gst_bambusrc_uri_get_type (GType type) -{ - return GST_URI_SRC; -} - -static const gchar *const * -gst_bambusrc_uri_get_protocols (GType type) -{ - static const gchar *protocols[] = { "bambu", NULL }; - - return protocols; -} - -static gchar * -gst_bambusrc_uri_get_uri (GstURIHandler * handler) -{ - GstBambuSrc *src = GST_BAMBUSRC (handler); - - /* FIXME: make thread-safe */ - return g_strdup (src->location); -} - -static gboolean -gst_bambusrc_uri_set_uri (GstURIHandler * handler, const gchar * uri, - GError ** error) -{ - GstBambuSrc *src = GST_BAMBUSRC (handler); - - return gst_bambusrc_set_location (src, uri, error); -} - -static void -gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data) -{ - GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; - - iface->get_type = gst_bambusrc_uri_get_type; - iface->get_protocols = gst_bambusrc_uri_get_protocols; - iface->get_uri = gst_bambusrc_uri_get_uri; - iface->set_uri = gst_bambusrc_uri_set_uri; -} - -static gboolean gstbambusrc_init(GstPlugin *plugin) -{ - return gst_element_register(plugin, "bambusrc", GST_RANK_PRIMARY, GST_TYPE_BAMBUSRC); -} - -#ifndef EXTERNAL_GST_PLUGIN - -// for use inside of Bambu Slicer -void gstbambusrc_register() -{ - static int did_register = 0; - if (did_register) - return; - did_register = 1; - - gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio"); -} - -#else - -#ifndef PACKAGE -#define PACKAGE "bambusrc" -#endif - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, bambusrc, "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "https://github.com/bambulab/BambuStudio") - -#endif diff --git a/src/slic3r/GUI/Printer/gstbambusrc.h b/src/slic3r/GUI/Printer/gstbambusrc.h deleted file mode 100644 index d5c022a40e..0000000000 --- a/src/slic3r/GUI/Printer/gstbambusrc.h +++ /dev/null @@ -1,78 +0,0 @@ -/* bambusrc for gstreamer - * integration with proprietary Bambu Lab blob for getting raw h.264 video - * - * Copyright (C) 2023 Joshua Wise - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_BAMBUSRC_H__ -#define __GST_BAMBUSRC_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_BAMBUSRC (gst_bambusrc_get_type()) -G_DECLARE_FINAL_TYPE (GstBambuSrc, gst_bambusrc, - GST, BAMBUSRC, GstPushSrc) - -typedef void *Bambu_Tunnel; - -struct _GstBambuSrc -{ - GstPushSrc element; - GstCaps *src_caps; - gchar *location; - Bambu_Tunnel tnl; - GstClockTime sttime; - int video_type; - int frame_rate; - guint64 frame_count; - GstClockTime last_arrival; - GstClockTime avg_period; -}; - -extern void gstbambusrc_register(); - -G_END_DECLS - -#endif /* __GST_BAMBUSRC_H__ */ diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 2411967b0d..ac56e35ac3 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -483,7 +483,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) m_link_edit_nozzle->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { - if (this && this->m_is_in_sending_mode) { + if (m_is_in_sending_mode) { return; } diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp index 17da4b66a0..a63d96ffce 100644 --- a/src/slic3r/GUI/SendToPrinter.cpp +++ b/src/slic3r/GUI/SendToPrinter.cpp @@ -978,18 +978,16 @@ void SendToPrinterDialog::on_ok(wxCommandEvent &event) m_send_job->on_check_ip_address_fail([this, token = std::weak_ptr(m_token)](int result) { CallAfter([token, this] { if (token.expired()) { return; } - if (this) { - SendFailedConfirm sfcDlg; - auto res = sfcDlg.ShowModal(); - m_status_bar->cancel(); + SendFailedConfirm sfcDlg; + auto res = sfcDlg.ShowModal(); + m_status_bar->cancel(); - if (res == wxYES) { - wxQueueEvent(m_button_ensure, new wxCommandEvent(wxEVT_BUTTON)); - } else if (res == wxAPPLY) { - wxCommandEvent *evt = new wxCommandEvent(EVT_CLEAR_IPADDRESS); - wxQueueEvent(this, evt); - wxGetApp().show_ip_address_enter_dialog(); - } + if (res == wxYES) { + wxQueueEvent(m_button_ensure, new wxCommandEvent(wxEVT_BUTTON)); + } else if (res == wxAPPLY) { + wxCommandEvent *evt = new wxCommandEvent(EVT_CLEAR_IPADDRESS); + wxQueueEvent(this, evt); + wxGetApp().show_ip_address_enter_dialog(); } }); }); diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 43522f352b..f7bd41fe84 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -983,7 +983,7 @@ void PrintingTaskPanel::paint(wxPaintEvent&) dc.DrawBitmap(m_thumbnail_bmp_display, wxPoint(0, 0)); } dc.SetFont(Label::Body_12); - + if (m_plate_index >= 0) { wxString plate_id_str = wxString::Format("%d", m_plate_index); dc.DrawText(plate_id_str, wxPoint(4, 4)); @@ -1271,7 +1271,7 @@ void PrintingTaskPanel::set_plate_index(int plate_idx) } void PrintingTaskPanel::market_scoring_show() -{ +{ m_score_staticline->Show(); m_score_subtask_info->Show(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " show market scoring page"; @@ -1402,7 +1402,7 @@ void StatusBasePanel::init_bitmaps() m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 22); m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24); m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24); - + m_thumbnail_brokenimg = ScalableBitmap(this, "monitor_brokenimg", 120); m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120); //m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18); @@ -1530,7 +1530,7 @@ wxBoxSizer *StatusBasePanel::create_monitoring_page() // media_ctrl_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); // media_ctrl_panel->SetBackgroundColour(*wxBLACK); // wxBoxSizer *bSizer_monitoring = new wxBoxSizer(wxVERTICAL); - m_media_ctrl = new wxMediaCtrl2(this); + m_media_ctrl = new wxMediaCtrl3(this); m_media_ctrl->SetMinSize(wxSize(PAGE_MIN_WIDTH, FromDIP(288))); m_custom_camera_view = WebView::CreateWebView(this, wxEmptyString); @@ -2458,7 +2458,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_project_task_panel->get_pause_resume_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_project_task_panel->get_abort_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); m_project_task_panel->get_market_scoring_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this); - m_project_task_panel->get_market_retry_buttom()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); + m_project_task_panel->get_market_retry_buttom()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); m_project_task_panel->get_clean_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this); m_setting_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this); @@ -2520,7 +2520,7 @@ StatusPanel::~StatusPanel() m_project_task_panel->get_pause_resume_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_project_task_panel->get_abort_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); m_project_task_panel->get_market_scoring_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this); - m_project_task_panel->get_market_retry_buttom()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); + m_project_task_panel->get_market_retry_buttom()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); m_project_task_panel->get_clean_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this); m_setting_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this); @@ -2566,7 +2566,7 @@ StatusPanel::~StatusPanel() if (sdcard_hint_dlg != nullptr) delete sdcard_hint_dlg; - if (m_score_data != nullptr) { + if (m_score_data != nullptr) { delete m_score_data; } } @@ -2590,7 +2590,7 @@ void StatusPanel::init_scaled_buttons() m_bpButton_e_down_10->SetCornerRadius(FromDIP(12)); } -void StatusPanel::on_market_scoring(wxCommandEvent &event) { +void StatusPanel::on_market_scoring(wxCommandEvent &event) { if (obj && obj->is_makeworld_subtask() && obj->rating_info && obj->rating_info->request_successful) { // model is mall model and has rating_id BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_market_scoring" ; if (m_score_data && m_score_data->rating_id == obj->rating_info->rating_id) { // current score data for model is same as mall model @@ -2599,7 +2599,7 @@ void StatusPanel::on_market_scoring(wxCommandEvent &event) { int ret = m_score_dlg.ShowModal(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data"; - if (ret == wxID_OK) { + if (ret == wxID_OK) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data is upload"; m_score_data->rating_id = -1; m_project_task_panel->set_star_count_dirty(false); @@ -2621,11 +2621,11 @@ void StatusPanel::on_market_scoring(wxCommandEvent &event) { std::string comment = obj->rating_info->content; if (!comment.empty()) { m_score_dlg.set_comment(comment); } - + std::vector images_json_array; images_json_array = obj->rating_info->image_url_paths; if (!images_json_array.empty()) m_score_dlg.set_cloud_bitmap(images_json_array); - + int ret = m_score_dlg.ShowModal(); if (ret == wxID_OK) { @@ -3651,14 +3651,14 @@ void StatusPanel::update_basic_print_data(bool def) void StatusPanel::update_model_info() { auto get_subtask_fn = [this](BBLModelTask* subtask) { - CallAfter([this, subtask]() { + CallAfter([this, subtask]() { if (obj && obj->subtask_id_ == subtask->task_id) { obj->set_modeltask(subtask); } }); }; - + if (wxGetApp().getAgent() && obj) { BBLSubTask* curr_task = obj->get_subtask(); if (curr_task) { @@ -3982,7 +3982,7 @@ void StatusPanel::reset_printing_values() m_project_task_panel->update_left_time(NA_STR); m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR)); update_calib_bitmap(); - + task_thumbnail_state = ThumbnailState::PLACE_HOLDER; m_start_loading_thumbnail = false; m_load_sdcard_thumbnail = false; @@ -4037,7 +4037,7 @@ bool StatusPanel::check_axis_z_at_home(MachineObject* obj) } void StatusPanel::on_axis_ctrl_z_up_10(wxCommandEvent &event) -{ +{ if (obj) { obj->command_axis_control("Z", 1.0, -10.0f, 900); if (!check_axis_z_at_home(obj)) @@ -5396,7 +5396,7 @@ void StatusPanel::msw_rescale() m_calibration_btn->Rescale(); m_options_btn->SetMinSize(wxSize(-1, FromDIP(26))); - m_options_btn->Rescale(); + m_options_btn->Rescale(); m_safety_btn->SetMinSize(wxSize(-1, FromDIP(26))); m_safety_btn->Rescale(); @@ -5578,11 +5578,11 @@ ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data) , m_upload_status_code(StatusCode::CODE_NUMBER) { m_tocken.reset(new int(0)); - + wxBoxSizer *m_main_sizer = get_main_sizer(score_data->local_to_url_image, score_data->comment_text); m_image_url_paths = score_data->image_url_paths; - + this->SetSizer(m_main_sizer); Fit(); @@ -5598,16 +5598,16 @@ void ScoreDialog::on_dpi_changed(const wxRect &suggested_rect) {} void ScoreDialog::OnBitmapClicked(wxMouseEvent &event) { wxStaticBitmap *clickedBitmap = dynamic_cast(event.GetEventObject()); - if (m_image.find(clickedBitmap) != m_image.end()) { + if (m_image.find(clickedBitmap) != m_image.end()) { if (!m_image[clickedBitmap].is_selected) { - for (auto panel : m_image[clickedBitmap].image_broad) { + for (auto panel : m_image[clickedBitmap].image_broad) { panel->Show(); } m_image[clickedBitmap].is_selected = true; m_selected_image_list.insert(clickedBitmap); } else { - for (auto panel : m_image[clickedBitmap].image_broad) { - panel->Hide(); + for (auto panel : m_image[clickedBitmap].image_broad) { + panel->Hide(); } m_image[clickedBitmap].is_selected = false; m_selected_image_list.erase(clickedBitmap); @@ -5624,9 +5624,9 @@ void ScoreDialog::OnBitmapClicked(wxMouseEvent &event) } std::set > ScoreDialog::add_need_upload_imgs() -{ +{ std::set> need_upload_images; - for (auto bitmap : m_image) { + for (auto bitmap : m_image) { if (!bitmap.second.is_uploaded) { wxString &local_image_path = bitmap.second.local_image_url; if (!local_image_path.empty()) { need_upload_images.insert(std::make_pair(bitmap.first, local_image_path)); } @@ -5646,7 +5646,7 @@ std::pair ScoreDialog::create_local_thu cur_image_msg.local_image_url = local_path; cur_image_msg.img_url_paths = ""; cur_image_msg.is_uploaded = false; - + wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(local_path, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition, wxDefaultSize, 0); imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this); @@ -5711,7 +5711,7 @@ void ScoreDialog::update_static_bitmap(wxStaticBitmap* static_bitmap, wxImage im } wxBoxSizer *ScoreDialog::create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg& cur_image_msg) -{ +{ // tb: top and bottom lr: left and right auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL); auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); @@ -5755,7 +5755,7 @@ void ScoreDialog::init() { fail_image = wxImage(Slic3r::resources_dir() + "/images/oss_picture_load_failed.png", wxBITMAP_TYPE_ANY); } -wxBoxSizer *ScoreDialog::get_score_sizer() { +wxBoxSizer *ScoreDialog::get_score_sizer() { wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Rate"), wxDefaultPosition, wxDefaultSize, 0); static_score_text->Wrap(-1); @@ -5878,18 +5878,18 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() { for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful bool is_repeat = false; for (auto image : m_image) { - if (filePaths[i] == image.second.local_image_url) { + if (filePaths[i] == image.second.local_image_url) { is_repeat = true; continue; } } if (!is_repeat) { local_path.push_back(std::make_pair(filePaths[i], "")); - if (local_path.size() + m_image.size() > m_photo_nums) { - break; + if (local_path.size() + m_image.size() > m_photo_nums) { + break; } } - + } load_photo(local_path); @@ -6007,7 +6007,7 @@ wxBoxSizer *ScoreDialog::get_button_sizer() } } progress_dialog->Hide(); - if (progress_dialog) { + if (progress_dialog) { delete progress_dialog; progress_dialog = nullptr; } @@ -6141,7 +6141,7 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const std::vectorAdd(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8)); m_image_sizer = new wxGridSizer(5, FromDIP(5), FromDIP(5)); - if (!images.empty()) { + if (!images.empty()) { load_photo(images); } m_main_sizer->Add(m_image_sizer, 0, wxEXPAND | wxLEFT, FromDIP(24)); @@ -6153,7 +6153,7 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const std::vectorGetValue(); score_data.image_url_paths = m_image_url_paths; for (auto img : m_image) { score_data.local_to_url_image.push_back(std::make_pair(img.second.local_image_url, img.second.img_url_paths)); } - + return score_data; } void ScoreDialog::set_comment(std::string comment) { - if (m_comment_text) { + if (m_comment_text) { m_comment_text->SetValue(wxString::FromUTF8(comment)); } } void ScoreDialog::set_cloud_bitmap(std::vector cloud_bitmaps) -{ +{ m_image_url_paths = cloud_bitmaps; for (std::string &url : cloud_bitmaps) { if (std::string::npos == url.find(m_model_id)) continue; diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index d0c8c99f49..341bb9ab69 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -14,7 +14,6 @@ #include #include #include -#include "wxMediaCtrl2.h" #include "MediaPlayCtrl.h" #include "AMSSetting.hpp" #include "Calibration.hpp" @@ -195,11 +194,11 @@ public: void set_cloud_bitmap(std::vector cloud_bitmaps); protected: - enum StatusCode { - UPLOAD_PROGRESS = 0, - UPLOAD_EXIST_ISSUE, + enum StatusCode { + UPLOAD_PROGRESS = 0, + UPLOAD_EXIST_ISSUE, UPLOAD_IMG_FAILED, - CODE_NUMBER + CODE_NUMBER }; std::shared_ptr m_tocken; @@ -217,7 +216,7 @@ protected: { wxString local_image_url; //local image path std::string img_url_paths; // oss url path - vector image_broad; + vector image_broad; bool is_selected; bool is_uploaded; // load wxBoxSizer * image_tb_broad = nullptr; @@ -252,7 +251,7 @@ protected: std::set> add_need_upload_imgs(); std::pair create_local_thumbnail(wxString &local_path); std::pair create_oss_thumbnail(std::string &oss_path); - + }; class PrintingTaskPanel : public wxPanel @@ -261,7 +260,7 @@ public: PrintingTaskPanel(wxWindow* parent, PrintingTaskType type); ~PrintingTaskPanel(); void create_panel(wxWindow* parent); - + private: MachineObject* m_obj{nullptr}; @@ -353,7 +352,7 @@ public: void set_plate_index(int plate_idx = -1); void market_scoring_show(); void market_scoring_hide(); - + public: ScalableButton* get_abort_button() {return m_button_abort;}; ScalableButton* get_pause_resume_button() {return m_button_pause_resume;}; @@ -443,7 +442,7 @@ protected: wxStaticBitmap* m_camera_switch_button; - wxMediaCtrl2 * m_media_ctrl; + wxMediaCtrl3 * m_media_ctrl; MediaPlayCtrl * m_media_play_ctrl; Label * m_staticText_printing; @@ -567,7 +566,7 @@ protected: virtual void on_bed_temp_kill_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_bed_temp_set_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_nozzle_temp_kill_focus(wxFocusEvent &event) { event.Skip(); } - virtual void on_nozzle_temp_set_focus(wxFocusEvent &event) { event.Skip(); } + virtual void on_nozzle_temp_set_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_nozzle_fan_switch(wxCommandEvent &event) { event.Skip(); } virtual void on_printing_fan_switch(wxCommandEvent &event) { event.Skip(); } virtual void on_axis_ctrl_z_up_10(wxCommandEvent &event) { event.Skip(); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1a1ace3f05..cd89ccdc26 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -7536,7 +7536,7 @@ void Tab::delete_preset() for (auto &preset2 : *m_presets) if (preset2.inherits() == current_preset.name) { ++count; - presets += "\n - " + preset2.name; + presets += "\n - " + from_u8(preset2.name); } if (count > 0) { msg = _L("Presets inherited by other presets cannot be deleted!"); diff --git a/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp b/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp index ee0608ffbe..535abfcaf2 100644 --- a/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp +++ b/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp @@ -124,7 +124,7 @@ void AxisCtrlButton::SetInnerBackgroundColor(StateColor const& color) void AxisCtrlButton::SetBitmap(ScalableBitmap &bmp) { - if (&bmp && (& bmp.bmp()) && (bmp.bmp().IsOk())) { + if (bmp.bmp().IsOk()) { m_icon = bmp; } } diff --git a/src/slic3r/GUI/Widgets/ComboBox.cpp b/src/slic3r/GUI/Widgets/ComboBox.cpp index b6f6d42450..08687f3cf6 100644 --- a/src/slic3r/GUI/Widgets/ComboBox.cpp +++ b/src/slic3r/GUI/Widgets/ComboBox.cpp @@ -208,7 +208,7 @@ bool ComboBox::SetFont(wxFont const& font) int ComboBox::Append(const wxString &item, const wxBitmap &bitmap, int style) { - if (&bitmap && bitmap.IsOk()) { + if (bitmap.IsOk()) { return Append(item, bitmap, nullptr, style); } return Append(item, wxNullBitmap, nullptr, style); @@ -219,7 +219,7 @@ int ComboBox::Append(const wxString &text, void * clientData, int style) { - if (&bitmap && bitmap.IsOk()) { + if (bitmap.IsOk()) { return Append(text, bitmap, wxString{}, clientData, style); } return Append(text, wxNullBitmap, wxString{}, clientData, style); @@ -237,7 +237,7 @@ int ComboBox::Append(const wxString &text, void *clientData, int style) { - auto valid_bit_map = (&bitmap && bitmap.IsOk()) ? bitmap : wxNullBitmap; + auto valid_bit_map = bitmap.IsOk() ? bitmap : wxNullBitmap; Item item{text, wxEmptyString, valid_bit_map, valid_bit_map, clientData, group_key, group_label}; item.style = style; items.push_back(item); @@ -333,7 +333,7 @@ wxBitmap ComboBox::GetItemBitmap(unsigned int n) { return items[n].icon; } void ComboBox::SetItemBitmap(unsigned int n, wxBitmap const &bitmap) { if (n >= items.size()) return; - items[n].icon = (&bitmap && bitmap.IsOk()) ? bitmap : wxNullBitmap; + items[n].icon = bitmap.IsOk() ? bitmap : wxNullBitmap; drop.Invalidate(); } diff --git a/src/slic3r/GUI/Widgets/TabCtrl.cpp b/src/slic3r/GUI/Widgets/TabCtrl.cpp index 8fc432771e..7e1f748e36 100644 --- a/src/slic3r/GUI/Widgets/TabCtrl.cpp +++ b/src/slic3r/GUI/Widgets/TabCtrl.cpp @@ -99,7 +99,7 @@ int TabCtrl::AppendItem(const wxString& item, int image, int selImage, void* cli btns.push_back(btn); if (btns.size() > 1) sizer->GetItem(sizer->GetItemCount() - 1)->SetMinSize({0, 0}); - sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, item_space * 2); + sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, item_space); sizer->AddStretchSpacer(1); relayout(); return btns.size() - 1; @@ -223,8 +223,9 @@ bool TabCtrl::IsVisible(unsigned int item) const { return true; } void TabCtrl::DoSetSize(int x, int y, int width, int height, int sizeFlags) { + auto size = GetSize(); wxWindow::DoSetSize(x, y, width, height, sizeFlags); - if (sizeFlags & wxSIZE_USE_EXISTING) + if (size == GetSize()) return; relayout(); } diff --git a/src/slic3r/GUI/wxMediaCtrl2.cpp b/src/slic3r/GUI/wxMediaCtrl2.cpp deleted file mode 100644 index f2d1d2701e..0000000000 --- a/src/slic3r/GUI/wxMediaCtrl2.cpp +++ /dev/null @@ -1,633 +0,0 @@ -#include "wxMediaCtrl2.h" -#include "libslic3r/Time.hpp" -#include "I18N.hpp" -#include "GUI_App.hpp" -#include "LinuxDisplayBackend.hpp" -#include -#include -#ifdef __WIN32__ -#include -#include -#include -#include -#endif - -#ifdef __LINUX__ -#include "Printer/gstbambusrc.h" -#include // main gstreamer header -#endif - -#if defined(__LINUX__) && defined(__WXGTK__) -#include -#include - -namespace { -bool ensure_gstreamer_initialized_for_liveview() -{ - GError* error = nullptr; - if (!gst_init_check(nullptr, nullptr, &error)) { - BOOST_LOG_TRIVIAL(error) << "wxMediaCtrl2: gst_init_check failed before native Wayland liveview setup" - << (error ? std::string(": ") + error->message : std::string()); - if (error) - g_error_free(error); - return false; - } - - return true; -} - -bool is_gstreamer_feature_available(const char* feature) -{ - if (!ensure_gstreamer_initialized_for_liveview()) - return false; - - GstElementFactory* factory = gst_element_factory_find(feature); - if (!factory) - return false; - - gst_object_unref(factory); - return true; -} - -void set_gstreamer_feature_rank(const char* feature, guint rank) -{ - GstElementFactory* factory = gst_element_factory_find(feature); - if (!factory) - return; - - gst_plugin_feature_set_rank(GST_PLUGIN_FEATURE(factory), rank); - gst_object_unref(factory); -} - -void configure_wayland_gstreamer_liveview_path() -{ - static bool configured = false; - if (configured) - return; - configured = true; - - if (!ensure_gstreamer_initialized_for_liveview()) - return; - - // Prefer software decode for Bambu liveview on Wayland/NVIDIA, where - // zero-copy GL/DMABUF display paths can be fragile. Keep hardware - // decoders available as lower-ranked fallbacks for VAAPI/NVDEC/V4L2-only - // installations instead of passing preflight and then blocking autoplug. - set_gstreamer_feature_rank("avdec_h264", GST_RANK_PRIMARY + 300); - set_gstreamer_feature_rank("openh264dec", GST_RANK_PRIMARY + 100); - set_gstreamer_feature_rank("nvh264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("vaapih264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("vah264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("v4l2h264dec", GST_RANK_MARGINAL); -} -} - -#endif // defined(__LINUX__) && defined(__WXGTK__) - -#ifdef __LINUX__ -extern "C" int gst_bambu_last_error; - -class WXDLLIMPEXP_MEDIA - wxGStreamerMediaBackend : public wxMediaBackendCommonBase -{ -public: - GstElement *m_playbin; // GStreamer media element -}; -#endif - -wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); - -wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent) -{ -#if defined(__LINUX__) && defined(__WXGTK__) - m_native_wayland = Slic3r::GUI::is_running_on_wayland(); - if (m_native_wayland && is_gstreamer_feature_available("gtksink")) - configure_wayland_gstreamer_liveview_path(); - else if (m_native_wayland) { - m_gtk_sink_error = _L("Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer."); - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: native Wayland liveview disabled because GStreamer gtksink is unavailable"; - } -#endif -#ifdef __WIN32__ - auto hModExe = GetModuleHandle(NULL); - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe; - auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement"); - auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance"); - if (NvOptimusEnablement) { - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: NvOptimusEnablement " << *NvOptimusEnablement; - *NvOptimusEnablement = 0; - } - if (AmdPowerXpressRequestHighPerformance) { - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance; - *AmdPowerXpressRequestHighPerformance = 0; - } -#endif -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_native_wayland) - wxControl::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize); - else -#endif - wxMediaCtrl::Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE); -#ifdef __LINUX__ - gstbambusrc_register(); -#ifdef __WXGTK__ - if (m_native_wayland && m_gtk_sink_error.empty()) - m_use_gtk_sink = CreateGtkSinkPlayer(); - if (m_native_wayland && !m_use_gtk_sink && m_gtk_sink_error.empty()) - m_gtk_sink_error = _L("Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation."); -#endif - if (!m_use_gtk_sink && m_imp) { - auto playbin = reinterpret_cast(m_imp)->m_playbin; - g_object_set(G_OBJECT(playbin), - "audio-sink", nullptr, - nullptr); - } else if (!m_use_gtk_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: wxMediaCtrl backend is unavailable"; - } - Bind(wxEVT_MEDIA_LOADED, [this](auto & e) { - m_loaded = true; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(0); - event.SetEventObject(this); - wxPostEvent(this, event); - }); -#endif -} - -wxMediaCtrl2::~wxMediaCtrl2() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - DestroyGtkSinkPlayer(); -#endif -} - -#if defined(__LINUX__) && defined(__WXGTK__) -bool wxMediaCtrl2::CreateGtkSinkPlayer() -{ - GstElement *playbin = gst_element_factory_make("playbin", "orca-wayland-gtk-playbin"); - if (!playbin) - return false; - - GError *error = nullptr; - GstElement *video_sink = gst_parse_bin_from_description( - "videoconvert ! videoscale ! video/x-raw,format=BGRx ! gtksink name=orca_wayland_gtksink sync=false", - TRUE, - &error); - if (!video_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: failed to create gtksink video bin" - << (error ? std::string(": ") + error->message : std::string()); - if (error) - g_error_free(error); - gst_object_unref(playbin); - return false; - } - - GstElement *gtk_sink = gst_bin_get_by_name(GST_BIN(video_sink), "orca_wayland_gtksink"); - if (!gtk_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: failed to find gtksink in video bin"; - gst_object_unref(video_sink); - gst_object_unref(playbin); - return false; - } - - GtkWidget *gtk_widget = nullptr; - g_object_get(G_OBJECT(gtk_sink), "widget", >k_widget, nullptr); - if (!gtk_widget) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: gtksink did not expose a GtkWidget"; - gst_object_unref(gtk_sink); - gst_object_unref(video_sink); - gst_object_unref(playbin); - return false; - } - - gtk_widget_show(gtk_widget); - m_gtk_video_window = new wxNativeWindow(this, wxID_ANY, gtk_widget); - m_gtk_video_window->Show(); - g_object_unref(gtk_widget); - - g_object_set(G_OBJECT(playbin), - "video-sink", video_sink, - "audio-sink", nullptr, - nullptr); - gst_object_unref(video_sink); - - m_gtk_playbin = playbin; - m_gtk_sink = gtk_sink; - - GstBus *bus = gst_element_get_bus(playbin); - m_gtk_bus_watch_id = gst_bus_add_watch(bus, [](GstBus *, GstMessage *message, gpointer data) -> gboolean { - auto *self = static_cast(data); - if (!self || !self->m_gtk_playbin) - return G_SOURCE_REMOVE; - - switch (GST_MESSAGE_TYPE(message)) { - case GST_MESSAGE_ERROR: - { - GError *error = nullptr; - gchar *debug = nullptr; - gst_message_parse_error(message, &error, &debug); - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: gtksink pipeline error" - << (error ? std::string(": ") + error->message : std::string()) - << (debug ? std::string(" debug: ") + debug : std::string()); - if (error) - g_error_free(error); - if (debug) - g_free(debug); - - self->m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(self->GetId()); - break; - } - case GST_MESSAGE_EOS: - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(self->GetId()); - break; - case GST_MESSAGE_STATE_CHANGED: - if (GST_MESSAGE_SRC(message) == GST_OBJECT(self->m_gtk_playbin)) { - GstState old_state; - GstState new_state; - GstState pending_state; - gst_message_parse_state_changed(message, &old_state, &new_state, &pending_state); - - if (new_state == GST_STATE_PLAYING) { - self->m_loaded = true; - self->m_gtk_state = wxMEDIASTATE_PLAYING; - self->PostGtkSinkStateEvent(); - } else if (new_state == GST_STATE_PAUSED && old_state < GST_STATE_PAUSED) { - // Treat only upward READY/NULL -> PAUSED as load completion. - // PLAYING -> PAUSED is a normal teardown step before NULL. - self->m_loaded = true; - self->m_gtk_state = wxMEDIASTATE_PAUSED; - self->PostGtkSinkStateEvent(); - } else if (new_state <= GST_STATE_READY && old_state >= GST_STATE_PAUSED) { - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(); - } - } - break; - default: - break; - } - - return G_SOURCE_CONTINUE; - }, this); - gst_object_unref(bus); - - BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: using GTK native Wayland video sink"; - return true; -} - -void wxMediaCtrl2::DestroyGtkSinkPlayer() -{ - if (m_gtk_bus_watch_id) { - g_source_remove(m_gtk_bus_watch_id); - m_gtk_bus_watch_id = 0; - } - - if (m_gtk_playbin) { - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - } - - if (m_gtk_video_window) { - m_gtk_video_window->Destroy(); - m_gtk_video_window = nullptr; - } - - if (m_gtk_playbin) { - gst_object_unref(m_gtk_playbin); - m_gtk_playbin = nullptr; - } - - if (m_gtk_sink) { - gst_object_unref(m_gtk_sink); - m_gtk_sink = nullptr; - } - -} - -void wxMediaCtrl2::PostGtkSinkStateEvent(int id) -{ - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(id); - event.SetEventObject(this); - wxPostEvent(this, event); -} -#endif // defined(__LINUX__) && defined(__WXGTK__) - -#define CLSID_BAMBU_SOURCE L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" - -void wxMediaCtrl2::Load(wxURI url) -{ -#ifdef __WIN32__ - InvalidateBestSize(); - if (m_imp == nullptr) { - static bool notified = false; - if (!notified) CallAfter([] { - auto res = wxMessageBox(_L("Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?"), _L("Error"), wxOK | wxCANCEL); - if (res == wxOK) { - wxString url = IsWindows10OrGreater() - ? "ms-settings:optionalfeatures?activationSource=SMC-Article-14209" - : "https://support.microsoft.com/en-au/windows/get-windows-media-player-81718e0d-cfce-25b1-aee3-94596b658287"; - wxExecute("cmd /c start " + url, wxEXEC_HIDE_CONSOLE); - } - }); - m_error = 100; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - { - wxRegKey key11(wxRegKey::HKCU, L"SOFTWARE\\Classes\\CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); - wxRegKey key12(wxRegKey::HKCR, L"CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); - wxString path = key11.Exists() ? key11.QueryDefaultValue() - : key12.Exists() ? key12.QueryDefaultValue() : wxString{}; - wxRegKey key2(wxRegKey::HKCR, "bambu"); - wxString clsid; - if (key2.Exists()) - key2.QueryRawValue("Source Filter", clsid); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": clsid %1% path %2%") % clsid % path; - - std::string data_dir_str = Slic3r::data_dir(); - boost::filesystem::path data_dir_path(data_dir_str); - auto dll_path = data_dir_path / "plugins" / "BambuSource.dll"; - if (path.empty() || !wxFile::Exists(path) || clsid != CLSID_BAMBU_SOURCE) { - if (boost::filesystem::exists(dll_path)) { - CallAfter( - [dll_path] { - int res = wxMessageBox(_L("BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice"), _L("Error"), wxYES_NO); - if (res == wxYES) { - std::string regContent = R"(Windows Registry Editor Version 5.00 - [HKEY_CLASSES_ROOT\bambu] - "Source Filter"="{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" - )"; - - auto reg_path = (fs::temp_directory_path() / fs::unique_path()).replace_extension(".reg"); - std::ofstream temp_reg_file(reg_path.c_str()); - if (!temp_reg_file) { - return false; - } - temp_reg_file << regContent; - temp_reg_file.close(); - auto sei_params = L"/q /s " + reg_path.wstring(); - SHELLEXECUTEINFO sei{sizeof(sei), SEE_MASK_NOCLOSEPROCESS, NULL, L"open", - L"regedit", sei_params.c_str(),SW_HIDE,SW_HIDE}; - ::ShellExecuteEx(&sei); - - wstring quoted_dll_path = L"\"" + dll_path.wstring() + L"\""; - SHELLEXECUTEINFO info{sizeof(info), 0, NULL, L"runas", L"regsvr32", quoted_dll_path.c_str(), SW_HIDE }; - ::ShellExecuteEx(&info); - fs::remove(reg_path); - } - return true; - }); - } else { - CallAfter([] { - wxMessageBox(_L("Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help."), _L("Error"), wxOK); - }); - } - m_error = clsid != CLSID_BAMBU_SOURCE ? 101 : path.empty() ? 102 : 103; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - if (path != dll_path) { - static bool notified = false; - if (!notified) CallAfter([dll_path] { - int res = wxMessageBox(_L("Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it."), _L("Warning"), wxYES_NO | wxICON_WARNING); - if (res == wxYES) { - auto path = dll_path.wstring(); - if (path.find(L' ') != std::wstring::npos) - path = L"\"" + path + L"\""; - SHELLEXECUTEINFO info{sizeof(info), 0, NULL, L"open", L"regsvr32", path.c_str(), SW_HIDE}; - ::ShellExecuteEx(&info); - } - }); - notified = true; - } - wxRegKey keyWmp(wxRegKey::HKCU, "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\."); - keyWmp.Create(); - long permissions = 0; - if (keyWmp.HasValue("Permissions")) - keyWmp.QueryValue("Permissions", &permissions); - if ((permissions & 32) == 0) { - permissions |= 32; - keyWmp.SetValue("Permissions", permissions); - } - } - url = wxURI(url.BuildURI().append("&hwnd=").append(boost::lexical_cast(GetHandle())).append("&tid=").append( - boost::lexical_cast(GetCurrentThreadId()))); -#endif -#ifdef __WXGTK3__ - GstElementFactory *factory; - int hasplugins = 1; - - factory = gst_element_factory_find("h264parse"); - if (!factory) { - hasplugins = 0; - } else { - gst_object_unref(factory); - } - - factory = gst_element_factory_find("openh264dec"); - if (!factory) { - factory = gst_element_factory_find("avdec_h264"); - } - if (!factory) { - factory = gst_element_factory_find("vaapih264dec"); - } - if (!factory) { - factory = gst_element_factory_find("vah264dec"); - } - if (!factory) { - factory = gst_element_factory_find("nvh264dec"); - } - if (!factory) { - factory = gst_element_factory_find("v4l2h264dec"); - } - if (!factory) { - hasplugins = 0; - } else { - gst_object_unref(factory); - } - - if (!hasplugins) { - CallAfter([] { - wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)"), _L("Error"), wxOK); - }); - m_error = 101; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - wxLog::EnableLogging(false); -#endif - m_error = 0; - m_loaded = false; -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - const std::string uri = std::string(url.BuildURI().ToUTF8().data()); - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - g_object_set(G_OBJECT(m_gtk_playbin), "uri", uri.c_str(), nullptr); - m_gtk_state = wxMEDIASTATE_STOPPED; - GstStateChangeReturn state = gst_element_set_state(m_gtk_playbin, GST_STATE_PAUSED); - if (state == GST_STATE_CHANGE_FAILURE) { - m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - PostGtkSinkStateEvent(GetId()); - } - return; - } - if (!m_imp) { - m_error = m_native_wayland && !m_gtk_sink_error.empty() ? 104 : 100; - m_loaded = false; - if (m_native_wayland && !m_gtk_sink_error.empty() && !m_gtk_sink_error_notified) { - m_gtk_sink_error_notified = true; - const wxString message = m_gtk_sink_error; - CallAfter([message] { - wxMessageBox(message, _L("Error"), wxOK); - }); - } - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } -#endif - wxMediaCtrl::Load(url); -} - -void wxMediaCtrl2::Play() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - GstStateChangeReturn state = gst_element_set_state(m_gtk_playbin, GST_STATE_PLAYING); - if (state == GST_STATE_CHANGE_FAILURE) { - m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - m_gtk_state = wxMEDIASTATE_STOPPED; - PostGtkSinkStateEvent(GetId()); - } - return; - } - if (!m_imp) { - m_error = m_native_wayland && !m_gtk_sink_error.empty() ? 104 : 100; - if (m_native_wayland && !m_gtk_sink_error.empty() && !m_gtk_sink_error_notified) { - m_gtk_sink_error_notified = true; - const wxString message = m_gtk_sink_error; - CallAfter([message] { - wxMessageBox(message, _L("Error"), wxOK); - }); - } - PostGtkSinkStateEvent(GetId()); - return; - } -#endif - wxMediaCtrl::Play(); -} - -void wxMediaCtrl2::Stop() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - m_gtk_state = wxMEDIASTATE_STOPPED; - m_loaded = false; - PostGtkSinkStateEvent(0); - return; - } - if (!m_imp) - return; -#endif - wxMediaCtrl::Stop(); -} - -wxMediaState wxMediaCtrl2::GetState() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) - return m_gtk_state; - if (!m_imp) - return wxMEDIASTATE_STOPPED; -#endif - return wxMediaCtrl::GetState(); -} - -int wxMediaCtrl2::GetLastError() const -{ -#ifdef __LINUX__ -#ifdef __WXGTK__ - if (m_use_gtk_sink && m_error) - return m_error; -#endif - if (m_error) - return m_error; - return gst_bambu_last_error; -#else - return m_error; -#endif -} - -wxSize wxMediaCtrl2::GetVideoSize() const -{ -#ifdef __LINUX__ - // Gstreamer doesn't give us a VideoSize until we're playing, which - // confuses the MediaPlayCtrl into claiming that it is stuck - // "Loading...". Fake it out for now. - return m_loaded ? wxSize(1280, 720) : wxSize{}; -#else - wxSize size = m_imp ? m_imp->GetVideoSize() : wxSize(0, 0); - if (size.GetWidth() > 0) - const_cast(m_video_size) = size; - return size; -#endif -} - -wxSize wxMediaCtrl2::DoGetBestSize() const -{ - return {-1, -1}; -} - -#ifdef __WIN32__ - -WXLRESULT wxMediaCtrl2::MSWWindowProc(WXUINT nMsg, - WXWPARAM wParam, - WXLPARAM lParam) -{ - // The stream source sends WM_USER+1000 with a synchronous SendMessage from its own threads, - // so this runs re-entrantly on the UI thread at whatever message-retrieval point the player - // happens to be in - often nested inside an Orca log statement. Never BOOST_LOG_TRIVIAL here: - // boost::log is not re-entrant on one thread, and doing so corrupted its per-thread record - // state, crashing later in unrelated places (the player, the log filter, a plug-in heap free). - // Post the string out (as the stat branch does) and log it on a clean stack instead. - if (nMsg == WM_USER + 1000) { - wxString msg((wchar_t const *) lParam); - if (wParam == 1) { - if (msg.EndsWith("]")) { - int n = msg.find_last_of('['); - if (n != wxString::npos) { - long val = 0; - if (msg.SubString(n + 1, msg.Length() - 2).ToLong(&val)) - m_error = (int) val; - } - } else if (msg.Contains("stat_log")) { - wxCommandEvent evt(EVT_MEDIA_CTRL_STAT); - evt.SetEventObject(this); - evt.SetString(msg.Mid(msg.Find(' ') + 1)); - wxPostEvent(this, evt); - } - } - return 0; - } - return wxMediaCtrl::MSWWindowProc(nMsg, wParam, lParam); -} - -#endif diff --git a/src/slic3r/GUI/wxMediaCtrl2.h b/src/slic3r/GUI/wxMediaCtrl2.h deleted file mode 100644 index 4f37b5cd1e..0000000000 --- a/src/slic3r/GUI/wxMediaCtrl2.h +++ /dev/null @@ -1,117 +0,0 @@ -// -// wxMediaCtrl2.h -// libslic3r_gui -// -// Created by cmguo on 2021/12/7. -// - -#ifndef wxMediaCtrl2_h -#define wxMediaCtrl2_h - -#include "wx/uri.h" -#include "wx/mediactrl.h" - -wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); - -#if defined(__LINUX__) && defined(__WXGTK__) -typedef struct _GstElement GstElement; -#endif - -#ifdef __WXMAC__ - -class wxMediaCtrl2 : public wxWindow -{ -public: - wxMediaCtrl2(wxWindow * parent); - - ~wxMediaCtrl2(); - - void Load(wxURI url); - - void Play(); - - void Stop(); - - void SetIdleImage(wxString const & image); - - wxMediaState GetState() const; - - wxSize GetVideoSize() const; - - int GetLastError() const { return m_error; } - - static inline const wxMediaState MEDIASTATE_BUFFERING = static_cast(6); - -protected: - void DoSetSize(int x, int y, int width, int height, int sizeFlags) override; - - static void bambu_log(void const * ctx, int level, char const * msg); - - void NotifyStopped(); - -private: - void create_player(); - void * m_player = nullptr; - wxMediaState m_state = wxMEDIASTATE_STOPPED; - int m_error = 0; - wxSize m_video_size{16, 9}; -}; - -#else - -class wxMediaCtrl2 : public wxMediaCtrl -{ -public: - wxMediaCtrl2(wxWindow *parent); - ~wxMediaCtrl2(); - - void Load(wxURI url); - - void Play(); - - void Stop(); - - void SetIdleImage(wxString const & image); - - wxMediaState GetState(); - - int GetLastError() const; - - wxSize GetVideoSize() const; - -protected: - wxSize DoGetBestSize() const override; - - void DoSetSize(int x, int y, int width, int height, int sizeFlags) override; - -#ifdef __WIN32__ - WXLRESULT MSWWindowProc(WXUINT nMsg, - WXWPARAM wParam, - WXLPARAM lParam) override; -#endif - -private: -#if defined(__LINUX__) && defined(__WXGTK__) - bool CreateGtkSinkPlayer(); - void DestroyGtkSinkPlayer(); - void PostGtkSinkStateEvent(int id = 0); - - bool m_native_wayland = false; - bool m_use_gtk_sink = false; - wxString m_gtk_sink_error; - bool m_gtk_sink_error_notified = false; - GstElement *m_gtk_playbin = nullptr; - GstElement *m_gtk_sink = nullptr; - unsigned int m_gtk_bus_watch_id = 0; - wxWindow *m_gtk_video_window = nullptr; - wxMediaState m_gtk_state = wxMEDIASTATE_STOPPED; -#endif - wxString m_idle_image; - int m_error = 0; - bool m_loaded = false; - wxSize m_video_size{16, 9}; -}; - -#endif - -#endif /* wxMediaCtrl2_h */ diff --git a/src/slic3r/GUI/wxMediaCtrl2.mm b/src/slic3r/GUI/wxMediaCtrl2.mm deleted file mode 100644 index 063472eccc..0000000000 --- a/src/slic3r/GUI/wxMediaCtrl2.mm +++ /dev/null @@ -1,170 +0,0 @@ -// -// wxMediaCtrl2.m -// OrcaSlicer -// -// Created by cmguo on 2021/12/7. -// - -#import "wxMediaCtrl2.h" -#import "wx/mediactrl.h" -#include - -#import -#import "BambuPlayer/BambuPlayer.h" -#import "../Utils/NetworkAgent.hpp" - -#include -#include - -wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); - -#define BAMBU_DYNAMIC - -void wxMediaCtrl2::bambu_log(void const * ctx, int level, char const * msg) -{ - if (level == 1) { - wxString msg2(msg); - if (msg2.EndsWith("]")) { - int n = msg2.find_last_of('['); - if (n != wxString::npos) { - long val = 0; - wxMediaCtrl2 * ctrl = (wxMediaCtrl2 *) ctx; - if (msg2.SubString(n + 1, msg2.Length() - 2).ToLong(&val)) - ctrl->m_error = (int) val; - } - } else if (strstr(msg, "stat_log")) { - wxMediaCtrl2 * ctrl = (wxMediaCtrl2 *) ctx; - wxCommandEvent evt(EVT_MEDIA_CTRL_STAT); - evt.SetEventObject(ctrl); - evt.SetString(strchr(msg, ' ') + 1); - wxPostEvent(ctrl, evt); - } - } else if (level < 0) { - wxMediaCtrl2 * ctrl = (wxMediaCtrl2 *) ctx; - ctrl->NotifyStopped(); - } - BOOST_LOG_TRIVIAL(info) << msg; -} - -wxMediaCtrl2::wxMediaCtrl2(wxWindow * parent) - : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) -{ - NSView * imageView = (NSView *) GetHandle(); - imageView.layer = [[CALayer alloc] init]; - CGColorRef color = CGColorCreateGenericRGB(0, 0, 0, 1.0f); - imageView.layer.backgroundColor = color; - CGColorRelease(color); - imageView.wantsLayer = YES; - create_player(); -} - -wxMediaCtrl2::~wxMediaCtrl2() -{ - BambuPlayer * player = (BambuPlayer *) m_player; - [player dealloc]; -} - -void wxMediaCtrl2::create_player() -{ - auto module = Slic3r::NetworkAgent::get_bambu_source_entry(); - if (!module) { - //not ready yet - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Network plugin not ready currently!"; - return; - } - Class cls = (__bridge Class) dlsym(module, "OBJC_CLASS_$_BambuPlayer"); - if (cls == nullptr) { - m_error = -2; - return; - } - NSView * imageView = (NSView *) GetHandle(); - BambuPlayer * player = [cls alloc]; - [player initWithImageView: imageView]; - [player setLogger: bambu_log withContext: this]; - m_player = player; -} - -void wxMediaCtrl2::Load(wxURI url) -{ - if (!m_player) { - create_player(); - if (!m_player) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": create_player failed currently!"; - return; - } - } - - BambuPlayer * player = (BambuPlayer *) m_player; - if (player) { - [player close]; - m_error = 0; - m_error = [player open: url.BuildURI().ToUTF8()]; - } - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); -} - -void wxMediaCtrl2::Play() -{ - if (!m_player) { - create_player(); - if (!m_player) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": create_player failed currently!"; - return; - } - } - BambuPlayer * player2 = (BambuPlayer *) m_player; - [player2 play]; - if (m_state != wxMEDIASTATE_PLAYING) { - m_state = wxMEDIASTATE_PLAYING; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - } -} - -void wxMediaCtrl2::Stop() -{ - if (!m_player) { - create_player(); - if (!m_player) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": create_player failed currently!"; - return; - } - } - BambuPlayer * player2 = (BambuPlayer *) m_player; - [player2 close]; - NotifyStopped(); -} - -void wxMediaCtrl2::NotifyStopped() -{ - if (m_state != wxMEDIASTATE_STOPPED) { - m_state = wxMEDIASTATE_STOPPED; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - } -} - -wxMediaState wxMediaCtrl2::GetState() const -{ - return m_state; -} - -wxSize wxMediaCtrl2::GetVideoSize() const -{ - BambuPlayer * player2 = (BambuPlayer *) m_player; - if (player2) { - NSSize size = [player2 videoSize]; - if (size.width > 0) - const_cast(m_video_size) = {(int) size.width, (int) size.height}; - return {(int) size.width, (int) size.height}; - } else { - return {0, 0}; - } -} diff --git a/src/slic3r/GUI/wxMediaCtrl3.cpp b/src/slic3r/GUI/wxMediaCtrl3.cpp new file mode 100644 index 0000000000..098db68808 --- /dev/null +++ b/src/slic3r/GUI/wxMediaCtrl3.cpp @@ -0,0 +1,313 @@ +#include "wxMediaCtrl3.h" +#include "AVVideoDecoder.hpp" +#include "I18N.hpp" +#include "libslic3r/Utils.hpp" +#include +#include +#ifdef __WIN32__ +#include +#include +#include +#endif + +wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); + +BEGIN_EVENT_TABLE(wxMediaCtrl3, wxWindow) + +// catch paint events +EVT_PAINT(wxMediaCtrl3::paintEvent) + +END_EVENT_TABLE() + +struct StaticBambuLib : BambuLib +{ + static StaticBambuLib &get(BambuLib *); +}; + +wxMediaCtrl3::wxMediaCtrl3(wxWindow *parent) + : wxWindow(parent, wxID_ANY) + , BambuLib(StaticBambuLib::get(this)) + , m_thread([this] { PlayThread(); }) +{ + SetBackgroundColour("#000001ff"); +} + +wxMediaCtrl3::~wxMediaCtrl3() +{ + { + std::unique_lock lk(m_mutex); + m_url.reset(new wxURI); + m_frame = wxImage(m_idle_image); + m_cond.notify_all(); + } + m_thread.join(); +} + +void wxMediaCtrl3::Load(wxURI url) +{ + std::unique_lock lk(m_mutex); + m_video_size = wxDefaultSize; + m_error = 0; + m_url.reset(new wxURI(url)); + m_cond.notify_all(); +} + +void wxMediaCtrl3::Play() +{ + std::unique_lock lk(m_mutex); + if (m_state != wxMEDIASTATE_PLAYING) { + m_state = wxMEDIASTATE_PLAYING; + wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); + event.SetId(GetId()); + event.SetEventObject(this); + wxPostEvent(this, event); + } +} + +void wxMediaCtrl3::Stop() +{ + std::unique_lock lk(m_mutex); + m_url.reset(); + m_frame = wxImage(m_idle_image); + NotifyStopped(); + m_cond.notify_all(); + Refresh(); +} + +void wxMediaCtrl3::SetIdleImage(wxString const &image) +{ + if (m_idle_image == image) + return; + m_idle_image = image; + if (m_url == nullptr) { + std::unique_lock lk(m_mutex); + m_frame = wxImage(m_idle_image); + assert(m_frame.IsOk()); + Refresh(); + } +} + +wxMediaState wxMediaCtrl3::GetState() +{ + std::unique_lock lk(m_mutex); + return m_state; +} + +int wxMediaCtrl3::GetLastError() +{ + std::unique_lock lk(m_mutex); + return m_error; +} + +wxSize wxMediaCtrl3::GetVideoSize() +{ + std::unique_lock lk(m_mutex); + return m_video_size; +} + +wxSize wxMediaCtrl3::DoGetBestSize() const +{ + return {-1, -1}; +} + +static void adjust_frame_size(wxSize & frame, wxSize const & video, wxSize const & window) +{ + if (video.x * window.y < video.y * window.x) + frame = { video.x * window.y / video.y, window.y }; + else + frame = { window.x, video.y * window.x / video.x }; +} + +void wxMediaCtrl3::paintEvent(wxPaintEvent &evt) +{ + wxPaintDC dc(this); + auto size = GetSize(); + if (size.x <= 0 || size.y <= 0) + return; + std::unique_lock lk(m_mutex); + if (!m_frame.IsOk()) + return; + auto size2 = m_frame.GetSize(); + if (size2.x != m_frame_size.x && size2.y == m_frame_size.y) + size2.x = m_frame_size.x; + auto size3 = (size - size2) / 2; + if (size2.x != size.x && size2.y != size.y) { + double scale = 1.; + if (size.x * size2.y > size.y * size2.x) { + size3 = {size.x * size2.y / size.y, size2.y}; + scale = double(size.y) / size2.y; + } else { + size3 = {size2.x, size.y * size2.x / size.x}; + scale = double(size.x) / size2.x; + } + dc.SetUserScale(scale, scale); + size3 = (size3 - size2) / 2; + } + dc.DrawBitmap(m_frame, size3.x, size3.y); +} + +void wxMediaCtrl3::DoSetSize(int x, int y, int width, int height, int sizeFlags) +{ + wxWindow::DoSetSize(x, y, width, height, sizeFlags); + if (sizeFlags == wxSIZE_USE_EXISTING) return; + wxMediaCtrl_OnSize(this, m_video_size, width, height); + std::unique_lock lk(m_mutex); + adjust_frame_size(m_frame_size, m_video_size, GetSize()); + Refresh(); +} + +void wxMediaCtrl3::bambu_log(void *ctx, int level, tchar const *msg2) +{ +#ifdef _WIN32 + wxString msg(msg2); +#else + wxString msg = wxString::FromUTF8(msg2); +#endif + if (level == 1) { + if (msg.EndsWith("]")) { + int n = msg.find_last_of('['); + if (n != wxString::npos) { + long val = 0; + wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx; + if (msg.SubString(n + 1, msg.Length() - 2).ToLong(&val)) { + std::unique_lock lk(ctrl->m_mutex); + ctrl->m_error = (int) val; + } + } + } else if (msg.Contains("stat_log")) { + wxCommandEvent evt(EVT_MEDIA_CTRL_STAT); + wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx; + evt.SetEventObject(ctrl); + evt.SetString(msg.Mid(msg.Find(' ') + 1)); + wxPostEvent(ctrl, evt); + } + } + BOOST_LOG_TRIVIAL(info) << msg.ToUTF8().data(); +} + +void wxMediaCtrl3::PlayThread() +{ + using namespace std::chrono_literals; + std::shared_ptr url; + std::unique_lock lk(m_mutex); + while (true) { + m_cond.wait(lk, [this, &url] { return m_url != url; }); + url = m_url; + if (url == nullptr) + continue; + if (!url->HasScheme()) + break; + lk.unlock(); + Bambu_Tunnel tunnel = nullptr; + int error = Bambu_Create(&tunnel, m_url->BuildURI().ToUTF8()); + if (error == 0) { + Bambu_SetLogger(tunnel, &wxMediaCtrl3::bambu_log, this); + error = Bambu_Open(tunnel); + if (error == 0) + error = Bambu_would_block; + } + lk.lock(); + while (error == int(Bambu_would_block)) { + m_cond.wait_for(lk, 100ms); + if (m_url != url) { + error = 1; + break; + } + lk.unlock(); + error = Bambu_StartStream(tunnel, true); + lk.lock(); + } + Bambu_StreamInfo info; + if (error == 0) + error = Bambu_GetStreamInfo(tunnel, 0, &info); + AVVideoDecoder decoder; + int minFrameDuration = 0; + if (error == 0) { + decoder.open(info); + m_video_size = { info.format.video.width, info.format.video.height }; + adjust_frame_size(m_frame_size, m_video_size, GetSize()); + minFrameDuration = 800 / info.format.video.frame_rate; // 80% + NotifyStopped(); + } + Bambu_Sample sample; + while (error == 0) { + lk.unlock(); + error = Bambu_ReadSample(tunnel, &sample); + lk.lock(); + while (error == int(Bambu_would_block)) { + m_cond.wait_for(lk, 100ms); + if (m_url != url) { + error = 1; + break; + } + lk.unlock(); + error = Bambu_ReadSample(tunnel, &sample); + lk.lock(); + } + if (error == 0) { + auto frame_size = m_frame_size; + lk.unlock(); + decoder.decode(sample); +#ifdef _WIN32 + wxBitmap bm; + decoder.toWxBitmap(bm, frame_size); +#else + wxImage bm; + decoder.toWxImage(bm, frame_size); +#endif + lk.lock(); + if (m_url != url) { + error = 1; + break; + } + if (bm.IsOk()) { + auto now = std::chrono::system_clock::now(); + if (m_last_PTS && (sample.decode_time - m_last_PTS) < 30000000ULL) { // 3s + auto next_PTS_expected = m_last_PTS_expected + std::chrono::milliseconds((sample.decode_time - m_last_PTS) / 10000ULL); + // The frame is late, catch up a little + auto next_PTS_practical = m_last_PTS_practical + std::chrono::milliseconds(minFrameDuration); + auto next_PTS = std::max(next_PTS_expected, next_PTS_practical); + if(now < next_PTS) + std::this_thread::sleep_until(next_PTS); + else + next_PTS = now; + //auto text = wxString::Format(L"wxMediaCtrl3 pts diff %ld\n", std::chrono::duration_cast(next_PTS - next_PTS_expected).count()); + //OutputDebugString(text); + m_last_PTS = sample.decode_time; + m_last_PTS_expected = next_PTS_expected; + m_last_PTS_practical = next_PTS; + } else { + // Resync + m_last_PTS = sample.decode_time; + m_last_PTS_expected = now; + m_last_PTS_practical = now; + } + m_frame = bm; + } + CallAfter([this] { Refresh(); }); + } + } + if (tunnel) { + lk.unlock(); + Bambu_Close(tunnel); + Bambu_Destroy(tunnel); + tunnel = nullptr; + lk.lock(); + } + if (m_url == url) + m_error = error; + m_frame_size = wxDefaultSize; + m_video_size = wxDefaultSize; + NotifyStopped(); + } + +} + +void wxMediaCtrl3::NotifyStopped() +{ + m_state = wxMEDIASTATE_STOPPED; + wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); + event.SetId(GetId()); + event.SetEventObject(this); + wxPostEvent(this, event); +} diff --git a/src/slic3r/GUI/wxMediaCtrl3.h b/src/slic3r/GUI/wxMediaCtrl3.h new file mode 100644 index 0000000000..1d64955ffd --- /dev/null +++ b/src/slic3r/GUI/wxMediaCtrl3.h @@ -0,0 +1,85 @@ +// +// wxMediaCtrl3.h +// libslic3r_gui +// +// Created by cmguo on 2024/6/22. +// + +#ifndef wxMediaCtrl3_h +#define wxMediaCtrl3_h + +#include "wx/uri.h" +#include "wx/mediactrl.h" + +wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); + +void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height); + +#define BAMBU_DYNAMIC +#include +#include +#ifndef _WIN32 +#include +#endif +#include "Printer/BambuTunnel.h" + +class AVVideoDecoder; + +class wxMediaCtrl3 : public wxWindow, BambuLib +{ +public: + wxMediaCtrl3(wxWindow *parent); + + ~wxMediaCtrl3(); + + void Load(wxURI url); + + void Play(); + + void Stop(); + + void SetIdleImage(wxString const & image); + + wxMediaState GetState(); + + int GetLastError(); + + wxSize GetVideoSize(); + +protected: + DECLARE_EVENT_TABLE() + + void paintEvent(wxPaintEvent &evt); + + wxSize DoGetBestSize() const override; + + void DoSetSize(int x, int y, int width, int height, int sizeFlags) override; + + static void bambu_log(void *ctx, int level, tchar const *msg); + + void PlayThread(); + + void NotifyStopped(); + +private: + wxString m_idle_image; + wxMediaState m_state = wxMEDIASTATE_STOPPED; + int m_error = 0; + wxSize m_video_size = wxDefaultSize; + wxSize m_frame_size = wxDefaultSize; +#ifdef _WIN32 + wxBitmap m_frame; +#else + wxImage m_frame; +#endif + + std::shared_ptr m_url; + std::uint64_t m_last_PTS{0}; + std::chrono::system_clock::time_point m_last_PTS_expected; + std::chrono::system_clock::time_point m_last_PTS_practical; + std::mutex m_mutex; + std::condition_variable m_cond; + std::thread m_thread; +}; + +#endif /* wxMediaCtrl3_h */ diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 06808e253d..56a2b66b49 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1198,7 +1198,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version version.config_version = cache_ver; version.comment = description; // Orca: update vendor.json - updates.updates.emplace_back(std::move(file_path), std::move(path_in_vendor.string()), std::move(version), vendor_name, changelog, "", force_update, false); + updates.updates.emplace_back(std::move(file_path), path_in_vendor.string(), std::move(version), vendor_name, changelog, "", force_update, false); //Orca: update vendor folder updates.updates.emplace_back(cache_profile_path / vendor_name, vendor_path / vendor_name, Version(), vendor_name, "", "", force_update, true); } else { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3cbdc25f5f..c403152c4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,25 +30,47 @@ if (APPLE) target_link_libraries(test_common INTERFACE "-liconv -framework IOKit" "-framework CoreFoundation" -lc++) endif() -# Copies runtime DLLs next to each test executable. Handles both single-config -# generators (CMAKE_BUILD_TYPE set) and multi-config generators (Ninja -# Multi-Config, Visual Studio) where CMAKE_BUILD_TYPE is empty and DLLs must -# land in every per-config output directory. +# Copies runtime shared libraries next to each test executable. Handles both +# single-config generators (CMAKE_BUILD_TYPE set) and multi-config generators +# (Ninja Multi-Config, Visual Studio) where CMAKE_BUILD_TYPE is empty and DLLs +# must land in every per-config output directory. On Windows the loader finds +# DLLs in the executable's directory; the Linux branch below does the same for +# the deps-built FFmpeg libraries and adds an $ORIGIN rpath, since the ELF +# loader does not search the executable's directory and the CI unit-test runner +# only receives the tests artifact (no deps install). function(orcaslicer_copy_test_dlls) - if (NOT WIN32) - return() - endif() - set(_configs ${CMAKE_CONFIGURATION_TYPES}) - if (NOT _configs) - set(_configs "${CMAKE_BUILD_TYPE}") - endif() - foreach(_cfg IN LISTS _configs) - if (_cfg STREQUAL "Debug") - orcaslicer_copy_dlls(COPY_DLLS "Debug" "d" _unused_dlls) - else() - orcaslicer_copy_dlls(COPY_DLLS "${_cfg}" "" _unused_dlls) + if (WIN32) + set(_configs ${CMAKE_CONFIGURATION_TYPES}) + if (NOT _configs) + set(_configs "${CMAKE_BUILD_TYPE}") endif() - endforeach() + foreach(_cfg IN LISTS _configs) + if (_cfg STREQUAL "Debug") + orcaslicer_copy_dlls(COPY_DLLS "Debug" "d" _unused_dlls) + else() + orcaslicer_copy_dlls(COPY_DLLS "${_cfg}" "" _unused_dlls) + endif() + endforeach() + elseif (UNIX AND NOT APPLE) + # Only test executables that link libslic3r_gui pull in the FFmpeg + # shared libraries (src/slic3r/CMakeLists.txt links PkgConfig::LIBAV + # into it). Copy them next to the executable and give it an $ORIGIN + # rpath so the loader finds them when the tests run on the CI unit-test + # runner, which only receives this build/tests tree. + get_target_property(_linked_libs ${_TEST_NAME}_tests LINK_LIBRARIES) + if (NOT "libslic3r_gui" IN_LIST _linked_libs) + return() + endif() + + set_property(TARGET ${_TEST_NAME}_tests PROPERTY BUILD_RPATH "$ORIGIN") + set(_configs ${CMAKE_CONFIGURATION_TYPES}) + if (NOT _configs) + set(_configs "${CMAKE_BUILD_TYPE}") + endif() + foreach(_cfg IN LISTS _configs) + orcaslicer_copy_sos(${_TEST_NAME}_tests "${_cfg}" "" _unused_sos) + endforeach() + endif() endfunction() # Register Catch2 tags as CTest labels so `ctest -L`/`-LE` can filter by tag. diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index 069d40b8e5..a493ea9b7b 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -1000,7 +1000,7 @@ TEST_CASE("Published 3MF full-published slots are imported as standalone detache check_double_vector(bundle.filaments.find_preset("My PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); CHECK(pub.skipped_keys.empty()); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PLA -> PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PLA -> PLA"); } SECTION("type mismatch also detaches: a fresh same-type copy replaces the slot") { @@ -1031,7 +1031,7 @@ TEST_CASE("Published 3MF full-published slots are imported as standalone detache check_double_vector(bundle.filaments.find_preset("My PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); CHECK(pub.skipped_keys.empty()); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PLA -> ABS (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PLA -> ABS"); } SECTION("the author's identity rides on the copy when the type has no library match") { @@ -1071,7 +1071,7 @@ TEST_CASE("Published 3MF full-published slots are imported as standalone detache check_double_vector(bundle.filaments.find_preset("Other PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.7 }); CHECK(pub.skipped_keys.empty()); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PLA -> ABS (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PLA -> ABS"); } } @@ -1137,7 +1137,7 @@ TEST_CASE("Published 3MF imports a full material under the author's stripped nam check_double_vector(bundle.filaments.find_preset("Generic PLA @System", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); check_double_vector(bundle.filaments.find_preset("My PETG", false, true)->config.opt("filament_retraction_length")->values, { 0.6 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA"); CHECK(pub.skipped_keys.empty()); } @@ -1168,7 +1168,7 @@ TEST_CASE("Published 3MF imports a full material under the author's stripped nam CHECK(bundle.filament_presets[0] == "Generic PLA"); check_double_vector(bundle.filaments.find_preset("Bambu PLA Basic @System", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA"); CHECK(pub.skipped_keys.empty()); } @@ -1217,7 +1217,7 @@ TEST_CASE("Published 3MF imports a full material under the author's stripped nam check_double_vector(bundle.filaments.find_preset("Generic PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.8 }); check_double_vector(bundle.filaments.find_preset("Generic PLA @System", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 1: Generic PLA @System -> Generic PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 1: Generic PLA @System -> Generic PLA"); CHECK(pub.skipped_keys.empty()); } } @@ -1271,7 +1271,7 @@ TEST_CASE("Published 3MF uniquifies an imported full material name on collision" check_double_vector(bundle.filaments.find_preset("Generic PLA @Qidi Q2 0.4 nozzle", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); check_double_vector(bundle.filaments.find_preset("Generic PLA @System", false, true)->config.opt("filament_retraction_length")->values, { 0.5 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (Published) (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (Published)"); CHECK(pub.skipped_keys.empty()); } @@ -1413,7 +1413,7 @@ TEST_CASE("Published 3MF imports a full material as a detached project-embedded check_double_vector(bundle.filaments.find_preset("Spare PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.4 }); CHECK(pub.skipped_keys.empty()); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Author PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Author PLA"); } // Compatibility restrictions riding on the receiver's baseline preset must not leak onto the @@ -1516,8 +1516,8 @@ TEST_CASE("Published 3MF shares one imported copy between identical full slots", check_double_vector(bundle.filaments.find_preset("Author PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.9 }); // Both slots reported, same target; originals untouched. REQUIRE(pub.material_replacements.size() == 2); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Author PLA (published material imported)"); - CHECK(pub.material_replacements[1] == "slot 1: Other PETG -> Author PLA (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Author PLA"); + CHECK(pub.material_replacements[1] == "slot 1: Other PETG -> Author PLA"); check_double_vector(bundle.filaments.find_preset("My PETG", false, true)->config.opt("filament_retraction_length")->values, { 0.6 }); check_double_vector(bundle.filaments.find_preset("Other PETG", false, true)->config.opt("filament_retraction_length")->values, { 0.65 }); CHECK(pub.skipped_keys.empty()); @@ -1642,7 +1642,7 @@ TEST_CASE("Re-importing a published full material uniquifies the second copy", " check_double_vector(bundle.filaments.find_preset("Author PLA (Published)", false, true)->config.opt("filament_retraction_length")->values, { 0.9 }); check_double_vector(bundle.filaments.find_preset("Author PLA", false, true)->config.opt("filament_retraction_length")->values, { 0.9 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: Author PLA -> Author PLA (Published) (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: Author PLA -> Author PLA (Published)"); } CHECK(pub.skipped_keys.empty()); } @@ -2496,7 +2496,7 @@ TEST_CASE("Published 3MF de-aliases an aliased slot by published identity withou REQUIRE(target != nullptr); check_double_vector(target->config.opt("filament_retraction_length")->values, { 0.9 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0].find("(de-aliased") != std::string::npos); + CHECK(pub.material_replacements[0] == "slot 1: My PLA -> Zzz PLA"); CHECK(pub.skipped_keys.empty()); } @@ -3877,7 +3877,7 @@ TEST_CASE("Published 3MF scores a grown slot's material by identity tiers", "[Pr CHECK(bundle.filament_presets[2] == "Aaa PLA"); // ...and since it is not an exact material match, the load says so. REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 2: Aaa PLA (substitute: no exact material match)"); + CHECK(pub.material_replacements[0] == "slot 2: Aaa PLA (substitute)"); } } @@ -3985,7 +3985,7 @@ TEST_CASE("Published 3MF uniquifies a second imported full material as (Publishe ->config.opt("filament_retraction_length")->values, { 0.5 }); REQUIRE(pub.material_replacements.size() == 1); - CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (Published 2) (published material imported)"); + CHECK(pub.material_replacements[0] == "slot 0: My PETG -> Generic PLA (Published 2)"); CHECK(pub.skipped_keys.empty()); }