GPv3: Dash modifier #117758
@ -25,9 +25,14 @@ vendor,product,version,cve_number,remarks,comment
|
||||
@TIFF_ID@,CVE-2022-3599,Ignored,issue in tiff command line tool not used by blender
|
||||
@TIFF_ID@,CVE-2022-3626,Ignored,issue in tiff command line tool not used by blender
|
||||
@TIFF_ID@,CVE-2022-3627,Ignored,issue in tiff command line tool not used by blender
|
||||
@TIFF_ID@,CVE-2023-40745,Ignored,issue in tiff command line tool not used by blender
|
||||
@TIFF_ID@,CVE-2023-41175,Ignored,issue in tiff command line tool not used by blender
|
||||
@XML2_ID@,CVE-2016-3709,Ignored,not affecting blender and not considered a security issue upstream
|
||||
@XML2_ID@,CVE-2023-39615,Ignored,not affecting blender and not considered a security issue upstream
|
||||
@XML2_ID@,CVE-2020-7595,Ignored,already fixed in the libxml2 version used
|
||||
@GMP_ID@,CVE-2021-43618,Mitigated,patched using upstream commit 561a9c25298e
|
||||
@SQLITE_ID@,CVE-2022-35737,Ignored,only affects SQLITE_ENABLE_STAT4 compile option not used by blender or python
|
||||
@SQLITE_ID@,CVE-2023-7104,Ignored,does not affect blender use of sqlite
|
||||
@SQLITE_ID@,CVE-2024-0232,Ignored,does not affect blender use of sqlite
|
||||
@ZLIB_ID@,CVE-2023-45853,Ignored,only affects minizip not used by blender
|
||||
@SBOMCONTENTS@
|
||||
|
@ -2,13 +2,23 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Generated configuration files use an old `aclocal-1.15` on RockyLinux8.
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(_autoconf_cmd_optional ./autogen.sh &&)
|
||||
else()
|
||||
set(_autoconf_cmd_optional)
|
||||
endif()
|
||||
|
||||
|
||||
ExternalProject_Add(external_flex
|
||||
URL file://${PACKAGE_DIR}/${FLEX_FILE}
|
||||
URL_HASH ${FLEX_HASH_TYPE}=${FLEX_HASH}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
PREFIX ${BUILD_DIR}/flex
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flex/src/external_flex/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/flex
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flex/src/external_flex/ && ${_autoconf_cmd_optional} ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/flex
|
||||
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flex/src/external_flex/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flex/src/external_flex/ && make install
|
||||
INSTALL_DIR ${LIBDIR}/flex
|
||||
)
|
||||
|
||||
unset(_autoconf_cmd_optional)
|
||||
|
@ -9,7 +9,12 @@ set(OIDN_EXTRA_ARGS
|
||||
-DOIDN_FILTER_RTLIGHTMAP=OFF
|
||||
-DPython_EXECUTABLE=${PYTHON_BINARY}
|
||||
)
|
||||
if(NOT APPLE)
|
||||
if(APPLE)
|
||||
set(OIDN_EXTRA_ARGS
|
||||
${OIDN_EXTRA_ARGS}
|
||||
-DOIDN_DEVICE_METAL=ON
|
||||
)
|
||||
else()
|
||||
set(OIDN_EXTRA_ARGS
|
||||
${OIDN_EXTRA_ARGS}
|
||||
-DOIDN_DEVICE_SYCL=ON
|
||||
|
@ -111,9 +111,9 @@ endif()
|
||||
|
||||
message("Checking for perl")
|
||||
# download perl for libvpx
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip")
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.38.0.1-64bit-portable.zip")
|
||||
message("Downloading perl")
|
||||
file(DOWNLOAD "http://strawberryperl.com/download/5.22.1.3/strawberry-perl-5.22.1.3-64bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip")
|
||||
file(DOWNLOAD "https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.38.0.1-64bit-portable.zip")
|
||||
endif()
|
||||
|
||||
# make perl root directory
|
||||
@ -125,10 +125,10 @@ if(NOT EXISTS "${DOWNLOAD_DIR}/perl")
|
||||
endif()
|
||||
|
||||
# extract perl
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/perl/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip"))
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/perl/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.38.0.1-64bit-portable.zip"))
|
||||
message("Extracting perl")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.38.0.1-64bit-portable.zip
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/perl
|
||||
)
|
||||
endif()
|
||||
|
@ -56,7 +56,7 @@ set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.tar.gz)
|
||||
set(BLOSC_HASH 134b55813b1dca57019d2a2dc1f7a923)
|
||||
set(BLOSC_HASH_TYPE MD5)
|
||||
set(BLOSC_FILE blosc-${BLOSC_VERSION}.tar.gz)
|
||||
set(BLOSC_CPE "cpe:2.3:a:c-blosc2_project:c-blosc2:${BLOSC_VERSION}:*:*:*:*:*:*:*")
|
||||
set(BLOSC_CPE "cpe:2.3:a:c-blosc_project:c-blosc:${BLOSC_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(PTHREADS_VERSION 3.0.0)
|
||||
set(PTHREADS_URI http://prdownloads.sourceforge.net/pthreads4w/pthreads4w-code-v${PTHREADS_VERSION}.zip)
|
||||
@ -218,11 +218,11 @@ set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz)
|
||||
# BZIP2, FFI, SQLITE and change the versions in this file as well. For compliance
|
||||
# reasons there can be no exceptions to this.
|
||||
|
||||
set(PYTHON_VERSION 3.11.6)
|
||||
set(PYTHON_VERSION 3.11.7)
|
||||
set(PYTHON_SHORT_VERSION 3.11)
|
||||
set(PYTHON_SHORT_VERSION_NO_DOTS 311)
|
||||
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
|
||||
set(PYTHON_HASH d0c5a1a31efe879723e51addf56dd206)
|
||||
set(PYTHON_HASH d96c7e134c35a8c46236f8a0e566b69c)
|
||||
set(PYTHON_HASH_TYPE MD5)
|
||||
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
|
||||
set(PYTHON_CPE "cpe:2.3:a:python:python:${PYTHON_VERSION}:-:*:*:*:*:*:*")
|
||||
@ -318,9 +318,9 @@ set(FLAC_FILE flac-${FLAC_VERSION}.tar.xz)
|
||||
set(FLAC_CPE "cpe:2.3:a:flac_project:flac:${FLAC_VERSION}:*:*:*:*:*:*:*")
|
||||
set(FLAC_HOMEPAGE https://xiph.org/flac/)
|
||||
|
||||
set(VPX_VERSION 1.11.0)
|
||||
set(VPX_VERSION 1.14.0)
|
||||
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
|
||||
set(VPX_HASH 965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83)
|
||||
set(VPX_HASH 5f21d2db27071c8a46f1725928a10227ae45c5cd1cad3727e4aafbe476e321fa)
|
||||
set(VPX_HASH_TYPE SHA256)
|
||||
set(VPX_FILE libvpx-v${VPX_VERSION}.tar.gz)
|
||||
set(VPX_CPE "cpe:2.3:a:webmproject:libvpx:${VPX_VERSION}:*:*:*:*:*:*:*")
|
||||
@ -347,9 +347,9 @@ set(OPENJPEG_HASH_TYPE SHA256)
|
||||
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
|
||||
set(OPENJPEG_CPE "cpe:2.3:a:uclouvain:openjpeg:${OPENJPEG_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(FFMPEG_VERSION 6.0)
|
||||
set(FFMPEG_VERSION 6.1.1)
|
||||
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
|
||||
set(FFMPEG_HASH 47d062731c9f66a78380e35a19aac77cebceccd1c7cc309b9c82343ffc430c3d)
|
||||
set(FFMPEG_HASH 5e3133939a61ef64ac9b47ffd29a5ea6e337a4023ef0ad972094b4da844e3a20)
|
||||
set(FFMPEG_HASH_TYPE SHA256)
|
||||
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
|
||||
set(FFMPEG_CPE "cpe:2.3:a:ffmpeg:ffmpeg:${FFMPEG_VERSION}:*:*:*:*:*:*:*")
|
||||
@ -479,9 +479,9 @@ set(LZMA_FILE xz-${LZMA_VERSION}.tar.bz2)
|
||||
set(LZMA_HOMEPAGE https://tukaani.org/lzma/)
|
||||
|
||||
# NOTE: Python's build has been modified to use our ssl version.
|
||||
set(SSL_VERSION 3.1.2)
|
||||
set(SSL_VERSION 3.1.5)
|
||||
set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
|
||||
set(SSL_HASH a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539)
|
||||
set(SSL_HASH 6ae015467dabf0469b139ada93319327be24b98251ffaeceda0221848dc09262)
|
||||
set(SSL_HASH_TYPE SHA256)
|
||||
set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
|
||||
set(SSL_CPE "cpe:2.3:a:openssl:openssl:${SSL_VERSION}:*:*:*:*:*:*:*")
|
||||
@ -490,10 +490,10 @@ set(SSL_HOMEPAGE https://www.openssl.org)
|
||||
# Note: This will *HAVE* to match the version python ships on windows which
|
||||
# is hardcoded in pythons PCbuild/get_externals.bat for compliance reasons there
|
||||
# can be no exceptions to this.
|
||||
set(SQLITE_VERSION 3.42.0)
|
||||
set(SQLLITE_LONG_VERSION 3420000)
|
||||
set(SQLITE_URI https://www.sqlite.org/2023/sqlite-autoconf-${SQLLITE_LONG_VERSION}.tar.gz)
|
||||
set(SQLITE_HASH 036575929b174c1b829769255491ba2b32bda9ee)
|
||||
set(SQLITE_VERSION 3.45.1)
|
||||
set(SQLLITE_LONG_VERSION 3450100)
|
||||
set(SQLITE_URI https://www.sqlite.org/2024/sqlite-autoconf-${SQLLITE_LONG_VERSION}.tar.gz)
|
||||
set(SQLITE_HASH 650305e234add12fc1e6bef0b365d86a087b3d38)
|
||||
set(SQLITE_HASH_TYPE SHA1)
|
||||
set(SQLITE_FILE sqlite-autoconf-${SQLLITE_LONG_VERSION}.tar.gz)
|
||||
set(SQLITE_CPE "cpe:2.3:a:sqlite:sqlite:${SQLITE_VERSION}:*:*:*:*:*:*:*")
|
||||
@ -517,9 +517,9 @@ set(MATERIALX_HASH fad8f4e19305fb2ee920cbff638f3560)
|
||||
set(MATERIALX_HASH_TYPE MD5)
|
||||
set(MATERIALX_FILE materialx-v${MATERIALX_VERSION}.tar.gz)
|
||||
|
||||
set(OIDN_VERSION 2.2.0-rc)
|
||||
set(OIDN_VERSION 2.2.0-rc2)
|
||||
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz)
|
||||
set(OIDN_HASH 896d43b65c3fe71144914a1d6b8a5bfb)
|
||||
set(OIDN_HASH 14b261af3a719c49ab10e71583f1a61a)
|
||||
set(OIDN_HASH_TYPE MD5)
|
||||
set(OIDN_FILE oidn-${OIDN_VERSION}.src.tar.gz)
|
||||
|
||||
|
@ -39,6 +39,9 @@ yum -y install scl-utils-build
|
||||
# Currently this is defined by the VFX platform (CY2023), see: https://vfxplatform.com
|
||||
yum -y install gcc-toolset-11
|
||||
|
||||
# Repository for CUDA (`nvcc`).
|
||||
dnf config-manager --add-repo http://developer.download.nvidia.com/compute/cuda/repos/rhel8/$(uname -i)/cuda-rhel8.repo
|
||||
|
||||
# Install packages needed for Blender's dependencies.
|
||||
PACKAGES_FOR_LIBS=(
|
||||
# Used to checkout Blender's code.
|
||||
@ -61,6 +64,9 @@ PACKAGES_FOR_LIBS=(
|
||||
automake
|
||||
libtool
|
||||
|
||||
# Required by: `external_libsndfile` configure scripts.
|
||||
autogen
|
||||
|
||||
# Used to set rpath on shared libraries
|
||||
patchelf
|
||||
|
||||
@ -73,6 +79,21 @@ PACKAGES_FOR_LIBS=(
|
||||
mesa-libGL-devel
|
||||
mesa-libGLU-devel
|
||||
|
||||
# NOTE(@ideasman42): Currently flex's `autogen.sh` is required to run because the bundled
|
||||
# configuration is looking for an older version of `aclocal` than the system provides.
|
||||
# This is resolved by generating new configuration files which requires the `autopoint`
|
||||
# command from `gettext-devel`, if the flex package is updated we could remove this.
|
||||
# Required by: [`flex` running `autogen.sh` for `autopoint`].
|
||||
gettext-devel
|
||||
# NOTE(@ideasman42): It seems newer files generated by `autogen.sh` also require `makeinfo`
|
||||
# and there isn't a flag to disable GNU "info".
|
||||
# Required by: [`flex` as a build-time dependency for `makeinfo`].
|
||||
texinfo
|
||||
|
||||
# NOTE(@ideasman42): `nvcc` will *not* be added to the `PATH`, must be done manually.
|
||||
# Required by `external_openimagedenoise` (`nvcc` command)
|
||||
cuda-toolkit
|
||||
|
||||
# Required by: `external_ispc`.
|
||||
zlib-devel
|
||||
# TODO: dependencies build without this, consider removal.
|
||||
@ -86,7 +107,7 @@ PACKAGES_FOR_LIBS=(
|
||||
# Why are both needed?
|
||||
yasm
|
||||
|
||||
# NOTE(@campbellbarton): while `python39` is available, the default Python version is 3.6.
|
||||
# NOTE(@ideasman42): while `python39` is available, the default Python version is 3.6.
|
||||
# This is used for the `python3-mako` package for e.g.
|
||||
# So use the "default" system Python since it means it's most compatible with other packages.
|
||||
python3
|
||||
|
@ -1,7 +1,7 @@
|
||||
diff -Naur ffmpeg-clean/configure ffmpeg-dirty/configure
|
||||
--- ffmpeg-clean/configure 2023-02-27 20:43:45.000000000 +0000
|
||||
+++ ffmpeg-dirty/configure 2023-05-25 09:49:24.949566500 +0100
|
||||
@@ -6563,7 +6563,7 @@
|
||||
@@ -6675,7 +6675,7 @@
|
||||
enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; }
|
||||
enabled ladspa && require_headers "ladspa.h dlfcn.h"
|
||||
enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext
|
||||
@ -10,7 +10,7 @@ diff -Naur ffmpeg-clean/configure ffmpeg-dirty/configure
|
||||
enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
|
||||
{ enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
|
||||
die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; }
|
||||
@@ -6654,16 +6654,15 @@
|
||||
@@ -6767,18 +6767,17 @@
|
||||
require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } ||
|
||||
require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; }
|
||||
enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion
|
||||
@ -18,7 +18,9 @@ diff -Naur ffmpeg-clean/configure ffmpeg-dirty/configure
|
||||
- { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } }
|
||||
+enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version "-DOPJ_STATIC" -lopenjp2
|
||||
enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
|
||||
enabled libopenvino && require libopenvino c_api/ie_c_api.h ie_c_api_version -linference_engine_c_api
|
||||
enabled libopenvino && { { check_pkg_config libopenvino openvino openvino/c/openvino.h ov_core_create && enable openvino2; } ||
|
||||
{ check_pkg_config libopenvino openvino c_api/ie_c_api.h ie_c_api_version ||
|
||||
require libopenvino c_api/ie_c_api.h ie_c_api_version -linference_engine_c_api; } }
|
||||
enabled libopus && {
|
||||
enabled libopus_decoder && {
|
||||
- require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create
|
||||
@ -30,9 +32,9 @@ diff -Naur ffmpeg-clean/configure ffmpeg-dirty/configure
|
||||
}
|
||||
}
|
||||
enabled libplacebo && require_pkg_config libplacebo "libplacebo >= 4.192.0" libplacebo/vulkan.h pl_vulkan_create
|
||||
@@ -6696,8 +6695,8 @@
|
||||
enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
|
||||
@@ -6812,8 +6811,8 @@
|
||||
enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init
|
||||
enabled libvmaf && check_pkg_config libvmaf_cuda "libvmaf >= 2.0.0" libvmaf_cuda.h vmaf_cuda_state_init
|
||||
enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
|
||||
-enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
|
||||
- require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
|
||||
@ -41,7 +43,7 @@ diff -Naur ffmpeg-clean/configure ffmpeg-dirty/configure
|
||||
|
||||
enabled libvpx && {
|
||||
enabled libvpx_vp8_decoder && {
|
||||
@@ -6724,7 +6723,7 @@
|
||||
@@ -6840,7 +6839,7 @@
|
||||
enabled libwebp && {
|
||||
enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
|
||||
enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
@echo Setting up environment for MSYS2 MSVC 64-bit...
|
||||
|
||||
@set PATH=%CD%\usr\bin;%cd%\..\..\perl\site\bin;%cd%\..\..\perl\bin;%cd%\..\..\c\bin;%PATH%
|
||||
@set PATH=%CD%\usr\bin;%cd%\..\..\perl\site\bin;%cd%\..\..\perl\perl\bin;%cd%\..\..\c\bin;%PATH%
|
||||
|
||||
|
||||
|
@ -1,49 +1,27 @@
|
||||
diff -Naur oidn-2.0.1/core/CMakeLists.txt external_openimagedenoise/core/CMakeLists.txt
|
||||
--- oidn-2.0.1/core/CMakeLists.txt 2023-06-26 09:06:31.000000000 -0600
|
||||
+++ external_openimagedenoise/core/CMakeLists.txt 2023-07-01 10:54:06.347161100 -0600
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
add_library(OpenImageDenoise_core SHARED ${OIDN_CORE_SOURCES} ${OIDN_RESOURCE_FILE})
|
||||
diff -Naur oidn-2.2.0/core/CMakeLists.txt external_openimagedenoise/core/CMakeLists.txt
|
||||
--- oidn-2.2.0/core/CMakeLists.txt 2024-02-01 17:52:16 -0700
|
||||
+++ external_openimagedenoise/core/CMakeLists.txt 2024-02-03 12:41:34 -0700
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
add_library(OpenImageDenoise_core ${OIDN_CORE_LIB_TYPE} ${OIDN_CORE_SOURCES} ${OIDN_RESOURCE_FILE})
|
||||
set_property(TARGET OpenImageDenoise_core PROPERTY VERSION ${PROJECT_VERSION})
|
||||
-
|
||||
+target_compile_definitions(OpenImageDenoise_core PRIVATE SHARED_POSTFIX=\"$<$<CONFIG:Debug>:$<TARGET_PROPERTY:OpenImageDenoise_core,DEBUG_POSTFIX>>\")
|
||||
target_link_libraries(OpenImageDenoise_core
|
||||
PUBLIC
|
||||
OpenImageDenoise_common
|
||||
diff -Naur oidn-2.0.1/core/module.cpp external_openimagedenoise/core/module.cpp
|
||||
--- oidn-2.0.1/core/module.cpp 2023-06-26 09:06:31.000000000 -0600
|
||||
+++ external_openimagedenoise/core/module.cpp 2023-07-01 10:49:59.924876500 -0600
|
||||
diff -Naur oidn-2.2.0/core/module.cpp external_openimagedenoise/core/module.cpp
|
||||
--- oidn-2.2.0/core/module.cpp 2024-02-01 17:52:16 -0700
|
||||
+++ external_openimagedenoise/core/module.cpp 2024-02-03 12:41:34 -0700
|
||||
@@ -29,7 +29,7 @@
|
||||
return true; // module already loaded
|
||||
|
||||
|
||||
// Get the path of the module to load
|
||||
- std::string filename = "OpenImageDenoise_" + name;
|
||||
+ std::string filename = "OpenImageDenoise_" + name + SHARED_POSTFIX;
|
||||
#if defined(_WIN32)
|
||||
filename += ".dll";
|
||||
#else
|
||||
diff -Naur oidn-2.1.0/devices/CMakeLists.txt external_openimagedenoise/devices/CMakeLists.txt
|
||||
--- oidn-2.1.0/devices/CMakeLists.txt 2023-10-11 14:04:08 -0600
|
||||
+++ external_openimagedenoise/devices/CMakeLists.txt 2023-12-23 09:34:17 -0700
|
||||
@@ -59,6 +59,8 @@
|
||||
-DOIDN_API_NAMESPACE:STRING=${OIDN_API_NAMESPACE}
|
||||
-DOIDN_WARN_AS_ERRORS:BOOL=${OIDN_WARN_AS_ERRORS}
|
||||
-DOIDN_SANITIZER:STRING=${OIDN_SANITIZER}
|
||||
+ -DPython_EXECUTABLE:STRING=${Python_EXECUTABLE}
|
||||
+ -DCMAKE_DEBUG_POSTFIX:STRING=${CMAKE_DEBUG_POSTFIX}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
OpenImageDenoise_core
|
||||
@@ -149,6 +151,7 @@
|
||||
-DOIDN_API_NAMESPACE:STRING=${OIDN_API_NAMESPACE}
|
||||
-DOIDN_WARN_AS_ERRORS:BOOL=${OIDN_WARN_AS_ERRORS}
|
||||
-DOIDN_SANITIZER:STRING=${OIDN_SANITIZER}
|
||||
+ -DPython_EXECUTABLE:STRING=${Python_EXECUTABLE}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
OpenImageDenoise_core
|
||||
--- a/core/module.cpp 2023-11-16 19:07:32
|
||||
+++ b/core/module.cpp 2023-11-16 19:08:01
|
||||
@@ -37,7 +37,8 @@
|
||||
"." + toString(OIDN_VERSION_MINOR) +
|
||||
"." + toString(OIDN_VERSION_PATCH);
|
||||
@ -54,3 +32,23 @@ diff -Naur oidn-2.1.0/devices/CMakeLists.txt external_openimagedenoise/devices/C
|
||||
#else
|
||||
filename = "lib" + filename + ".so" + versionStr;
|
||||
#endif
|
||||
diff -Naur oidn-2.2.0/devices/CMakeLists.txt external_openimagedenoise/devices/CMakeLists.txt
|
||||
--- oidn-2.2.0/devices/CMakeLists.txt 2024-02-01 17:52:16 -0700
|
||||
+++ external_openimagedenoise/devices/CMakeLists.txt 2024-02-03 13:10:31 -0700
|
||||
@@ -65,6 +65,7 @@
|
||||
-DOIDN_WARN_AS_ERRORS:BOOL=${OIDN_WARN_AS_ERRORS}
|
||||
-DOIDN_SANITIZER:STRING=${OIDN_SANITIZER}
|
||||
-DOIDN_DEVICE_CUDA_API:STRING=${OIDN_DEVICE_CUDA_API}
|
||||
+ -DPython_EXECUTABLE:STRING=${Python_EXECUTABLE}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
OpenImageDenoise_core
|
||||
@@ -155,6 +156,8 @@
|
||||
-DOIDN_API_NAMESPACE:STRING=${OIDN_API_NAMESPACE}
|
||||
-DOIDN_WARN_AS_ERRORS:BOOL=${OIDN_WARN_AS_ERRORS}
|
||||
-DOIDN_SANITIZER:STRING=${OIDN_SANITIZER}
|
||||
+ -DPython_EXECUTABLE:STRING=${Python_EXECUTABLE}
|
||||
+ -DCMAKE_DEBUG_POSTFIX:STRING=${CMAKE_DEBUG_POSTFIX}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
OpenImageDenoise_core
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = V4.1
|
||||
PROJECT_NUMBER = V4.2
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
@ -352,6 +352,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO_NORMAL',
|
||||
)
|
||||
denoising_use_gpu: BoolProperty(
|
||||
name="Denoise on GPU",
|
||||
description="Perform denoising on GPU devices, if available. This is significantly faster than on CPU, but requires additional GPU memory. When large scenes need more GPU memory, this option can be disabled",
|
||||
default=False,
|
||||
)
|
||||
|
||||
use_preview_denoising: BoolProperty(
|
||||
name="Use Viewport Denoising",
|
||||
@ -382,6 +387,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
min=0, max=(1 << 24),
|
||||
default=1,
|
||||
)
|
||||
preview_denoising_use_gpu: BoolProperty(
|
||||
name="Denoise Preview on GPU",
|
||||
description="Perform denoising on GPU devices, if available. This is significantly faster than on CPU, but requires additional GPU memory. When large scenes need more GPU memory, this option can be disabled",
|
||||
default=True,
|
||||
)
|
||||
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
@ -1591,6 +1601,22 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
def has_active_device(self):
|
||||
return self.get_num_gpu_devices() > 0
|
||||
|
||||
def has_oidn_gpu_devices(self):
|
||||
import _cycles
|
||||
compute_device_type = self.get_compute_device_type()
|
||||
|
||||
# We need non-CPU devices, used for rendering and supporting OIDN GPU denoising
|
||||
for device in _cycles.available_devices(compute_device_type):
|
||||
device_type = device[1]
|
||||
if device_type == 'CPU':
|
||||
continue
|
||||
|
||||
has_device_oidn_support = device[5]
|
||||
if has_device_oidn_support and self.find_existing_device_entry(device).use:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _draw_devices(self, layout, device_type, devices):
|
||||
box = layout.box()
|
||||
|
||||
@ -1685,12 +1711,13 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
import _cycles
|
||||
has_peer_memory = 0
|
||||
has_rt_api_support = False
|
||||
has_rt_api_support = {'METAL': False, 'HIP': False, 'ONEAPI': False}
|
||||
for device in _cycles.available_devices(compute_device_type):
|
||||
if device[3] and self.find_existing_device_entry(device).use:
|
||||
has_peer_memory += 1
|
||||
if device[4] and self.find_existing_device_entry(device).use:
|
||||
has_rt_api_support = True
|
||||
device_type = device[1]
|
||||
has_rt_api_support[device_type] = True
|
||||
|
||||
if has_peer_memory > 1:
|
||||
row = layout.row()
|
||||
@ -1708,25 +1735,25 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
# MetalRT only works on Apple Silicon and Navi2.
|
||||
is_arm64 = platform.machine() == 'arm64'
|
||||
if is_arm64 or (is_navi_2 and has_rt_api_support):
|
||||
if is_arm64 or (is_navi_2 and has_rt_api_support['METAL']):
|
||||
col = layout.column()
|
||||
col.use_property_split = True
|
||||
# Kernel specialization is only supported on Apple Silicon
|
||||
if is_arm64:
|
||||
col.prop(self, "kernel_optimization_level")
|
||||
if has_rt_api_support:
|
||||
if has_rt_api_support['METAL']:
|
||||
col.prop(self, "metalrt")
|
||||
|
||||
if compute_device_type == 'HIP':
|
||||
import platform
|
||||
if platform.system() == "Windows": # HIP-RT is currently only supported on Windows
|
||||
has_cuda, has_optix, has_hip, has_metal, has_oneapi, has_hiprt = _cycles.get_device_types()
|
||||
row = layout.row()
|
||||
row.enabled = has_hiprt
|
||||
row.active = has_rt_api_support['HIP']
|
||||
row.prop(self, "use_hiprt")
|
||||
|
||||
elif compute_device_type == 'ONEAPI' and _cycles.with_embree_gpu:
|
||||
row = layout.row()
|
||||
row.active = has_rt_api_support['ONEAPI']
|
||||
row.prop(self, "use_oneapirt")
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -157,6 +157,10 @@ def get_effective_preview_denoiser(context):
|
||||
return 'OIDN'
|
||||
|
||||
|
||||
def has_oidn_gpu_devices(context):
|
||||
return context.preferences.addons[__package__].preferences.has_oidn_gpu_devices()
|
||||
|
||||
|
||||
def use_mnee(context):
|
||||
# The MNEE kernel doesn't compile on macOS < 13.
|
||||
if use_metal(context):
|
||||
@ -236,6 +240,11 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
|
||||
|
||||
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||
|
||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
||||
row = col.row()
|
||||
row.active = not use_cpu(context) and has_oidn_gpu_devices(context)
|
||||
row.prop(cscene, "preview_denoising_use_gpu", text="Use GPU")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
@ -295,6 +304,11 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
||||
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
row = col.row()
|
||||
row.active = not use_cpu(context) and has_oidn_gpu_devices(context)
|
||||
row.prop(cscene, "denoising_use_gpu", text="Use GPU")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Path Guiding"
|
||||
@ -1573,6 +1587,7 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
|
||||
col.separator()
|
||||
|
||||
if light.type in {'POINT', 'SPOT'}:
|
||||
col.prop(light, "use_soft_falloff")
|
||||
col.prop(light, "shadow_soft_size", text="Radius")
|
||||
elif light.type == 'SUN':
|
||||
col.prop(light, "angle")
|
||||
@ -1587,6 +1602,7 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
|
||||
sub.prop(light, "size_y", text="Y")
|
||||
|
||||
if not (light.type == 'AREA' and clamp.is_portal):
|
||||
col.separator()
|
||||
sub = col.column()
|
||||
sub.prop(clamp, "max_bounces")
|
||||
|
||||
|
@ -48,6 +48,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||
BL::PointLight b_point_light(b_light);
|
||||
light->set_size(b_point_light.shadow_soft_size());
|
||||
light->set_light_type(LIGHT_POINT);
|
||||
light->set_is_sphere(!b_point_light.use_soft_falloff());
|
||||
break;
|
||||
}
|
||||
case BL::Light::type_SPOT: {
|
||||
@ -56,6 +57,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||
light->set_light_type(LIGHT_SPOT);
|
||||
light->set_spot_angle(b_spot_light.spot_size());
|
||||
light->set_spot_smooth(b_spot_light.spot_blend());
|
||||
light->set_is_sphere(!b_spot_light.use_soft_falloff());
|
||||
break;
|
||||
}
|
||||
/* Hemi were removed from 2.8 */
|
||||
|
@ -417,12 +417,14 @@ static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args)
|
||||
for (size_t i = 0; i < devices.size(); i++) {
|
||||
DeviceInfo &device = devices[i];
|
||||
string type_name = Device::string_from_type(device.type);
|
||||
PyObject *device_tuple = PyTuple_New(5);
|
||||
PyObject *device_tuple = PyTuple_New(6);
|
||||
PyTuple_SET_ITEM(device_tuple, 0, pyunicode_from_string(device.description.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 1, pyunicode_from_string(type_name.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 2, pyunicode_from_string(device.id.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 3, PyBool_FromLong(device.has_peer_memory));
|
||||
PyTuple_SET_ITEM(device_tuple, 4, PyBool_FromLong(device.use_hardware_raytracing));
|
||||
PyTuple_SET_ITEM(
|
||||
device_tuple, 5, PyBool_FromLong(device.denoisers & DENOISER_OPENIMAGEDENOISE));
|
||||
PyTuple_SET_ITEM(ret, i, device_tuple);
|
||||
}
|
||||
|
||||
|
@ -474,10 +474,12 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
* is that the interface and the integrator are technically out of sync. */
|
||||
if (denoise_params.use) {
|
||||
integrator->set_denoiser_type(denoise_params.type);
|
||||
integrator->set_denoise_use_gpu(denoise_params.use_gpu);
|
||||
integrator->set_denoise_start_sample(denoise_params.start_sample);
|
||||
integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo);
|
||||
integrator->set_use_denoise_pass_normal(denoise_params.use_pass_normal);
|
||||
integrator->set_denoiser_prefilter(denoise_params.prefilter);
|
||||
integrator->set_denoiser_quality(denoise_params.quality);
|
||||
}
|
||||
|
||||
/* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the
|
||||
@ -970,8 +972,12 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
/* Final Render Denoising */
|
||||
denoising.use = get_boolean(cscene, "use_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.use_gpu = get_boolean(cscene, "denoising_use_gpu");
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
|
||||
/* This currently only affects NVIDIA and the difference in quality is too small to justify
|
||||
* exposing a setting to the user. */
|
||||
denoising.quality = DENOISER_QUALITY_HIGH;
|
||||
|
||||
input_passes = (DenoiserInput)get_enum(
|
||||
cscene, "denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
|
||||
@ -988,8 +994,12 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
denoising.use = get_boolean(cscene, "use_preview_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(
|
||||
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.use_gpu = get_boolean(cscene, "preview_denoising_use_gpu");
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
|
||||
/* This currently only affects NVIDIA and the difference in quality is too small to justify
|
||||
* exposing a setting to the user. */
|
||||
denoising.quality = DENOISER_QUALITY_BALANCED;
|
||||
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
|
||||
|
||||
input_passes = (DenoiserInput)get_enum(
|
||||
|
@ -195,7 +195,11 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
||||
VLOG_INFO << "Device has compute preemption or is not used for display.";
|
||||
devices.push_back(info);
|
||||
}
|
||||
VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
|
||||
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
|
||||
|
||||
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
|
||||
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
|
||||
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
|
||||
}
|
||||
|
||||
if (!display_devices.empty()) {
|
||||
|
@ -48,12 +48,25 @@ const NodeEnum *DenoiseParams::get_prefilter_enum()
|
||||
return &prefilter_enum;
|
||||
}
|
||||
|
||||
const NodeEnum *DenoiseParams::get_quality_enum()
|
||||
{
|
||||
static NodeEnum quality_enum;
|
||||
|
||||
if (quality_enum.empty()) {
|
||||
quality_enum.insert("high", DENOISER_QUALITY_HIGH);
|
||||
quality_enum.insert("balanced", DENOISER_QUALITY_BALANCED);
|
||||
}
|
||||
|
||||
return &quality_enum;
|
||||
}
|
||||
|
||||
NODE_DEFINE(DenoiseParams)
|
||||
{
|
||||
NodeType *type = NodeType::add("denoise_params", create);
|
||||
|
||||
const NodeEnum *type_enum = get_type_enum();
|
||||
const NodeEnum *prefilter_enum = get_prefilter_enum();
|
||||
const NodeEnum *quality_enum = get_quality_enum();
|
||||
|
||||
SOCKET_BOOLEAN(use, "Use", false);
|
||||
|
||||
@ -67,6 +80,7 @@ NODE_DEFINE(DenoiseParams)
|
||||
SOCKET_BOOLEAN(temporally_stable, "Temporally Stable", false);
|
||||
|
||||
SOCKET_ENUM(prefilter, "Prefilter", *prefilter_enum, DENOISER_PREFILTER_FAST);
|
||||
SOCKET_ENUM(quality, "Quality", *quality_enum, DENOISER_QUALITY_HIGH);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
@ -40,6 +40,12 @@ enum DenoiserPrefilter {
|
||||
DENOISER_PREFILTER_NUM,
|
||||
};
|
||||
|
||||
enum DenoiserQuality {
|
||||
DENOISER_QUALITY_HIGH = 1,
|
||||
DENOISER_QUALITY_BALANCED = 2,
|
||||
DENOISER_QUALITY_NUM,
|
||||
};
|
||||
|
||||
/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization.
|
||||
* The default values here do not really matter as they are always initialized from the
|
||||
* Integrator node. */
|
||||
@ -63,20 +69,19 @@ class DenoiseParams : public Node {
|
||||
/* Configure the denoiser to use motion vectors, previous image and a temporally stable model. */
|
||||
bool temporally_stable = false;
|
||||
|
||||
/* If true, then allow, if supported, OpenImageDenoise to use GPU device.
|
||||
* If false, then OpenImageDenoise will always use CPU regardless of GPU device
|
||||
* precense. */
|
||||
bool use_gpu = true;
|
||||
|
||||
DenoiserPrefilter prefilter = DENOISER_PREFILTER_FAST;
|
||||
DenoiserQuality quality = DENOISER_QUALITY_HIGH;
|
||||
|
||||
static const NodeEnum *get_type_enum();
|
||||
static const NodeEnum *get_prefilter_enum();
|
||||
static const NodeEnum *get_quality_enum();
|
||||
|
||||
DenoiseParams();
|
||||
|
||||
bool modified(const DenoiseParams &other) const
|
||||
{
|
||||
return !(use == other.use && type == other.type && start_sample == other.start_sample &&
|
||||
use_pass_albedo == other.use_pass_albedo &&
|
||||
use_pass_normal == other.use_pass_normal &&
|
||||
temporally_stable == other.temporally_stable && prefilter == other.prefilter);
|
||||
}
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -257,6 +257,12 @@ class Device {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns native buffer handle for device pointer. */
|
||||
virtual void *get_native_buffer(device_ptr /*ptr*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Guiding */
|
||||
|
||||
/* Returns path guiding device handle. */
|
||||
|
@ -206,7 +206,11 @@ void device_hip_info(vector<DeviceInfo> &devices)
|
||||
devices.push_back(info);
|
||||
}
|
||||
|
||||
VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
|
||||
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
|
||||
|
||||
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
|
||||
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
|
||||
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
|
||||
}
|
||||
|
||||
if (!display_devices.empty())
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
# include "device/metal/device.h"
|
||||
# include "device/metal/device_impl.h"
|
||||
# include "integrator/denoiser_oidn_gpu.h"
|
||||
|
||||
#endif
|
||||
|
||||
@ -55,6 +56,11 @@ void device_metal_info(vector<DeviceInfo> &devices)
|
||||
info.display_device = true;
|
||||
info.denoisers = DENOISER_NONE;
|
||||
info.id = id;
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
if (OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
}
|
||||
# endif
|
||||
|
||||
MetalGPUVendor vendor = MetalInfo::get_device_vendor(device);
|
||||
|
||||
@ -79,6 +85,12 @@ void device_metal_info(vector<DeviceInfo> &devices)
|
||||
|
||||
devices.push_back(info);
|
||||
device_index++;
|
||||
|
||||
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
|
||||
|
||||
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
|
||||
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
|
||||
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,8 @@ class MetalDevice : public Device {
|
||||
|
||||
virtual bool should_use_graphics_interop() override;
|
||||
|
||||
virtual void *get_native_buffer(device_ptr ptr) override;
|
||||
|
||||
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
|
||||
|
||||
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
|
||||
|
@ -1389,6 +1389,11 @@ bool MetalDevice::should_use_graphics_interop()
|
||||
return false;
|
||||
}
|
||||
|
||||
void *MetalDevice::get_native_buffer(device_ptr ptr)
|
||||
{
|
||||
return ((MetalMem *)ptr)->mtlBuffer;
|
||||
}
|
||||
|
||||
void MetalDevice::flush_delayed_free_list()
|
||||
{
|
||||
/* free any Metal buffers that may have been freed by host while a command
|
||||
|
@ -40,6 +40,8 @@ class MetalDeviceQueue : public DeviceQueue {
|
||||
virtual void copy_to_device(device_memory &mem) override;
|
||||
virtual void copy_from_device(device_memory &mem) override;
|
||||
|
||||
virtual void *native_queue() override;
|
||||
|
||||
protected:
|
||||
void setup_capture();
|
||||
void update_capture(DeviceKernel kernel);
|
||||
|
@ -979,6 +979,11 @@ void MetalDeviceQueue::close_blit_encoder()
|
||||
}
|
||||
}
|
||||
|
||||
void *MetalDeviceQueue::native_queue()
|
||||
{
|
||||
return mtlCommandQueue_;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_METAL */
|
||||
|
@ -131,7 +131,11 @@ static void device_iterator_cb(
|
||||
# endif
|
||||
|
||||
devices->push_back(info);
|
||||
VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
|
||||
VLOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
|
||||
|
||||
if (info.denoisers & DENOISER_OPENIMAGEDENOISE)
|
||||
VLOG_INFO << "Device with id \"" << info.id << "\" is supporting "
|
||||
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -157,6 +157,11 @@ class DeviceQueue {
|
||||
/* Device this queue has been created for. */
|
||||
Device *device;
|
||||
|
||||
virtual void *native_queue()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Hide construction so that allocation via `Device` API is enforced. */
|
||||
explicit DeviceQueue(Device *device);
|
||||
|
@ -27,7 +27,9 @@ unique_ptr<Denoiser> Denoiser::create(Device *path_trace_device, const DenoisePa
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
if (params.type == DENOISER_OPENIMAGEDENOISE && path_trace_device->info.type != DEVICE_CPU &&
|
||||
/* If available and allowed, then we will use OpenImageDenoise on GPU, otherwise on CPU. */
|
||||
if (params.type == DENOISER_OPENIMAGEDENOISE && params.use_gpu &&
|
||||
path_trace_device->info.type != DEVICE_CPU &&
|
||||
OIDNDenoiserGPU::is_device_supported(path_trace_device->info))
|
||||
{
|
||||
return make_unique<OIDNDenoiserGPU>(path_trace_device, params);
|
||||
|
@ -324,9 +324,9 @@ void DenoiserGPU::denoise_color_read(const DenoiseContext &context, const Denois
|
||||
denoiser_queue_.get(), pass_access_info, 1.0f, context.num_samples);
|
||||
|
||||
PassAccessor::Destination destination(pass_access_info.type);
|
||||
destination.d_pixels = context.render_buffers->buffer.device_pointer +
|
||||
pass.denoised_offset * sizeof(float);
|
||||
destination.d_pixels = context.render_buffers->buffer.device_pointer;
|
||||
destination.num_components = 3;
|
||||
destination.pixel_offset = pass.denoised_offset;
|
||||
destination.pixel_stride = context.buffer_params.pass_stride;
|
||||
|
||||
BufferParams buffer_params = context.buffer_params;
|
||||
|
@ -164,6 +164,18 @@ class OIDNDenoiseContext {
|
||||
oidn_filter.setProgressMonitorFunction(oidn_progress_monitor_function, denoiser_);
|
||||
oidn_filter.set("hdr", true);
|
||||
oidn_filter.set("srgb", false);
|
||||
|
||||
# if OIDN_VERSION_MAJOR >= 2
|
||||
switch (denoise_params_.quality) {
|
||||
case DENOISER_QUALITY_BALANCED:
|
||||
oidn_filter.set("quality", OIDN_QUALITY_BALANCED);
|
||||
break;
|
||||
case DENOISER_QUALITY_HIGH:
|
||||
default:
|
||||
oidn_filter.set("quality", OIDN_QUALITY_HIGH);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (denoise_params_.prefilter == DENOISER_PREFILTER_NONE ||
|
||||
denoise_params_.prefilter == DENOISER_PREFILTER_ACCURATE)
|
||||
{
|
||||
|
@ -47,6 +47,20 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
|
||||
case DEVICE_OPTIX:
|
||||
device_type = OIDN_DEVICE_TYPE_CUDA;
|
||||
break;
|
||||
# endif
|
||||
# ifdef OIDN_DEVICE_METAL
|
||||
case DEVICE_METAL: {
|
||||
int num_devices = oidnGetNumPhysicalDevices();
|
||||
for (int i = 0; i < num_devices; i++) {
|
||||
if (oidnGetPhysicalDeviceUInt(i, "type") == OIDN_DEVICE_TYPE_METAL) {
|
||||
const char *name = oidnGetPhysicalDeviceString(i, "name");
|
||||
if (device.id.find(name) != std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
case DEVICE_CPU:
|
||||
/* This is the GPU denoiser - CPU devices shouldn't end up here. */
|
||||
@ -82,18 +96,7 @@ OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams
|
||||
|
||||
OIDNDenoiserGPU::~OIDNDenoiserGPU()
|
||||
{
|
||||
if (albedo_filter_) {
|
||||
oidnReleaseFilter(albedo_filter_);
|
||||
}
|
||||
if (normal_filter_) {
|
||||
oidnReleaseFilter(normal_filter_);
|
||||
}
|
||||
if (oidn_filter_) {
|
||||
oidnReleaseFilter(oidn_filter_);
|
||||
}
|
||||
if (oidn_device_) {
|
||||
oidnReleaseDevice(oidn_device_);
|
||||
}
|
||||
release_all_resources();
|
||||
}
|
||||
|
||||
bool OIDNDenoiserGPU::denoise_buffer(const BufferParams &buffer_params,
|
||||
@ -111,6 +114,9 @@ uint OIDNDenoiserGPU::get_device_type_mask() const
|
||||
# ifdef OIDN_DEVICE_SYCL
|
||||
device_mask |= DEVICE_MASK_ONEAPI;
|
||||
# endif
|
||||
# ifdef OIDN_DEVICE_METAL
|
||||
device_mask |= DEVICE_MASK_METAL;
|
||||
# endif
|
||||
# ifdef OIDN_DEVICE_CUDA
|
||||
device_mask |= DEVICE_MASK_CUDA;
|
||||
device_mask |= DEVICE_MASK_OPTIX;
|
||||
@ -132,26 +138,67 @@ OIDNFilter OIDNDenoiserGPU::create_filter()
|
||||
denoiser_device_->set_error(error_message);
|
||||
}
|
||||
}
|
||||
|
||||
# if OIDN_VERSION_MAJOR >= 2
|
||||
switch (quality_) {
|
||||
case DENOISER_QUALITY_BALANCED:
|
||||
oidnSetFilterInt(filter, "quality", OIDN_QUALITY_BALANCED);
|
||||
break;
|
||||
case DENOISER_QUALITY_HIGH:
|
||||
default:
|
||||
oidnSetFilterInt(filter, "quality", OIDN_QUALITY_HIGH);
|
||||
}
|
||||
# endif
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
bool OIDNDenoiserGPU::commit_and_execute_filter(OIDNFilter filter, ExecMode mode)
|
||||
{
|
||||
const char *error_message = nullptr;
|
||||
OIDNError err = OIDN_ERROR_NONE;
|
||||
|
||||
for (;;) {
|
||||
oidnCommitFilter(filter);
|
||||
if (mode == ExecMode::ASYNC) {
|
||||
oidnExecuteFilterAsync(filter);
|
||||
}
|
||||
else {
|
||||
oidnExecuteFilter(filter);
|
||||
}
|
||||
|
||||
/* If OIDN runs out of memory, reduce mem limit and retry */
|
||||
err = oidnGetDeviceError(oidn_device_, (const char **)&error_message);
|
||||
if (err != OIDN_ERROR_OUT_OF_MEMORY || max_mem_ < 200) {
|
||||
break;
|
||||
}
|
||||
max_mem_ = max_mem_ / 2;
|
||||
oidnSetFilterInt(oidn_filter_, "maxMemoryMB", max_mem_);
|
||||
}
|
||||
|
||||
if (err != OIDN_ERROR_NONE) {
|
||||
if (error_message == nullptr) {
|
||||
error_message = "Unspecified OIDN error";
|
||||
}
|
||||
LOG(ERROR) << "OIDN error: " << error_message;
|
||||
denoiser_device_->set_error(error_message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
{
|
||||
const bool recreate_denoiser = (oidn_device_ == nullptr) || (oidn_filter_ == nullptr) ||
|
||||
(use_pass_albedo_ != context.use_pass_albedo) ||
|
||||
(use_pass_normal_ != context.use_pass_normal);
|
||||
(use_pass_normal_ != context.use_pass_normal) ||
|
||||
(quality_ != params_.quality);
|
||||
if (!recreate_denoiser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Destroy existing handle before creating new one. */
|
||||
if (oidn_filter_) {
|
||||
oidnReleaseFilter(oidn_filter_);
|
||||
}
|
||||
|
||||
if (oidn_device_) {
|
||||
oidnReleaseDevice(oidn_device_);
|
||||
}
|
||||
/* Destroy existing handles before creating new ones. */
|
||||
release_all_resources();
|
||||
|
||||
switch (denoiser_device_->info.type) {
|
||||
# if defined(OIDN_DEVICE_SYCL) && defined(WITH_ONEAPI)
|
||||
@ -161,6 +208,13 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
1);
|
||||
break;
|
||||
# endif
|
||||
# if defined(OIDN_DEVICE_METAL) && defined(WITH_METAL)
|
||||
case DEVICE_METAL: {
|
||||
denoiser_queue_->init_execution();
|
||||
const MTLCommandQueue_id queue = (const MTLCommandQueue_id)denoiser_queue_->native_queue();
|
||||
oidn_device_ = oidnNewMetalDevice(&queue, 1);
|
||||
} break;
|
||||
# endif
|
||||
# if defined(OIDN_DEVICE_CUDA) && defined(WITH_CUDA)
|
||||
case DEVICE_CUDA:
|
||||
case DEVICE_OPTIX: {
|
||||
@ -192,6 +246,8 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
|
||||
oidnCommitDevice(oidn_device_);
|
||||
|
||||
quality_ = params_.quality;
|
||||
|
||||
oidn_filter_ = create_filter();
|
||||
if (oidn_filter_ == nullptr) {
|
||||
return false;
|
||||
@ -199,12 +255,6 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
|
||||
oidnSetFilterBool(oidn_filter_, "hdr", true);
|
||||
oidnSetFilterBool(oidn_filter_, "srgb", false);
|
||||
oidnSetFilterInt(oidn_filter_, "maxMemoryMB", max_mem_);
|
||||
if (params_.prefilter == DENOISER_PREFILTER_NONE ||
|
||||
params_.prefilter == DENOISER_PREFILTER_ACCURATE)
|
||||
{
|
||||
oidnSetFilterInt(oidn_filter_, "cleanAux", true);
|
||||
}
|
||||
|
||||
if (context.use_pass_albedo) {
|
||||
albedo_filter_ = create_filter();
|
||||
@ -249,24 +299,25 @@ bool OIDNDenoiserGPU::denoise_run(const DenoiseContext &context, const DenoisePa
|
||||
/* Color pass. */
|
||||
const int64_t pass_stride_in_bytes = context.buffer_params.pass_stride * sizeof(float);
|
||||
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"color",
|
||||
(void *)context.render_buffers->buffer.device_pointer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
pass.denoised_offset * sizeof(float),
|
||||
pass_stride_in_bytes,
|
||||
pass_stride_in_bytes * context.buffer_params.stride);
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"output",
|
||||
(void *)context.render_buffers->buffer.device_pointer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
pass.denoised_offset * sizeof(float),
|
||||
pass_stride_in_bytes,
|
||||
pass_stride_in_bytes * context.buffer_params.stride);
|
||||
set_filter_pass(oidn_filter_,
|
||||
"color",
|
||||
context.render_buffers->buffer.device_pointer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
pass.denoised_offset * sizeof(float),
|
||||
pass_stride_in_bytes,
|
||||
pass_stride_in_bytes * context.buffer_params.stride);
|
||||
|
||||
set_filter_pass(oidn_filter_,
|
||||
"output",
|
||||
context.render_buffers->buffer.device_pointer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
pass.denoised_offset * sizeof(float),
|
||||
pass_stride_in_bytes,
|
||||
pass_stride_in_bytes * context.buffer_params.stride);
|
||||
|
||||
/* Optional albedo and color passes. */
|
||||
if (context.num_input_passes > 1) {
|
||||
@ -275,125 +326,146 @@ bool OIDNDenoiserGPU::denoise_run(const DenoiseContext &context, const DenoisePa
|
||||
const int64_t row_stride_in_bytes = context.guiding_params.stride * pixel_stride_in_bytes;
|
||||
|
||||
if (context.use_pass_albedo) {
|
||||
if (params_.prefilter == DENOISER_PREFILTER_NONE) {
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"albedo",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
}
|
||||
else {
|
||||
oidnSetSharedFilterImage(albedo_filter_,
|
||||
"color",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
oidnSetSharedFilterImage(albedo_filter_,
|
||||
"output",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
oidnCommitFilter(albedo_filter_);
|
||||
oidnExecuteFilterAsync(albedo_filter_);
|
||||
set_filter_pass(oidn_filter_,
|
||||
"albedo",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"albedo",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
if (params_.prefilter == DENOISER_PREFILTER_ACCURATE) {
|
||||
set_filter_pass(albedo_filter_,
|
||||
"albedo",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
set_filter_pass(albedo_filter_,
|
||||
"output",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_albedo * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
if (!commit_and_execute_filter(albedo_filter_, ExecMode::ASYNC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context.use_pass_normal) {
|
||||
if (params_.prefilter == DENOISER_PREFILTER_NONE) {
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"normal",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
}
|
||||
else {
|
||||
oidnSetSharedFilterImage(normal_filter_,
|
||||
"color",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
set_filter_pass(oidn_filter_,
|
||||
"normal",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
oidnSetSharedFilterImage(normal_filter_,
|
||||
"output",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
if (params_.prefilter == DENOISER_PREFILTER_ACCURATE) {
|
||||
set_filter_pass(normal_filter_,
|
||||
"normal",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
oidnCommitFilter(normal_filter_);
|
||||
oidnExecuteFilterAsync(normal_filter_);
|
||||
set_filter_pass(normal_filter_,
|
||||
"output",
|
||||
d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
oidnSetSharedFilterImage(oidn_filter_,
|
||||
"normal",
|
||||
(void *)d_guiding_buffer,
|
||||
OIDN_FORMAT_FLOAT3,
|
||||
context.buffer_params.width,
|
||||
context.buffer_params.height,
|
||||
context.guiding_params.pass_normal * sizeof(float),
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
if (!commit_and_execute_filter(normal_filter_, ExecMode::ASYNC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oidnCommitFilter(oidn_filter_);
|
||||
oidnExecuteFilter(oidn_filter_);
|
||||
oidnSetFilterInt(oidn_filter_, "cleanAux", params_.prefilter != DENOISER_PREFILTER_FAST);
|
||||
return commit_and_execute_filter(oidn_filter_);
|
||||
}
|
||||
|
||||
const char *out_message = nullptr;
|
||||
OIDNError err = oidnGetDeviceError(oidn_device_, (const char **)&out_message);
|
||||
if (OIDN_ERROR_NONE != err) {
|
||||
/* If OIDN runs out of memory, reduce mem limit and retry */
|
||||
while (err == OIDN_ERROR_OUT_OF_MEMORY && max_mem_ > 200) {
|
||||
max_mem_ = max_mem_ / 2;
|
||||
oidnSetFilterInt(oidn_filter_, "maxMemoryMB", max_mem_);
|
||||
oidnCommitFilter(oidn_filter_);
|
||||
oidnExecuteFilter(oidn_filter_);
|
||||
err = oidnGetDeviceError(oidn_device_, &out_message);
|
||||
}
|
||||
if (out_message) {
|
||||
LOG(ERROR) << "OIDN error: " << out_message;
|
||||
denoiser_device_->set_error(out_message);
|
||||
}
|
||||
else {
|
||||
LOG(ERROR) << "OIDN error: unspecified";
|
||||
denoiser_device_->set_error("Unspecified OIDN error");
|
||||
}
|
||||
return false;
|
||||
void OIDNDenoiserGPU::set_filter_pass(OIDNFilter filter,
|
||||
const char *name,
|
||||
device_ptr ptr,
|
||||
int format,
|
||||
int width,
|
||||
int height,
|
||||
size_t offset_in_bytes,
|
||||
size_t pixel_stride_in_bytes,
|
||||
size_t row_stride_in_bytes)
|
||||
{
|
||||
# if defined(OIDN_DEVICE_METAL) && defined(WITH_METAL)
|
||||
if (denoiser_device_->info.type == DEVICE_METAL) {
|
||||
void *mtl_buffer = denoiser_device_->get_native_buffer(ptr);
|
||||
OIDNBuffer oidn_buffer = oidnNewSharedBufferFromMetal(oidn_device_, mtl_buffer);
|
||||
|
||||
oidnSetFilterImage(filter,
|
||||
name,
|
||||
oidn_buffer,
|
||||
(OIDNFormat)format,
|
||||
width,
|
||||
height,
|
||||
offset_in_bytes,
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
|
||||
oidnReleaseBuffer(oidn_buffer);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
oidnSetSharedFilterImage(filter,
|
||||
name,
|
||||
(void *)ptr,
|
||||
(OIDNFormat)format,
|
||||
width,
|
||||
height,
|
||||
offset_in_bytes,
|
||||
pixel_stride_in_bytes,
|
||||
row_stride_in_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void OIDNDenoiserGPU::release_all_resources()
|
||||
{
|
||||
if (albedo_filter_) {
|
||||
oidnReleaseFilter(albedo_filter_);
|
||||
albedo_filter_ = nullptr;
|
||||
}
|
||||
if (normal_filter_) {
|
||||
oidnReleaseFilter(normal_filter_);
|
||||
normal_filter_ = nullptr;
|
||||
}
|
||||
if (oidn_filter_) {
|
||||
oidnReleaseFilter(oidn_filter_);
|
||||
oidn_filter_ = nullptr;
|
||||
}
|
||||
if (oidn_device_) {
|
||||
oidnReleaseDevice(oidn_device_);
|
||||
oidn_device_ = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -36,6 +36,11 @@ class OIDNDenoiserGPU : public DenoiserGPU {
|
||||
static bool is_device_supported(const DeviceInfo &device);
|
||||
|
||||
protected:
|
||||
enum class ExecMode {
|
||||
SYNC,
|
||||
ASYNC,
|
||||
};
|
||||
|
||||
virtual uint get_device_type_mask() const override;
|
||||
|
||||
/* Create OIDN denoiser descriptor if needed.
|
||||
@ -50,6 +55,20 @@ class OIDNDenoiserGPU : public DenoiserGPU {
|
||||
virtual bool denoise_run(const DenoiseContext &context, const DenoisePass &pass) override;
|
||||
|
||||
OIDNFilter create_filter();
|
||||
bool commit_and_execute_filter(OIDNFilter filter, ExecMode mode = ExecMode::SYNC);
|
||||
|
||||
void set_filter_pass(OIDNFilter filter,
|
||||
const char *name,
|
||||
device_ptr ptr,
|
||||
int format,
|
||||
int width,
|
||||
int height,
|
||||
size_t offset_in_bytes,
|
||||
size_t pixel_stride_in_bytes,
|
||||
size_t row_stride_in_bytes);
|
||||
|
||||
/* Delete all allocated OIDN objects. */
|
||||
void release_all_resources();
|
||||
|
||||
OIDNDevice oidn_device_ = nullptr;
|
||||
OIDNFilter oidn_filter_ = nullptr;
|
||||
@ -61,8 +80,10 @@ class OIDNDenoiserGPU : public DenoiserGPU {
|
||||
|
||||
bool use_pass_albedo_ = false;
|
||||
bool use_pass_normal_ = false;
|
||||
DenoiserQuality quality_ = DENOISER_QUALITY_HIGH;
|
||||
|
||||
int max_mem_ = 3000;
|
||||
/* Filter memory usage limit if we ran out of memory with OIDN's default limit. */
|
||||
int max_mem_ = 768;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -69,6 +69,10 @@ class PassAccessor {
|
||||
* Allows to get pixels of render buffer into a partial slice of the destination. */
|
||||
int offset = 0;
|
||||
|
||||
/* Offset in floats from the beginning of pixels storage.
|
||||
* Is ignored for half4 destination. */
|
||||
int pixel_offset = 0;
|
||||
|
||||
/* Number of floats per pixel. When zero is the same as `num_components`.
|
||||
*
|
||||
* NOTE: Is ignored for half4 destination, as the half4 pixels are always 4-component
|
||||
|
@ -47,7 +47,7 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_float(
|
||||
|
||||
parallel_for(0, buffer_params.window_height, [&](int64_t y) {
|
||||
const float *buffer = window_data + y * buffer_row_stride;
|
||||
float *pixel = destination.pixels +
|
||||
float *pixel = destination.pixels + destination.pixel_offset +
|
||||
(y * buffer_params.width + destination.offset) * pixel_stride;
|
||||
func(kfilm_convert, buffer, pixel, buffer_params.window_width, pass_stride, pixel_stride);
|
||||
});
|
||||
|
@ -48,6 +48,7 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel,
|
||||
&buffer_params.window_width,
|
||||
&offset,
|
||||
&buffer_params.stride,
|
||||
&destination.pixel_offset,
|
||||
&destination.offset,
|
||||
&destination_stride);
|
||||
|
||||
|
@ -809,6 +809,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
|
||||
int width, \
|
||||
int offset, \
|
||||
int stride, \
|
||||
int channel_offset, \
|
||||
int rgba_offset, \
|
||||
int rgba_stride) \
|
||||
{ \
|
||||
@ -824,7 +825,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
|
||||
ccl_global const float *buffer = render_buffer + offset + \
|
||||
buffer_pixel_index * kfilm_convert.pass_stride; \
|
||||
\
|
||||
ccl_global float *pixel = pixels + \
|
||||
ccl_global float *pixel = pixels + channel_offset + \
|
||||
(render_pixel_index + rgba_offset) * kfilm_convert.pixel_stride; \
|
||||
\
|
||||
FILM_GET_PASS_PIXEL_F32(variant, input_channel_count); \
|
||||
|
@ -308,7 +308,7 @@ ccl_device_inline bool area_light_eval(const ccl_global KernelLight *klight,
|
||||
}
|
||||
|
||||
if (in_volume_segment || (!sample_rectangle && klight->area.tan_half_spread > 0)) {
|
||||
ls->pdf *= lamp_light_pdf(Ng, -ls->D, ls->t);
|
||||
ls->pdf *= light_pdf_area_to_solid_angle(Ng, -ls->D, ls->t);
|
||||
}
|
||||
|
||||
return ls->eval_fac > 0;
|
||||
@ -368,7 +368,7 @@ ccl_device_forceinline void area_light_mnee_sample_update(const ccl_global Kerne
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
area_light_eval<false>(klight, P, &ls->P, ls, zero_float2(), false);
|
||||
/* Convert pdf to be in area measure. */
|
||||
ls->pdf /= lamp_light_pdf(ls->Ng, -ls->D, ls->t);
|
||||
ls->pdf /= light_pdf_area_to_solid_angle(ls->Ng, -ls->D, ls->t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ ccl_device_inline float background_portal_pdf(
|
||||
if (is_round) {
|
||||
float t;
|
||||
float3 D = normalize_len(lightpos - P, &t);
|
||||
portal_pdf += fabsf(klight->area.invarea) * lamp_light_pdf(dir, -D, t);
|
||||
portal_pdf += fabsf(klight->area.invarea) * light_pdf_area_to_solid_angle(dir, -D, t);
|
||||
}
|
||||
else {
|
||||
portal_pdf += area_light_rect_sample(
|
||||
@ -256,7 +256,7 @@ ccl_device float3 background_portal_sample(KernelGlobals kg,
|
||||
lightpos += ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, rand);
|
||||
float t;
|
||||
D = normalize_len(lightpos - P, &t);
|
||||
*pdf = fabsf(klight->area.invarea) * lamp_light_pdf(dir, -D, t);
|
||||
*pdf = fabsf(klight->area.invarea) * light_pdf_area_to_solid_angle(dir, -D, t);
|
||||
}
|
||||
else {
|
||||
*pdf = area_light_rect_sample(P, &lightpos, axis_u, len_u, axis_v, len_v, rand, true);
|
||||
|
@ -49,7 +49,7 @@ ccl_device float3 disk_light_sample(float3 n, float2 rand)
|
||||
return ellipse_sample(ru, rv, rand);
|
||||
}
|
||||
|
||||
ccl_device float lamp_light_pdf(const float3 Ng, const float3 I, float t)
|
||||
ccl_device float light_pdf_area_to_solid_angle(const float3 Ng, const float3 I, float t)
|
||||
{
|
||||
float cos_pi = dot(Ng, I);
|
||||
|
||||
|
@ -15,48 +15,61 @@ ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
||||
const int shader_flags,
|
||||
ccl_private LightSample *ls)
|
||||
{
|
||||
const float r_sq = sqr(klight->spot.radius);
|
||||
|
||||
float3 lightN = P - klight->co;
|
||||
const float d_sq = len_squared(lightN);
|
||||
const float d = sqrtf(d_sq);
|
||||
lightN /= d;
|
||||
|
||||
const float r_sq = sqr(klight->spot.radius);
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
|
||||
float cos_theta;
|
||||
if (d_sq > r_sq) {
|
||||
const float one_minus_cos = sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
||||
ls->D = sample_uniform_cone(-lightN, one_minus_cos, rand, &cos_theta, &ls->pdf);
|
||||
}
|
||||
else {
|
||||
const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
|
||||
if (has_transmission) {
|
||||
ls->D = sample_uniform_sphere(rand);
|
||||
ls->pdf = M_1_2PI_F * 0.5f;
|
||||
if (klight->spot.is_sphere) {
|
||||
/* Spherical light geometry. */
|
||||
float cos_theta;
|
||||
if (d_sq > r_sq) {
|
||||
/* Outside sphere. */
|
||||
const float one_minus_cos = sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
||||
ls->D = sample_uniform_cone(-lightN, one_minus_cos, rand, &cos_theta, &ls->pdf);
|
||||
}
|
||||
else {
|
||||
sample_cos_hemisphere(N, rand, &ls->D, &ls->pdf);
|
||||
/* Inside sphere. */
|
||||
const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
|
||||
if (has_transmission) {
|
||||
ls->D = sample_uniform_sphere(rand);
|
||||
ls->pdf = M_1_2PI_F * 0.5f;
|
||||
}
|
||||
else {
|
||||
sample_cos_hemisphere(N, rand, &ls->D, &ls->pdf);
|
||||
}
|
||||
cos_theta = -dot(ls->D, lightN);
|
||||
}
|
||||
cos_theta = -dot(ls->D, lightN);
|
||||
}
|
||||
|
||||
/* Law of cosines. */
|
||||
ls->t = d * cos_theta - copysignf(safe_sqrtf(r_sq - d_sq + d_sq * sqr(cos_theta)), d_sq - r_sq);
|
||||
/* Law of cosines. */
|
||||
ls->t = d * cos_theta -
|
||||
copysignf(safe_sqrtf(r_sq - d_sq + d_sq * sqr(cos_theta)), d_sq - r_sq);
|
||||
|
||||
ls->P = P + ls->D * ls->t;
|
||||
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
if (r_sq == 0) {
|
||||
/* Use intensity instead of radiance for point light. */
|
||||
ls->eval_fac /= sqr(ls->t);
|
||||
/* `ls->Ng` is not well-defined for point light, so use the incoming direction instead. */
|
||||
ls->Ng = -ls->D;
|
||||
}
|
||||
else {
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
/* Remap sampled point onto the sphere to prevent precision issues with small radius. */
|
||||
ls->P = P + ls->D * ls->t;
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
ls->P = ls->Ng * klight->spot.radius + klight->co;
|
||||
}
|
||||
else {
|
||||
/* Point light with ad-hoc radius based on oriented disk. */
|
||||
ls->P = klight->co;
|
||||
if (r_sq > 0.0f) {
|
||||
ls->P += disk_light_sample(lightN, rand) * klight->spot.radius;
|
||||
}
|
||||
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
ls->Ng = -ls->D;
|
||||
|
||||
/* PDF. */
|
||||
const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq * M_PI_F) : 1.0f;
|
||||
ls->pdf = invarea * light_pdf_area_to_solid_angle(lightN, -ls->D, ls->t);
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
const Transform itfm = klight->itfm;
|
||||
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
||||
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
||||
@ -66,7 +79,7 @@ ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
||||
return true;
|
||||
}
|
||||
|
||||
ccl_device_forceinline float point_light_pdf(
|
||||
ccl_device_forceinline float sphere_light_pdf(
|
||||
const float d_sq, const float r_sq, const float3 N, const float3 D, const uint32_t path_flag)
|
||||
{
|
||||
if (d_sq > r_sq) {
|
||||
@ -87,26 +100,26 @@ ccl_device_forceinline void point_light_mnee_sample_update(const ccl_global Kern
|
||||
|
||||
const float radius = klight->spot.radius;
|
||||
|
||||
if (radius > 0) {
|
||||
if (klight->spot.is_sphere) {
|
||||
const float d_sq = len_squared(P - klight->co);
|
||||
const float r_sq = sqr(radius);
|
||||
const float t_sq = sqr(ls->t);
|
||||
|
||||
ls->pdf = point_light_pdf(d_sq, r_sq, N, ls->D, path_flag);
|
||||
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf *= 0.5f * fabsf(d_sq - r_sq - t_sq) / (radius * ls->t * t_sq);
|
||||
const float jacobian_solid_angle_to_area = 0.5f * fabsf(d_sq - r_sq - t_sq) /
|
||||
(radius * ls->t * t_sq);
|
||||
ls->pdf = sphere_light_pdf(d_sq, r_sq, N, ls->D, path_flag) * jacobian_solid_angle_to_area;
|
||||
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
}
|
||||
else {
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf = ls->eval_fac * 4.0f * M_PI_F;
|
||||
|
||||
ls->Ng = -ls->D;
|
||||
|
||||
/* PDF does not change. */
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
const Transform itfm = klight->itfm;
|
||||
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
||||
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
||||
@ -123,8 +136,16 @@ ccl_device_inline bool point_light_intersect(const ccl_global KernelLight *kligh
|
||||
return false;
|
||||
}
|
||||
|
||||
float3 P;
|
||||
return ray_sphere_intersect(ray->P, ray->D, ray->tmin, ray->tmax, klight->co, radius, &P, t);
|
||||
if (klight->spot.is_sphere) {
|
||||
float3 P;
|
||||
return ray_sphere_intersect(ray->P, ray->D, ray->tmin, ray->tmax, klight->co, radius, &P, t);
|
||||
}
|
||||
else {
|
||||
float3 P;
|
||||
const float3 diskN = normalize(ray->P - klight->co);
|
||||
return ray_disk_intersect(
|
||||
ray->P, ray->D, ray->tmin, ray->tmax, klight->co, diskN, radius, &P, t);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline bool point_light_sample_from_intersection(
|
||||
@ -136,25 +157,34 @@ ccl_device_inline bool point_light_sample_from_intersection(
|
||||
const uint32_t path_flag,
|
||||
ccl_private LightSample *ccl_restrict ls)
|
||||
{
|
||||
const float r_sq = sqr(klight->spot.radius);
|
||||
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
|
||||
const float radius = klight->spot.radius;
|
||||
|
||||
ls->Ng = radius > 0 ? normalize(ls->P - klight->co) : -ray_D;
|
||||
if (klight->spot.is_sphere) {
|
||||
const float d_sq = len_squared(ray_P - klight->co);
|
||||
ls->pdf = sphere_light_pdf(d_sq, r_sq, N, ray_D, path_flag);
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
}
|
||||
else {
|
||||
if (ls->t != FLT_MAX) {
|
||||
const float3 lightN = normalize(ray_P - klight->co);
|
||||
const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq * M_PI_F) : 1.0f;
|
||||
ls->pdf = invarea * light_pdf_area_to_solid_angle(lightN, -ray_D, ls->t);
|
||||
}
|
||||
else {
|
||||
ls->pdf = 0.0f;
|
||||
}
|
||||
ls->Ng = -ray_D;
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
const Transform itfm = klight->itfm;
|
||||
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
||||
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
||||
ls->u = uv.y;
|
||||
ls->v = 1.0f - uv.x - uv.y;
|
||||
|
||||
if (ls->t == FLT_MAX) {
|
||||
ls->pdf = 0.0f;
|
||||
}
|
||||
else {
|
||||
ls->pdf = point_light_pdf(len_squared(ray_P - klight->co), sqr(radius), N, ray_D, path_flag);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -175,16 +205,25 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL
|
||||
point_to_centroid = safe_normalize_len(centroid - P, &dist_point_to_centroid);
|
||||
|
||||
const float radius = klight->spot.radius;
|
||||
if (dist_point_to_centroid > radius) {
|
||||
/* Equivalent to a disk light with the same angular span. */
|
||||
cos_theta_u = cos_from_sin(radius / dist_point_to_centroid);
|
||||
distance = dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f);
|
||||
|
||||
if (klight->spot.is_sphere) {
|
||||
if (dist_point_to_centroid > radius) {
|
||||
/* Equivalent to a disk light with the same angular span. */
|
||||
cos_theta_u = cos_from_sin(radius / dist_point_to_centroid);
|
||||
distance = dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f);
|
||||
}
|
||||
else {
|
||||
/* Similar to background light. */
|
||||
cos_theta_u = -1.0f;
|
||||
/* HACK: pack radiance scaling in the distance. */
|
||||
distance = one_float2() * radius / M_SQRT2_F;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Similar to background light. */
|
||||
cos_theta_u = -1.0f;
|
||||
/* HACK: pack radiance scaling in the distance. */
|
||||
distance = one_float2() * radius / M_SQRT2_F;
|
||||
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid));
|
||||
cos_theta_u = dist_point_to_centroid / hypotenus;
|
||||
|
||||
distance = make_float2(hypotenus, dist_point_to_centroid);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -43,82 +43,104 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
|
||||
const int shader_flags,
|
||||
ccl_private LightSample *ls)
|
||||
{
|
||||
const float radius = klight->spot.radius;
|
||||
const float r_sq = sqr(klight->spot.radius);
|
||||
|
||||
const float3 center = klight->co;
|
||||
|
||||
float3 lightN = P - center;
|
||||
float3 lightN = P - klight->co;
|
||||
const float d_sq = len_squared(lightN);
|
||||
const float d = sqrtf(d_sq);
|
||||
lightN /= d;
|
||||
|
||||
float cos_theta;
|
||||
ls->t = FLT_MAX;
|
||||
if (d_sq > r_sq) {
|
||||
const float one_minus_cos_half_spot_spread = 1.0f - klight->spot.cos_half_spot_angle;
|
||||
const float one_minus_cos_half_angle = sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
|
||||
if (in_volume_segment || one_minus_cos_half_angle < one_minus_cos_half_spot_spread) {
|
||||
/* Sample visible part of the sphere. */
|
||||
ls->D = sample_uniform_cone(-lightN, one_minus_cos_half_angle, rand, &cos_theta, &ls->pdf);
|
||||
}
|
||||
else {
|
||||
/* Sample spread cone. */
|
||||
ls->D = sample_uniform_cone(
|
||||
-klight->spot.dir, one_minus_cos_half_spot_spread, rand, &cos_theta, &ls->pdf);
|
||||
if (klight->spot.is_sphere) {
|
||||
/* Spherical light geometry. */
|
||||
float cos_theta;
|
||||
ls->t = FLT_MAX;
|
||||
if (d_sq > r_sq) {
|
||||
/* Outside sphere. */
|
||||
const float one_minus_cos_half_spot_spread = 1.0f - klight->spot.cos_half_spot_angle;
|
||||
const float one_minus_cos_half_angle = sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
||||
|
||||
if (!ray_sphere_intersect(P, ls->D, 0.0f, FLT_MAX, center, radius, &ls->P, &ls->t)) {
|
||||
/* Sampled direction does not intersect with the light. */
|
||||
return false;
|
||||
if (in_volume_segment || one_minus_cos_half_angle < one_minus_cos_half_spot_spread) {
|
||||
/* Sample visible part of the sphere. */
|
||||
ls->D = sample_uniform_cone(-lightN, one_minus_cos_half_angle, rand, &cos_theta, &ls->pdf);
|
||||
}
|
||||
else {
|
||||
/* Sample spread cone. */
|
||||
ls->D = sample_uniform_cone(
|
||||
-klight->spot.dir, one_minus_cos_half_spot_spread, rand, &cos_theta, &ls->pdf);
|
||||
|
||||
if (!ray_sphere_intersect(
|
||||
P, ls->D, 0.0f, FLT_MAX, klight->co, klight->spot.radius, &ls->P, &ls->t))
|
||||
{
|
||||
/* Sampled direction does not intersect with the light. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
|
||||
if (has_transmission) {
|
||||
ls->D = sample_uniform_sphere(rand);
|
||||
ls->pdf = M_1_2PI_F * 0.5f;
|
||||
else {
|
||||
/* Inside sphere. */
|
||||
const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
|
||||
if (has_transmission) {
|
||||
ls->D = sample_uniform_sphere(rand);
|
||||
ls->pdf = M_1_2PI_F * 0.5f;
|
||||
}
|
||||
else {
|
||||
sample_cos_hemisphere(N, rand, &ls->D, &ls->pdf);
|
||||
}
|
||||
cos_theta = -dot(ls->D, lightN);
|
||||
}
|
||||
|
||||
/* Attenuation. */
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
|
||||
if (d_sq > r_sq) {
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
}
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ls->t == FLT_MAX) {
|
||||
/* Law of cosines. */
|
||||
ls->t = d * cos_theta -
|
||||
copysignf(safe_sqrtf(r_sq - d_sq + d_sq * sqr(cos_theta)), d_sq - r_sq);
|
||||
ls->P = P + ls->D * ls->t;
|
||||
}
|
||||
else {
|
||||
sample_cos_hemisphere(N, rand, &ls->D, &ls->pdf);
|
||||
/* Already computed when sampling the spread cone. */
|
||||
}
|
||||
cos_theta = -dot(ls->D, lightN);
|
||||
}
|
||||
|
||||
if (ls->t == FLT_MAX) {
|
||||
/* Law of cosines. */
|
||||
ls->t = d * cos_theta -
|
||||
copysignf(safe_sqrtf(r_sq - d_sq + d_sq * sqr(cos_theta)), d_sq - r_sq);
|
||||
ls->P = P + ls->D * ls->t;
|
||||
}
|
||||
else {
|
||||
/* Already computed when sampling the spread cone. */
|
||||
}
|
||||
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
if (d_sq > r_sq) {
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
}
|
||||
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (r_sq == 0) {
|
||||
/* Use intensity instead of radiance when the radius is zero. */
|
||||
ls->eval_fac /= sqr(ls->t);
|
||||
/* `ls->Ng` is not well-defined when the radius is zero, use the incoming direction instead. */
|
||||
ls->Ng = -ls->D;
|
||||
}
|
||||
else {
|
||||
ls->Ng = normalize(ls->P - center);
|
||||
/* Remap sampled point onto the sphere to prevent precision issues with small radius. */
|
||||
ls->P = ls->Ng * radius + center;
|
||||
}
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
ls->P = ls->Ng * klight->spot.radius + klight->co;
|
||||
|
||||
spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
|
||||
/* Texture coordinates. */
|
||||
spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
|
||||
}
|
||||
else {
|
||||
/* Point light with ad-hoc radius based on oriented disk. */
|
||||
ls->P = klight->co;
|
||||
if (r_sq > 0.0f) {
|
||||
ls->P += disk_light_sample(lightN, rand) * klight->spot.radius;
|
||||
}
|
||||
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
ls->Ng = -ls->D;
|
||||
|
||||
/* Attenuation. */
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* PDF. */
|
||||
const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq * M_PI_F) : 1.0f;
|
||||
ls->pdf = invarea * light_pdf_area_to_solid_angle(lightN, -ls->D, ls->t);
|
||||
|
||||
/* Texture coordinates. */
|
||||
spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -146,35 +168,40 @@ ccl_device_forceinline void spot_light_mnee_sample_update(const ccl_global Kerne
|
||||
{
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
|
||||
const float radius = klight->spot.radius;
|
||||
bool use_attenuation = true;
|
||||
|
||||
if (radius > 0) {
|
||||
if (klight->spot.is_sphere) {
|
||||
const float d_sq = len_squared(P - klight->co);
|
||||
const float r_sq = sqr(radius);
|
||||
const float t_sq = sqr(ls->t);
|
||||
|
||||
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ls->D, path_flag);
|
||||
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf *= 0.5f * fabsf(d_sq - r_sq - t_sq) / (radius * ls->t * t_sq);
|
||||
const float jacobian_solid_angle_to_area = 0.5f * fabsf(d_sq - r_sq - t_sq) /
|
||||
(radius * ls->t * t_sq);
|
||||
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ls->D, path_flag) *
|
||||
jacobian_solid_angle_to_area;
|
||||
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
|
||||
if (d_sq > r_sq) {
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
}
|
||||
use_attenuation = (d_sq > r_sq);
|
||||
}
|
||||
else {
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf = ls->eval_fac * 4.0f * M_PI_F;
|
||||
|
||||
ls->Ng = -ls->D;
|
||||
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
|
||||
/* PDF does not change. */
|
||||
}
|
||||
|
||||
/* Attenuation. */
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ls->D);
|
||||
if (use_attenuation) {
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
|
||||
}
|
||||
|
||||
@ -199,22 +226,37 @@ ccl_device_inline bool spot_light_sample_from_intersection(
|
||||
const uint32_t path_flag,
|
||||
ccl_private LightSample *ccl_restrict ls)
|
||||
{
|
||||
const float d_sq = len_squared(ray_P - klight->co);
|
||||
const float r_sq = sqr(klight->spot.radius);
|
||||
const float d_sq = len_squared(ray_P - klight->co);
|
||||
|
||||
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ray_D, path_flag);
|
||||
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ray_D);
|
||||
ls->eval_fac = klight->spot.eval_fac;
|
||||
if (d_sq > r_sq) {
|
||||
|
||||
if (klight->spot.is_sphere) {
|
||||
ls->pdf = spot_light_pdf(klight->spot.cos_half_spot_angle, d_sq, r_sq, N, ray_D, path_flag);
|
||||
ls->Ng = normalize(ls->P - klight->co);
|
||||
}
|
||||
else {
|
||||
if (ls->t != FLT_MAX) {
|
||||
const float3 lightN = normalize(ray_P - klight->co);
|
||||
const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq * M_PI_F) : 1.0f;
|
||||
ls->pdf = invarea * light_pdf_area_to_solid_angle(lightN, -ray_D, ls->t);
|
||||
}
|
||||
else {
|
||||
ls->pdf = 0.0f;
|
||||
}
|
||||
ls->Ng = -ray_D;
|
||||
}
|
||||
|
||||
/* Attenuation. */
|
||||
const float3 local_ray = spot_light_to_local(&klight->spot, -ray_D);
|
||||
if (!klight->spot.is_sphere || d_sq > r_sq) {
|
||||
ls->eval_fac *= spot_light_attenuation(&klight->spot, local_ray);
|
||||
}
|
||||
if (ls->eval_fac == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ls->Ng = r_sq > 0 ? normalize(ls->P - klight->co) : -ray_D;
|
||||
|
||||
/* Texture coordinates. */
|
||||
spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
|
||||
|
||||
return true;
|
||||
@ -232,16 +274,30 @@ ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLi
|
||||
const float3 point_to_centroid_ = safe_normalize_len(centroid - P, &dist_point_to_centroid);
|
||||
|
||||
const float radius = klight->spot.radius;
|
||||
cos_theta_u = (dist_point_to_centroid > radius) ? cos_from_sin(radius / dist_point_to_centroid) :
|
||||
-1.0f;
|
||||
|
||||
if (in_volume_segment) {
|
||||
return true;
|
||||
if (klight->spot.is_sphere) {
|
||||
cos_theta_u = (dist_point_to_centroid > radius) ?
|
||||
cos_from_sin(radius / dist_point_to_centroid) :
|
||||
-1.0f;
|
||||
|
||||
if (in_volume_segment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
distance = (dist_point_to_centroid > radius) ?
|
||||
dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f) :
|
||||
one_float2() * radius / M_SQRT2_F;
|
||||
}
|
||||
else {
|
||||
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid));
|
||||
cos_theta_u = dist_point_to_centroid / hypotenus;
|
||||
|
||||
distance = (dist_point_to_centroid > radius) ?
|
||||
dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f) :
|
||||
one_float2() * radius / M_SQRT2_F;
|
||||
if (in_volume_segment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
distance = make_float2(hypotenus, dist_point_to_centroid);
|
||||
}
|
||||
point_to_centroid = point_to_centroid_;
|
||||
|
||||
return true;
|
||||
|
@ -1369,7 +1369,7 @@ typedef struct KernelSpotLight {
|
||||
float half_cot_half_spot_angle;
|
||||
float inv_len_z;
|
||||
float spot_smooth;
|
||||
float pad;
|
||||
int is_sphere;
|
||||
} KernelSpotLight;
|
||||
|
||||
/* PointLight is SpotLight with only radius and invarea being used. */
|
||||
|
@ -136,6 +136,10 @@ NODE_DEFINE(Integrator)
|
||||
denoiser_prefilter_enum.insert("fast", DENOISER_PREFILTER_FAST);
|
||||
denoiser_prefilter_enum.insert("accurate", DENOISER_PREFILTER_ACCURATE);
|
||||
|
||||
static NodeEnum denoiser_quality_enum;
|
||||
denoiser_quality_enum.insert("high", DENOISER_QUALITY_HIGH);
|
||||
denoiser_quality_enum.insert("balanced", DENOISER_QUALITY_BALANCED);
|
||||
|
||||
/* Default to accurate denoising with OpenImageDenoise. For interactive viewport
|
||||
* it's best use OptiX and disable the normal pass since it does not always have
|
||||
* the desired effect for that denoiser. */
|
||||
@ -148,6 +152,8 @@ NODE_DEFINE(Integrator)
|
||||
"Denoiser Prefilter",
|
||||
denoiser_prefilter_enum,
|
||||
DENOISER_PREFILTER_ACCURATE);
|
||||
SOCKET_BOOLEAN(denoise_use_gpu, "Denoise on GPU", true);
|
||||
SOCKET_ENUM(denoiser_quality, "Denoiser Quality", denoiser_quality_enum, DENOISER_QUALITY_HIGH);
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -393,12 +399,15 @@ DenoiseParams Integrator::get_denoise_params() const
|
||||
|
||||
denoise_params.type = denoiser_type;
|
||||
|
||||
denoise_params.use_gpu = denoise_use_gpu;
|
||||
|
||||
denoise_params.start_sample = denoise_start_sample;
|
||||
|
||||
denoise_params.use_pass_albedo = use_denoise_pass_albedo;
|
||||
denoise_params.use_pass_normal = use_denoise_pass_normal;
|
||||
|
||||
denoise_params.prefilter = denoiser_prefilter;
|
||||
denoise_params.quality = denoiser_quality;
|
||||
|
||||
return denoise_params;
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ class Integrator : public Node {
|
||||
NODE_SOCKET_API(bool, use_denoise_pass_albedo);
|
||||
NODE_SOCKET_API(bool, use_denoise_pass_normal);
|
||||
NODE_SOCKET_API(DenoiserPrefilter, denoiser_prefilter);
|
||||
NODE_SOCKET_API(bool, denoise_use_gpu);
|
||||
NODE_SOCKET_API(DenoiserQuality, denoiser_quality);
|
||||
|
||||
enum : uint32_t {
|
||||
AO_PASS_MODIFIED = (1 << 0),
|
||||
|
@ -110,6 +110,8 @@ NODE_DEFINE(Light)
|
||||
SOCKET_INT(map_resolution, "Map Resolution", 0);
|
||||
SOCKET_FLOAT(average_radiance, "Average Radiance", 0.0f);
|
||||
|
||||
SOCKET_BOOLEAN(is_sphere, "Is Sphere", true);
|
||||
|
||||
SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
|
||||
SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
|
||||
|
||||
@ -1253,6 +1255,7 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
|
||||
klights[light_index].co = light->get_co();
|
||||
klights[light_index].spot.radius = radius;
|
||||
klights[light_index].spot.eval_fac = eval_fac;
|
||||
klights[light_index].spot.is_sphere = light->get_is_sphere() && radius != 0.0f;
|
||||
}
|
||||
else if (light->light_type == LIGHT_DISTANT) {
|
||||
shader_id &= ~SHADER_AREA_LIGHT;
|
||||
|
@ -48,6 +48,8 @@ class Light : public Node {
|
||||
NODE_SOCKET_API(int, map_resolution)
|
||||
NODE_SOCKET_API(float, average_radiance)
|
||||
|
||||
NODE_SOCKET_API(bool, is_sphere)
|
||||
|
||||
NODE_SOCKET_API(float, spot_angle)
|
||||
NODE_SOCKET_API(float, spot_smooth)
|
||||
|
||||
|
@ -135,8 +135,7 @@ static void initRawInput()
|
||||
|
||||
typedef BOOL(API *GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
|
||||
|
||||
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
: m_hasPerformanceCounter(false), m_freq(0), m_start(0), m_lfstart(0)
|
||||
GHOST_SystemWin32::GHOST_SystemWin32() : m_hasPerformanceCounter(false), m_freq(0)
|
||||
{
|
||||
m_displayManager = new GHOST_DisplayManagerWin32();
|
||||
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
|
||||
@ -178,22 +177,17 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
|
||||
uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
|
||||
{
|
||||
/* Calculate the time passed since system initialization. */
|
||||
__int64 delta = (perf_ticks - m_start) * 1000;
|
||||
__int64 delta = perf_ticks * 1000;
|
||||
|
||||
uint64_t t = uint64_t(delta / m_freq);
|
||||
return t;
|
||||
}
|
||||
|
||||
uint64_t GHOST_SystemWin32::tickCountToMillis(__int64 ticks) const
|
||||
{
|
||||
return ticks - m_lfstart;
|
||||
}
|
||||
|
||||
uint64_t GHOST_SystemWin32::getMilliSeconds() const
|
||||
{
|
||||
/* Hardware does not support high resolution timers. We will use GetTickCount instead then. */
|
||||
if (!m_hasPerformanceCounter) {
|
||||
return tickCountToMillis(::GetTickCount());
|
||||
return ::GetTickCount64();
|
||||
}
|
||||
|
||||
/* Retrieve current count */
|
||||
@ -204,10 +198,9 @@ uint64_t GHOST_SystemWin32::getMilliSeconds() const
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds since the start of the Blender process to the time of the
|
||||
* last message, using the high frequency timer if available. This should be used instead of
|
||||
* getMilliSeconds when you need the time a message was delivered versus collected, so for all
|
||||
* event creation that are in response to receiving a Windows message.
|
||||
* Returns the message time, compatible with the time value from #getMilliSeconds.
|
||||
* This should be used instead of #getMilliSeconds when you need the time a message was delivered
|
||||
* versus collected, so for all event creation that are in response to receiving a Windows message.
|
||||
*/
|
||||
static uint64_t getMessageTime(GHOST_SystemWin32 *system)
|
||||
{
|
||||
@ -219,7 +212,7 @@ static uint64_t getMessageTime(GHOST_SystemWin32 *system)
|
||||
t_delta -= int64_t(UINT32_MAX) + 1;
|
||||
}
|
||||
|
||||
/* Return message time as 64-bit milliseconds since Blender start. */
|
||||
/* Return message time as 64-bit milliseconds with the delta applied. */
|
||||
return system->getMilliSeconds() + t_delta;
|
||||
}
|
||||
|
||||
@ -575,16 +568,8 @@ GHOST_TSuccess GHOST_SystemWin32::init()
|
||||
SetProcessDPIAware();
|
||||
initRawInput();
|
||||
|
||||
m_lfstart = ::GetTickCount();
|
||||
/* Determine whether this system has a high frequency performance counter. */
|
||||
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER *)&m_freq) == TRUE;
|
||||
if (m_hasPerformanceCounter) {
|
||||
GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer available\n");
|
||||
::QueryPerformanceCounter((LARGE_INTEGER *)&m_start);
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer not available\n");
|
||||
}
|
||||
|
||||
if (success) {
|
||||
WNDCLASSW wc = {0};
|
||||
|
@ -60,13 +60,6 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
*/
|
||||
uint64_t performanceCounterToMillis(__int64 perf_ticks) const;
|
||||
|
||||
/**
|
||||
* This method converts system ticks into milliseconds since the start of the
|
||||
* Blender process.
|
||||
* \return The number of milliseconds since the start of the Blender process.
|
||||
*/
|
||||
uint64_t tickCountToMillis(__int64 ticks) const;
|
||||
|
||||
/**
|
||||
* Returns the system time.
|
||||
* Returns the number of milliseconds since the start of the Blender process.
|
||||
@ -476,10 +469,6 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
bool m_hasPerformanceCounter;
|
||||
/** High frequency timer variable. */
|
||||
__int64 m_freq;
|
||||
/** High frequency timer variable. */
|
||||
__int64 m_start;
|
||||
/** Low frequency timer variable. */
|
||||
__int64 m_lfstart;
|
||||
/** AltGr on current keyboard layout. */
|
||||
bool m_hasAltGr;
|
||||
/** Language identifier. */
|
||||
|
@ -274,7 +274,7 @@ struct GWL_WindowFrame {
|
||||
/**
|
||||
* The frame size (in GHOST window coordinates).
|
||||
*
|
||||
* These must be converted to WAYLADN relative coordinates when the window is scaled
|
||||
* These must be converted to WAYLAND relative coordinates when the window is scaled
|
||||
* by Hi-DPI/fractional scaling.
|
||||
*/
|
||||
int32_t size[2] = {0, 0};
|
||||
@ -641,11 +641,10 @@ static bool gwl_window_viewport_size_update(GWL_Window *win)
|
||||
if (win->wp.viewport == nullptr) {
|
||||
return false;
|
||||
}
|
||||
wp_viewport_set_source(win->wp.viewport,
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(win->frame.size[0]),
|
||||
wl_fixed_from_int(win->frame.size[1]));
|
||||
|
||||
/* Setting `wp_viewport_set_source` isn't necessary as an unset value is ensured on creation
|
||||
* and documented to use the entire buffer, further this can crash with NVIDIA, see: #117531. */
|
||||
|
||||
wp_viewport_set_destination(
|
||||
win->wp.viewport,
|
||||
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]),
|
||||
|
@ -8,9 +8,13 @@ echo by dragging them into the text area of your bug report, please include both
|
||||
echo blender_debug_output.txt and blender_system_info.txt in your report.
|
||||
echo.
|
||||
pause
|
||||
mkdir "%temp%\blender\debug_logs" > NUL 2>&1
|
||||
echo.
|
||||
echo Starting blender and waiting for it to exit....
|
||||
setlocal
|
||||
|
||||
set PYTHONPATH=
|
||||
"%~dp0\blender" --debug --debug-gpu --debug-cycles --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%temp%\blender\debug_logs"
|
||||
set DEBUGLOGS="%temp%\blender\debug_logs"
|
||||
mkdir "%DEBUGLOGS%" > NUL 2>&1
|
||||
|
||||
"%~dp0\blender" --debug --debug-gpu --debug-cycles --python-expr "import bpy; bpy.context.preferences.filepaths.temporary_directory=r'%DEBUGLOGS%'; bpy.ops.wm.sysinfo(filepath=r'%DEBUGLOGS%\blender_system_info.txt')" > "%DEBUGLOGS%\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%DEBUGLOGS%"
|
||||
|
@ -8,9 +8,13 @@ echo by dragging them into the text area of your bug report, please include both
|
||||
echo blender_debug_output.txt and blender_system_info.txt in your report.
|
||||
echo.
|
||||
pause
|
||||
mkdir "%temp%\blender\debug_logs" > NUL 2>&1
|
||||
echo.
|
||||
echo Starting blender and waiting for it to exit....
|
||||
setlocal
|
||||
|
||||
set PYTHONPATH=
|
||||
"%~dp0\blender" --debug --debug-gpu --debug-gpu-force-workarounds --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%temp%\blender\debug_logs"
|
||||
set DEBUGLOGS="%temp%\blender\debug_logs"
|
||||
mkdir "%DEBUGLOGS%" > NUL 2>&1
|
||||
|
||||
"%~dp0\blender" --debug --debug-gpu --debug-gpu-force-workarounds --python-expr "import bpy; bpy.context.preferences.filepaths.temporary_directory=r'%DEBUGLOGS%'; bpy.ops.wm.sysinfo(filepath=r'%DEBUGLOGS%\blender_system_info.txt')" > "%DEBUGLOGS%\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%DEBUGLOGS%"
|
||||
|
@ -8,9 +8,13 @@ echo by dragging them into the text area of your bug report, please include both
|
||||
echo blender_debug_output.txt and blender_system_info.txt in your report.
|
||||
echo.
|
||||
pause
|
||||
mkdir "%temp%\blender\debug_logs" > NUL 2>&1
|
||||
echo.
|
||||
echo Starting blender and waiting for it to exit....
|
||||
setlocal
|
||||
|
||||
set PYTHONPATH=
|
||||
"%~dp0\blender" --debug --debug-cycles --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%temp%\blender\debug_logs"
|
||||
set DEBUGLOGS="%temp%\blender\debug_logs"
|
||||
mkdir "%DEBUGLOGS%" > NUL 2>&1
|
||||
|
||||
"%~dp0\blender" --debug --debug-cycles --python-expr "import bpy; bpy.context.preferences.filepaths.temporary_directory=r'%DEBUGLOGS%'; bpy.ops.wm.sysinfo(filepath=r'%DEBUGLOGS%\blender_system_info.txt')" > "%DEBUGLOGS%\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%DEBUGLOGS%"
|
||||
|
@ -8,9 +8,13 @@ echo by dragging them into the text area of your bug report, please include both
|
||||
echo blender_debug_output.txt and blender_system_info.txt in your report.
|
||||
echo.
|
||||
pause
|
||||
mkdir "%temp%\blender\debug_logs" > NUL 2>&1
|
||||
echo.
|
||||
echo Starting blender and waiting for it to exit....
|
||||
setlocal
|
||||
|
||||
set PYTHONPATH=
|
||||
"%~dp0\blender" --factory-startup --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1
|
||||
explorer "%temp%\blender\debug_logs"
|
||||
set DEBUGLOGS="%temp%\blender\debug_logs"
|
||||
mkdir "%DEBUGLOGS%" > NUL 2>&1
|
||||
|
||||
"%~dp0\blender" --factory-startup --python-expr "import bpy; bpy.context.preferences.filepaths.temporary_directory=r'%DEBUGLOGS%'; bpy.ops.wm.sysinfo(filepath=r'%DEBUGLOGS%\blender_system_info.txt')" > "%DEBUGLOGS%\blender_debug_output.txt" 2>&1 < %0
|
||||
explorer "%DEBUGLOGS%"
|
||||
|
@ -11,6 +11,7 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import glob
|
||||
from pathlib import PurePath
|
||||
|
||||
# XXX Relative import does not work here when used from Blender...
|
||||
from bl_i18n_utils import settings as settings_i18n, utils
|
||||
@ -575,6 +576,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
("pgettext_tip", ("tip_",)),
|
||||
("pgettext_rpt", ("rpt_",)),
|
||||
("pgettext_data", ("data_",)),
|
||||
("poll_message_set", ()),
|
||||
)
|
||||
pgettext_variants_args = {"msgid": (0, {"msgctxt": 1})}
|
||||
|
||||
@ -664,6 +666,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
root_node = ast.parse(filedata.read(), fp, 'exec')
|
||||
|
||||
fp_rel = make_rel(fp)
|
||||
fp_rel = PurePath(fp_rel).as_posix()
|
||||
|
||||
for node in ast.walk(root_node):
|
||||
if type(node) == ast.Call:
|
||||
|
@ -15,6 +15,7 @@ from bl_i18n_utils import (
|
||||
settings,
|
||||
utils_rtl,
|
||||
)
|
||||
from typing import Dict
|
||||
|
||||
|
||||
##### Misc Utils #####
|
||||
@ -737,6 +738,7 @@ class I18nMessages:
|
||||
self._reverse_cache = None
|
||||
if rebuild_now:
|
||||
src_to_msg, ctxt_to_msg, msgid_to_msg, msgstr_to_msg = {}, {}, {}, {}
|
||||
ctxt_to_msg.setdefault(self.settings.DEFAULT_CONTEXT, set())
|
||||
for key, msg in self.msgs.items():
|
||||
if msg.is_commented:
|
||||
continue
|
||||
@ -799,7 +801,7 @@ class I18nMessages:
|
||||
rlbl = getattr(msgs, msgmap["rna_label"]["msgstr"])
|
||||
# print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
|
||||
if rlbl:
|
||||
k = ctxt_to_msg[rna_ctxt].copy()
|
||||
k = ctxt_to_msg.get(rna_ctxt, set()).copy()
|
||||
if k and rlbl in msgid_to_msg:
|
||||
k &= msgid_to_msg[rlbl]
|
||||
elif k and rlbl in msgstr_to_msg:
|
||||
@ -1253,7 +1255,7 @@ class I18n:
|
||||
|
||||
def __init__(self, kind=None, src=None, langs=set(), settings=settings):
|
||||
self.settings = settings
|
||||
self.trans = {}
|
||||
self.trans: Dict[str, I18nMessages] = {}
|
||||
self.src = {} # Should have the same keys as self.trans (plus PARSER_PY_ID for py file)!
|
||||
self.dst = self._dst # A callable that transforms src_path into dst_path!
|
||||
if kind and src:
|
||||
@ -1485,6 +1487,7 @@ class I18n:
|
||||
if langs:
|
||||
translations &= langs
|
||||
translations = [('"' + lng + '"', " " * (len(lng) + 6), self.trans[lng]) for lng in sorted(translations)]
|
||||
print("Translated keys saved to .py file:")
|
||||
print(*(k for k in keys.keys()))
|
||||
for key in keys.keys():
|
||||
if ref.msgs[key].is_commented:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2019-2023 Blender Authors
|
||||
# SPDX-FileCopyrightText: 2019-2024 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@ -73,6 +73,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.simulation_nodes_cache_calculate_to_frame*", "physics/simulation_nodes.html#bpy-ops-object-simulation-nodes-cache-calculate-to-frame"),
|
||||
("bpy.types.brushcurvessculptsettings.density_add_attempts*", "sculpt_paint/curves_sculpting/tools/density_curves.html#bpy-types-brushcurvessculptsettings-density-add-attempts"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-strength"),
|
||||
("bpy.types.cyclesmaterialsettings.use_bump_map_correction*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-use-bump-map-correction"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_front*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-front"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_right*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-right"),
|
||||
("bpy.types.lineartgpencilmodifier.shadow_region_filtering*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-shadow-region-filtering"),
|
||||
@ -94,6 +95,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_left*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-left"),
|
||||
("bpy.types.lineartgpencilmodifier.use_intersection_match*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-match"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_view_modifier*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-modifier"),
|
||||
("bpy.types.sequencertimelineoverlay.show_strip_tag_color*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-tag-color"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_grease_pencil*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-grease-pencil"),
|
||||
("bpy.types.brushcurvessculptsettings.interpolate_length*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-interpolate-length"),
|
||||
("bpy.types.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"),
|
||||
@ -243,6 +245,7 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/view_layer/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"),
|
||||
("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-overlap-strokes"),
|
||||
("bpy.types.movietrackingtrack.use_grayscale_preview*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-grayscale-preview"),
|
||||
("bpy.types.nodetreeinterfacesocket.hide_in_modifier*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-hide-in-modifier"),
|
||||
("bpy.types.sequencertimelineoverlay.show_strip_name*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-name"),
|
||||
("bpy.types.sequencertimelineoverlay.show_thumbnails*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-thumbnails"),
|
||||
("bpy.types.spacespreadsheet.geometry_component_type*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-geometry-component-type"),
|
||||
@ -259,6 +262,7 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.compression_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-compression-stiffness-max"),
|
||||
("bpy.types.colormanagedsequencercolorspacesettings*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings"),
|
||||
("bpy.types.colormanagedviewsettings.view_transform*", "render/color_management.html#bpy-types-colormanagedviewsettings-view-transform"),
|
||||
("bpy.types.compositornodetree.use_groupnode_buffer*", "compositing/sidebar.html#bpy-types-compositornodetree-use-groupnode-buffer"),
|
||||
("bpy.types.cyclesmaterialsettings.volume_step_rate*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-step-rate"),
|
||||
("bpy.types.cyclesobjectsettings.is_caustics_caster*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-caster"),
|
||||
("bpy.types.cyclesrendersettings.adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-threshold"),
|
||||
@ -287,6 +291,7 @@ url_manual_mapping = (
|
||||
("bpy.types.movietrackingplanetrack.use_auto_keying*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-use-auto-keying"),
|
||||
("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"),
|
||||
("bpy.types.nodesmodifier.simulation_bake_directory*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier-simulation-bake-directory"),
|
||||
("bpy.types.nodetreeinterfacesocket.force_non_field*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-force-non-field"),
|
||||
("bpy.types.rendersettings.simplify_child_particles*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-child-particles"),
|
||||
("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"),
|
||||
("bpy.types.sculpt.automasking_start_normal_falloff*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-automasking-start-normal-falloff"),
|
||||
@ -337,6 +342,7 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/view_layer/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"),
|
||||
("bpy.types.materiallineart.use_material_mask_bits*", "render/materials/line_art.html#bpy-types-materiallineart-use-material-mask-bits"),
|
||||
("bpy.types.movietrackingdopesheet.use_invert_sort*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-use-invert-sort"),
|
||||
("bpy.types.nodetreeinterfacesocket*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-default-value"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"),
|
||||
("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"),
|
||||
("bpy.types.sculpt.use_automasking_cavity_inverted*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-cavity-inverted"),
|
||||
@ -428,6 +434,7 @@ url_manual_mapping = (
|
||||
("bpy.types.clothcollisionsettings.use_collision*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-use-collision"),
|
||||
("bpy.types.clothsettings.uniform_pressure_force*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-uniform-pressure-force"),
|
||||
("bpy.types.collection.lineart_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-mask"),
|
||||
("bpy.types.compositornodetree.use_viewer_border*", "compositing/sidebar.html#bpy-types-compositornodetree-use-viewer-border"),
|
||||
("bpy.types.cyclesobjectsettings.use_camera_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-camera-cull"),
|
||||
("bpy.types.cyclesobjectsettings.use_motion_blur*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-motion-blur"),
|
||||
("bpy.types.cyclesrendersettings.diffuse_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-diffuse-bounces"),
|
||||
@ -459,7 +466,6 @@ url_manual_mapping = (
|
||||
("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"),
|
||||
("bpy.types.movietrackingtrack.use_alpha_preview*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-alpha-preview"),
|
||||
("bpy.types.movietrackingtrack.use_green_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-green-channel"),
|
||||
("bpy.types.nodesocketinterface.hide_in_modifier*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-hide-in-modifier"),
|
||||
("bpy.types.rendersettings.resolution_percentage*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-percentage"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"),
|
||||
("bpy.types.softbodysettings.use_estimate_matrix*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-use-estimate-matrix"),
|
||||
@ -490,7 +496,6 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.compression_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-compression-stiffness"),
|
||||
("bpy.types.clothsettings.tension_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-tension-stiffness-max"),
|
||||
("bpy.types.clothsettings.vertex_group_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-pressure"),
|
||||
("bpy.types.cyclesmaterialsettings.displacement*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-displacement"),
|
||||
("bpy.types.cyclesrendersettings.fast_gi_method*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-fast-gi-method"),
|
||||
("bpy.types.cyclesrendersettings.glossy_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-glossy-bounces"),
|
||||
("bpy.types.cyclesrendersettings.use_light_tree*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-light-tree"),
|
||||
@ -512,7 +517,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.particle_radius*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-radius"),
|
||||
("bpy.types.fluiddomainsettings.slice_per_voxel*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-per-voxel"),
|
||||
("bpy.types.fluiddomainsettings.surface_tension*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-surface-tension"),
|
||||
("bpy.types.fluiddomainsettings.viscosity_value*", "physics/fluid/type/domain/liquid/viscosity.html#bpy-types-fluiddomainsettings-viscosity-value"),
|
||||
("bpy.types.fluiddomainsettings.viscosity_value*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-value"),
|
||||
("bpy.types.fluideffectorsettings.effector_type*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-effector-type"),
|
||||
("bpy.types.fluidflowsettings.use_particle_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-particle-size"),
|
||||
("bpy.types.freestylelineset.face_mark_negation*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-face-mark-negation"),
|
||||
@ -526,10 +531,12 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.alignment_mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-alignment-mode"),
|
||||
("bpy.types.movietrackingtrack.use_blue_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-blue-channel"),
|
||||
("bpy.types.movietrackingtrack.use_custom_color*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-custom-color"),
|
||||
("bpy.types.nodetreeinterfacesocket.description*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-description"),
|
||||
("bpy.types.objectlineart.intersection_priority*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-intersection-priority"),
|
||||
("bpy.types.particlesettings.use_modifier_stack*", "physics/particles/emitter/emission.html#bpy-types-particlesettings-use-modifier-stack"),
|
||||
("bpy.types.rendersettings.sequencer_gl_preview*", "editors/video_sequencer/preview/sidebar.html#bpy-types-rendersettings-sequencer-gl-preview"),
|
||||
("bpy.types.rendersettings.simplify_subdivision*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-subdivision"),
|
||||
("bpy.types.rendersettings.use_simplify_normals*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-use-simplify-normals"),
|
||||
("bpy.types.sculpt.use_automasking_start_normal*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-start-normal"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"),
|
||||
("bpy.types.softbodysettings.use_edge_collision*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-edge-collision"),
|
||||
@ -606,7 +613,9 @@ url_manual_mapping = (
|
||||
("bpy.types.moviesequence.animation_offset_end*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-moviesequence-animation-offset-end"),
|
||||
("bpy.types.movietrackingdopesheet.sort_method*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-sort-method"),
|
||||
("bpy.types.movietrackingtrack.use_red_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-red-channel"),
|
||||
("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"),
|
||||
("bpy.types.nodetreeinterfacesocket*.max_value*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-max-value"),
|
||||
("bpy.types.nodetreeinterfacesocket*.min_value*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-min-value"),
|
||||
("bpy.types.nodetreeinterfacesocket.hide_value*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-hide-value"),
|
||||
("bpy.types.object.add_rest_position_attribute*", "animation/shape_keys/shape_keys_panel.html#bpy-types-object-add-rest-position-attribute"),
|
||||
("bpy.types.rendersettings.line_thickness_mode*", "render/freestyle/render.html#bpy-types-rendersettings-line-thickness-mode"),
|
||||
("bpy.types.rendersettings.motion_blur_shutter*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-motion-blur-shutter"),
|
||||
@ -646,6 +655,7 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"),
|
||||
("bpy.types.clothsettings.vertex_group_shrink*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-vertex-group-shrink"),
|
||||
("bpy.types.colormanagedviewsettings.exposure*", "render/color_management.html#bpy-types-colormanagedviewsettings-exposure"),
|
||||
("bpy.types.compositornodetree.render_quality*", "compositing/sidebar.html#bpy-types-compositornodetree-render-quality"),
|
||||
("bpy.types.cyclesobjectsettings.motion_steps*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-motion-steps"),
|
||||
("bpy.types.cyclesrendersettings.filter_width*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-filter-width"),
|
||||
("bpy.types.fluiddomainsettings.cfl_condition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-cfl-condition"),
|
||||
@ -654,7 +664,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.timesteps_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-min"),
|
||||
("bpy.types.fluiddomainsettings.use_diffusion*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-use-diffusion"),
|
||||
("bpy.types.fluiddomainsettings.use_fractions*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-fractions"),
|
||||
("bpy.types.fluiddomainsettings.use_viscosity*", "physics/fluid/type/domain/liquid/viscosity.html#bpy-types-fluiddomainsettings-use-viscosity"),
|
||||
("bpy.types.fluiddomainsettings.use_viscosity*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-use-viscosity"),
|
||||
("bpy.types.fluidflowsettings.particle_system*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-particle-system"),
|
||||
("bpy.types.fluidflowsettings.velocity_factor*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-factor"),
|
||||
("bpy.types.fluidflowsettings.velocity_normal*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-normal"),
|
||||
@ -677,6 +687,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.preview_pixel_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-preview-pixel-size"),
|
||||
("bpy.types.rendersettings.use_crop_to_border*", "render/output/properties/format.html#bpy-types-rendersettings-use-crop-to-border"),
|
||||
("bpy.types.rendersettings.use_file_extension*", "render/output/properties/output.html#bpy-types-rendersettings-use-file-extension"),
|
||||
("bpy.types.scene.use_custom_simulation_range*", "scene_layout/scene/properties.html#bpy-types-scene-use-custom-simulation-range"),
|
||||
("bpy.types.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"),
|
||||
("bpy.types.sequencemodifier.input_mask_strip*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier-input-mask-strip"),
|
||||
("bpy.types.sequencertoolsettings.pivot_point*", "editors/video_sequencer/preview/controls/pivot_point.html#bpy-types-sequencertoolsettings-pivot-point"),
|
||||
@ -725,6 +736,7 @@ url_manual_mapping = (
|
||||
("bpy.types.cyclesrendersettings.max_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-bounces"),
|
||||
("bpy.types.cyclesrendersettings.use_fast_gi*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-use-fast-gi"),
|
||||
("bpy.types.cyclesrendersettings.use_guiding*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-guiding"),
|
||||
("bpy.types.drivervariable.type.context_prop*", "animation/drivers/drivers_panel.html#bpy-types-drivervariable-type-context-prop"),
|
||||
("bpy.types.editbone.bbone_custom_handle_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-end"),
|
||||
("bpy.types.editbone.bbone_handle_type_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-start"),
|
||||
("bpy.types.fieldsettings.guide_clump_amount*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-guide-clump-amount"),
|
||||
@ -792,7 +804,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.collection_exclude_clear*", "editors/outliner/editing.html#bpy-ops-outliner-collection-exclude-clear"),
|
||||
("bpy.ops.outliner.collection_holdout_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-clear"),
|
||||
("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-face-set-change-visibility"),
|
||||
("bpy.ops.sculpt.face_set_invert_visibility*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-invert-visibility"),
|
||||
("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"),
|
||||
("bpy.ops.sequencer.retiming_transition_add*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-retiming-transition-add"),
|
||||
("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"),
|
||||
@ -806,6 +817,8 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.tension_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-tension-stiffness"),
|
||||
("bpy.types.clothsettings.vertex_group_mass*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-vertex-group-mass"),
|
||||
("bpy.types.compositornodeconvertcolorspace*", "compositing/types/color/convert_colorspace.html#bpy-types-compositornodeconvertcolorspace"),
|
||||
("bpy.types.compositornodetree.edit_quality*", "compositing/sidebar.html#bpy-types-compositornodetree-edit-quality"),
|
||||
("bpy.types.compositornodetree.use_two_pass*", "compositing/sidebar.html#bpy-types-compositornodetree-use-two-pass"),
|
||||
("bpy.types.cyclescurverendersettings.shape*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-shape"),
|
||||
("bpy.types.cycleslightsettings.cast_shadow*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-cast-shadow"),
|
||||
("bpy.types.cycleslightsettings.max_bounces*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-max-bounces"),
|
||||
@ -850,7 +863,6 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.fill_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-style"),
|
||||
("bpy.types.materialgpencilstyle.mix_factor*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-factor"),
|
||||
("bpy.types.materialgpencilstyle.pass_index*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-pass-index"),
|
||||
("bpy.types.nodesocketinterface.description*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-description"),
|
||||
("bpy.types.rendersettings.dither_intensity*", "render/output/properties/post_processing.html#bpy-types-rendersettings-dither-intensity"),
|
||||
("bpy.types.rendersettings.film_transparent*", "render/cycles/render_settings/film.html#bpy-types-rendersettings-film-transparent"),
|
||||
("bpy.types.rendersettings.simplify_volumes*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-volumes"),
|
||||
@ -864,6 +876,7 @@ url_manual_mapping = (
|
||||
("bpy.types.spacefilebrowser.recent_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-recent-folders"),
|
||||
("bpy.types.spacefilebrowser.system_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-folders"),
|
||||
("bpy.types.spacenodeeditor.show_annotation*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeeditor-show-annotation"),
|
||||
("bpy.types.spacenodeeditor.use_auto_render*", "compositing/sidebar.html#bpy-types-spacenodeeditor-use-auto-render"),
|
||||
("bpy.types.spaceoutliner.use_filter_object*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object"),
|
||||
("bpy.types.spacesequenceeditor.use_proxies*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-use-proxies"),
|
||||
("bpy.types.spaceuveditor.edge_display_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-edge-display-type"),
|
||||
@ -952,9 +965,6 @@ url_manual_mapping = (
|
||||
("bpy.types.movietrackingobject.keyframe_a*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingobject-keyframe-a"),
|
||||
("bpy.types.movietrackingobject.keyframe_b*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingobject-keyframe-b"),
|
||||
("bpy.types.movietrackingtrack.weight_stab*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-weight-stab"),
|
||||
("bpy.types.nodesocketinterface*.max_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-max-value"),
|
||||
("bpy.types.nodesocketinterface*.min_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-min-value"),
|
||||
("bpy.types.nodesocketinterface.hide_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-hide-value"),
|
||||
("bpy.types.object.use_shape_key_edit_mode*", "animation/shape_keys/shape_keys_panel.html#bpy-types-object-use-shape-key-edit-mode"),
|
||||
("bpy.types.objectlineart.crease_threshold*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-crease-threshold"),
|
||||
("bpy.types.rendersettings.use_compositing*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-compositing"),
|
||||
@ -1012,6 +1022,8 @@ url_manual_mapping = (
|
||||
("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"),
|
||||
("bpy.types.compositornodecolorcorrection*", "compositing/types/color/adjust/color_correction.html#bpy-types-compositornodecolorcorrection"),
|
||||
("bpy.types.compositornodemoviedistortion*", "compositing/types/transform/movie_distortion.html#bpy-types-compositornodemoviedistortion"),
|
||||
("bpy.types.compositornodetree.chunk_size*", "compositing/sidebar.html#bpy-types-compositornodetree-chunk-size"),
|
||||
("bpy.types.compositornodetree.use_opencl*", "compositing/sidebar.html#bpy-types-compositornodetree-use-opencl"),
|
||||
("bpy.types.cyclesrendersettings.caustics*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-caustics"),
|
||||
("bpy.types.cyclesrendersettings.denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoiser"),
|
||||
("bpy.types.editbone.use_inherit_rotation*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-inherit-rotation"),
|
||||
@ -1113,6 +1125,7 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.rest_shape_key*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-rest-shape-key"),
|
||||
("bpy.types.compositornodebrightcontrast*", "compositing/types/color/adjust/bright_contrast.html#bpy-types-compositornodebrightcontrast"),
|
||||
("bpy.types.compositornodedoubleedgemask*", "compositing/types/mask/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"),
|
||||
("bpy.types.compositornodetree.precision*", "compositing/sidebar.html#bpy-types-compositornodetree-precision"),
|
||||
("bpy.types.cyclesrendersettings.samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-samples"),
|
||||
("bpy.types.dopesheet.show_only_selected*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-only-selected"),
|
||||
("bpy.types.ffmpegsettings.audio_bitrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-bitrate"),
|
||||
@ -1140,11 +1153,13 @@ url_manual_mapping = (
|
||||
("bpy.types.geometrynodetoolsetselection*", "modeling/geometry_nodes/geometry/write/set_selection.html#bpy-types-geometrynodetoolsetselection"),
|
||||
("bpy.types.geometrynodetree.is_modifier*", "editors/geometry_node.html#bpy-types-geometrynodetree-is-modifier"),
|
||||
("bpy.types.greasepencil.edit_line_color*", "grease_pencil/properties/display.html#bpy-types-greasepencil-edit-line-color"),
|
||||
("bpy.types.material.displacement_method*", "render/cycles/material_settings.html#bpy-types-material-displacement-method"),
|
||||
("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"),
|
||||
("bpy.types.materialgpencilstyle.pattern*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-pattern"),
|
||||
("bpy.types.materialgpencilstyle.texture*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-texture"),
|
||||
("bpy.types.modifier.use_apply_on_spline*", "modeling/modifiers/introduction.html#bpy-types-modifier-use-apply-on-spline"),
|
||||
("bpy.types.movietrackingplanetrack.name*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-name"),
|
||||
("bpy.types.nodetreeinterfacesocket.name*", "interface/controls/nodes/groups.html#bpy-types-nodetreeinterfacesocket-name"),
|
||||
("bpy.types.object.use_empty_image_alpha*", "modeling/empties.html#bpy-types-object-use-empty-image-alpha"),
|
||||
("bpy.types.rendersettings.frame_map_new*", "render/output/properties/frame_range.html#bpy-types-rendersettings-frame-map-new"),
|
||||
("bpy.types.rendersettings.frame_map_old*", "render/output/properties/frame_range.html#bpy-types-rendersettings-frame-map-old"),
|
||||
@ -1153,6 +1168,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.use_sequencer*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-sequencer"),
|
||||
("bpy.types.sceneeevee.volumetric_shadow*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-shadow"),
|
||||
("bpy.types.sequenceeditor.overlay_frame*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-overlay-frame"),
|
||||
("bpy.types.sequenceeditor.proxy_storage*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceeditor-proxy-storage"),
|
||||
("bpy.types.sequencetimelinechannel.lock*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-lock"),
|
||||
("bpy.types.sequencetimelinechannel.mute*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-mute"),
|
||||
("bpy.types.sequencetimelinechannel.name*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-name"),
|
||||
@ -1227,6 +1243,7 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodedistancematte*", "compositing/types/keying/distance_key.html#bpy-types-compositornodedistancematte"),
|
||||
("bpy.types.compositornodeseparatecolor*", "compositing/types/color/mix/separate_color.html#bpy-types-compositornodeseparatecolor"),
|
||||
("bpy.types.compositornodesetalpha.mode*", "compositing/types/color/set_alpha.html#bpy-types-compositornodesetalpha-mode"),
|
||||
("bpy.types.compositornodeviewer.center*", "compositing/types/output/viewer.html#bpy-types-compositornodeviewer-center"),
|
||||
("bpy.types.curves.use_sculpt_collision*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-use-sculpt-collision"),
|
||||
("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels/introduction.html#bpy-types-dopesheet-use-filter-invert"),
|
||||
("bpy.types.editbone.bbone_mapping_mode*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-mapping-mode"),
|
||||
@ -1289,6 +1306,7 @@ url_manual_mapping = (
|
||||
("bpy.types.sequence.show_retiming_keys*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-show-retiming-keys"),
|
||||
("bpy.types.sequenceeditor.show_overlay*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-show-overlay"),
|
||||
("bpy.types.sequenceeditor.use_prefetch*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-prefetch"),
|
||||
("bpy.types.sequenceproxy.use_overwrite*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy-use-overwrite"),
|
||||
("bpy.types.softbodysettings.ball_stiff*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-stiff"),
|
||||
("bpy.types.soundsequence.show_waveform*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-soundsequence-show-waveform"),
|
||||
("bpy.types.spaceclipeditor.show_stable*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-stable"),
|
||||
@ -1467,7 +1485,6 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"),
|
||||
("bpy.types.compositornodeellipsemask*", "compositing/types/mask/ellipse_mask.html#bpy-types-compositornodeellipsemask"),
|
||||
("bpy.types.compositornodeseparatexyz*", "compositing/types/vector/separate_xyz.html#bpy-types-compositornodeseparatexyz"),
|
||||
("bpy.types.compositornodesplitviewer*", "compositing/types/output/split_viewer.html#bpy-types-compositornodesplitviewer"),
|
||||
("bpy.types.curve.render_resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-render-resolution-u"),
|
||||
("bpy.types.cyclesrendersettings.seed*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-seed"),
|
||||
("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"),
|
||||
@ -1580,6 +1597,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"),
|
||||
("bpy.ops.sequencer.crossfade_sounds*", "video_editing/edit/montage/strips/transitions/sound_crossfade.html#bpy-ops-sequencer-crossfade-sounds"),
|
||||
("bpy.ops.sequencer.export_subtitles*", "editors/video_sequencer/preview/header.html#bpy-ops-sequencer-export-subtitles"),
|
||||
("bpy.ops.sequencer.previewrange_set*", "editors/video_sequencer/sequencer/navigating.html#bpy-ops-sequencer-previewrange-set"),
|
||||
("bpy.ops.sequencer.retiming_key_add*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-retiming-key-add"),
|
||||
("bpy.ops.text.jump_to_file_at_point*", "editors/text_editor.html#bpy-ops-text-jump-to-file-at-point"),
|
||||
("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"),
|
||||
@ -1653,13 +1671,13 @@ url_manual_mapping = (
|
||||
("bpy.types.mesh.use_mirror_topology*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-topology"),
|
||||
("bpy.types.movieclip.display_aspect*", "editors/clip/display/clip_display.html#bpy-types-movieclip-display-aspect"),
|
||||
("bpy.types.movietrackingtrack.color*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-color"),
|
||||
("bpy.types.nodesocketinterface.name*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-name"),
|
||||
("bpy.types.object.is_shadow_catcher*", "render/cycles/object_settings/object_data.html#bpy-types-object-is-shadow-catcher"),
|
||||
("bpy.types.particleinstancemodifier*", "modeling/modifiers/physics/particle_instance.html#bpy-types-particleinstancemodifier"),
|
||||
("bpy.types.rendersettings.hair_type*", "render/eevee/render_settings/hair.html#bpy-types-rendersettings-hair-type"),
|
||||
("bpy.types.rendersettings.tile_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-tile-size"),
|
||||
("bpy.types.rigidbodyobject.friction*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-friction"),
|
||||
("bpy.types.scenedisplay.viewport_aa*", "render/workbench/sampling.html#bpy-types-scenedisplay-viewport-aa"),
|
||||
("bpy.types.sequenceeditor.proxy_dir*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceeditor-proxy-dir"),
|
||||
("bpy.types.sequencertimelineoverlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay"),
|
||||
("bpy.types.sequencetransform.filter*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-filter"),
|
||||
("bpy.types.sequencetransform.offset*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-offset"),
|
||||
@ -1697,6 +1715,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.geometry.attribute_remove*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-geometry-attribute-remove"),
|
||||
("bpy.ops.gpencil.frame_clean_loose*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-loose"),
|
||||
("bpy.ops.gpencil.selectmode_toggle*", "grease_pencil/selecting.html#bpy-ops-gpencil-selectmode-toggle"),
|
||||
("bpy.ops.graph.scale_from_neighbor*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-scale-from-neighbor"),
|
||||
("bpy.ops.mask.feather_weight_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-feather-weight-clear"),
|
||||
("bpy.ops.mask.primitive_circle_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-circle-add"),
|
||||
("bpy.ops.mask.primitive_square_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-square-add"),
|
||||
@ -1719,6 +1738,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.render.play_rendered_anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"),
|
||||
("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-set-pivot-position"),
|
||||
("bpy.ops.sculpt.trim_lasso_gesture*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-trim-lasso-gesture"),
|
||||
("bpy.ops.sculpt_curves.select_ends*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-ends"),
|
||||
("bpy.ops.sculpt_curves.select_grow*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-grow"),
|
||||
("bpy.ops.sequencer.image_strip_add*", "video_editing/edit/montage/strips/image.html#bpy-ops-sequencer-image-strip-add"),
|
||||
("bpy.ops.sequencer.images_separate*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-images-separate"),
|
||||
@ -1802,6 +1822,7 @@ url_manual_mapping = (
|
||||
("bpy.types.limitdistanceconstraint*", "animation/constraints/transform/limit_distance.html#bpy-types-limitdistanceconstraint"),
|
||||
("bpy.types.limitlocationconstraint*", "animation/constraints/transform/limit_location.html#bpy-types-limitlocationconstraint"),
|
||||
("bpy.types.limitrotationconstraint*", "animation/constraints/transform/limit_rotation.html#bpy-types-limitrotationconstraint"),
|
||||
("bpy.types.moviesequence.use_proxy*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-moviesequence-use-proxy"),
|
||||
("bpy.types.movietrackingtrack.lock*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-lock"),
|
||||
("bpy.types.movietrackingtrack.name*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-name"),
|
||||
("bpy.types.multiplygpencilmodifier*", "grease_pencil/modifiers/generate/multiple_strokes.html#bpy-types-multiplygpencilmodifier"),
|
||||
@ -1844,6 +1865,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.gpencil.vertex_color_set*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-set"),
|
||||
("bpy.ops.graph.extrapolation_type*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-extrapolation-type"),
|
||||
("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"),
|
||||
("bpy.ops.graph.select_key_handles*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-key-handles"),
|
||||
("bpy.ops.image.match_movie_length*", "editors/image/image_settings.html#bpy-ops-image-match-movie-length"),
|
||||
("bpy.ops.mesh.customdata_skin_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-add"),
|
||||
("bpy.ops.mesh.dissolve_degenerate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-dissolve-degenerate"),
|
||||
@ -1851,6 +1873,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.mark_freestyle_face*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-mark-freestyle-face"),
|
||||
("bpy.ops.mesh.primitive_plane_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-plane-add"),
|
||||
("bpy.ops.mesh.primitive_torus_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-torus-add"),
|
||||
("bpy.ops.mesh.select_by_attribute*", "modeling/meshes/selecting/by_attribute.html#bpy-ops-mesh-select-by-attribute"),
|
||||
("bpy.ops.mesh.select_non_manifold*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-non-manifold"),
|
||||
("bpy.ops.nla.selected_objects_add*", "editors/nla/introduction.html#bpy-ops-nla-selected-objects-add"),
|
||||
("bpy.ops.object.constraints_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-clear"),
|
||||
@ -1870,14 +1893,15 @@ url_manual_mapping = (
|
||||
("bpy.ops.scene.view_layer_add_aov*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-aov"),
|
||||
("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"),
|
||||
("bpy.ops.sculpt.detail_flood_fill*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-detail-flood-fill"),
|
||||
("bpy.ops.sculpt_curves.select_end*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-end"),
|
||||
("bpy.ops.sequencer.duplicate_move*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-duplicate-move"),
|
||||
("bpy.ops.sequencer.enable_proxies*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-ops-sequencer-enable-proxies"),
|
||||
("bpy.ops.sequencer.retiming_reset*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-retiming-reset"),
|
||||
("bpy.ops.sequencer.select_grouped*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-grouped"),
|
||||
("bpy.ops.sequencer.select_handles*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-handles"),
|
||||
("bpy.ops.ui.copy_data_path_button*", "interface/controls/buttons/menus.html#bpy-ops-ui-copy-data-path-button"),
|
||||
("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"),
|
||||
("bpy.ops.wm.read_factory_settings*", "interface/window_system/topbar.html#bpy-ops-wm-read-factory-settings"),
|
||||
("bpy.ops.wm.read_factory_userpref*", "editors/preferences/introduction.html#bpy-ops-wm-read-factory-userpref"),
|
||||
("bpy.types.action.use_frame_range*", "animation/actions.html#bpy-types-action-use-frame-range"),
|
||||
("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"),
|
||||
("bpy.types.armature.pose_position*", "animation/armatures/properties/introduction.html#bpy-types-armature-pose-position"),
|
||||
@ -1934,6 +1958,7 @@ url_manual_mapping = (
|
||||
("bpy.types.geometrynodeinputimage*", "modeling/geometry_nodes/input/constant/image.html#bpy-types-geometrynodeinputimage"),
|
||||
("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/geometry/read/input_index.html#bpy-types-geometrynodeinputindex"),
|
||||
("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/scene/is_viewport.html#bpy-types-geometrynodeisviewport"),
|
||||
("bpy.types.geometrynodemenuswitch*", "modeling/geometry_nodes/utilities/menu_switch.html#bpy-types-geometrynodemenuswitch"),
|
||||
("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh/primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"),
|
||||
("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/scene/object_info.html#bpy-types-geometrynodeobjectinfo"),
|
||||
("bpy.types.geometrynodeselfobject*", "modeling/geometry_nodes/input/scene/self_object.html#bpy-types-geometrynodeselfobject"),
|
||||
@ -1966,6 +1991,7 @@ url_manual_mapping = (
|
||||
("bpy.types.sceneeevee.motion_blur*", "render/eevee/render_settings/motion_blur.html#bpy-types-sceneeevee-motion-blur"),
|
||||
("bpy.types.sceneeevee.taa_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-samples"),
|
||||
("bpy.types.sculpt.radial_symmetry*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-radial-symmetry"),
|
||||
("bpy.types.sequenceproxy.timecode*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy-timecode"),
|
||||
("bpy.types.shadernodecombinecolor*", "render/shader_nodes/converter/combine_color.html#bpy-types-shadernodecombinecolor"),
|
||||
("bpy.types.shadernodedisplacement*", "render/shader_nodes/vector/displacement.html#bpy-types-shadernodedisplacement"),
|
||||
("bpy.types.shadernodelightfalloff*", "render/shader_nodes/color/light_falloff.html#bpy-types-shadernodelightfalloff"),
|
||||
@ -2038,6 +2064,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"),
|
||||
("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/brush/brush_settings.html#bpy-ops-paint-brush-colors-flip"),
|
||||
("bpy.ops.paint.vertex_color_dirt*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-dirt"),
|
||||
("bpy.ops.paint.visibility_invert*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-paint-visibility-invert"),
|
||||
("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"),
|
||||
("bpy.ops.paintcurve.delete_point*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-delete-point"),
|
||||
("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"),
|
||||
@ -2046,6 +2073,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"),
|
||||
("bpy.ops.sculpt.face_sets_create*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-create"),
|
||||
("bpy.ops.sculpt.trim_box_gesture*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-trim-box-gesture"),
|
||||
("bpy.ops.sequencer.rebuild_proxy*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-ops-sequencer-rebuild-proxy"),
|
||||
("bpy.ops.sequencer.retiming_show*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-retiming-show"),
|
||||
("bpy.ops.sequencer.select_linked*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-linked"),
|
||||
("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"),
|
||||
@ -2122,6 +2150,7 @@ url_manual_mapping = (
|
||||
("bpy.types.sculpt.detail_percent*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-percent"),
|
||||
("bpy.types.sculpt.gravity_object*", "sculpt_paint/sculpting/tool_settings/options.html#bpy-types-sculpt-gravity-object"),
|
||||
("bpy.types.sculpt.show_face_sets*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-types-sculpt-show-face-sets"),
|
||||
("bpy.types.sequenceproxy.quality*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy-quality"),
|
||||
("bpy.types.shadernodebsdfdiffuse*", "render/shader_nodes/shader/diffuse.html#bpy-types-shadernodebsdfdiffuse"),
|
||||
("bpy.types.shadernodelayerweight*", "render/shader_nodes/input/layer_weight.html#bpy-types-shadernodelayerweight"),
|
||||
("bpy.types.shadernodenewgeometry*", "render/shader_nodes/input/geometry.html#bpy-types-shadernodenewgeometry"),
|
||||
@ -2163,6 +2192,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.gpencil.stroke_outline*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-outline"),
|
||||
("bpy.ops.graph.blend_to_default*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-default"),
|
||||
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
||||
("bpy.ops.graph.select_leftright*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-leftright"),
|
||||
("bpy.ops.graph.sound_to_samples*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-sound-to-samples"),
|
||||
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
||||
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
||||
@ -2370,6 +2400,7 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodeimage*", "compositing/types/input/image.html#bpy-types-compositornodeimage"),
|
||||
("bpy.types.compositornodemapuv*", "compositing/types/transform/map_uv.html#bpy-types-compositornodemapuv"),
|
||||
("bpy.types.compositornodescale*", "compositing/types/transform/scale.html#bpy-types-compositornodescale"),
|
||||
("bpy.types.compositornodesplit*", "compositing/types/utilities/split.html#bpy-types-compositornodesplit"),
|
||||
("bpy.types.compositornodevalue*", "compositing/types/input/constant/value.html#bpy-types-compositornodevalue"),
|
||||
("bpy.types.copyscaleconstraint*", "animation/constraints/transform/copy_scale.html#bpy-types-copyscaleconstraint"),
|
||||
("bpy.types.curve.path_duration*", "modeling/curves/properties/path_animation.html#bpy-types-curve-path-duration"),
|
||||
@ -2401,6 +2432,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rigidbodyconstraint*", "physics/rigid_body/constraints/index.html#bpy-types-rigidbodyconstraint"),
|
||||
("bpy.types.rigifyarmaturelayer*", "addons/rigging/rigify/metarigs.html#bpy-types-rigifyarmaturelayer"),
|
||||
("bpy.types.scene.show_subframe*", "editors/timeline.html#bpy-types-scene-show-subframe"),
|
||||
("bpy.types.sequenceproxy.build*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy-build"),
|
||||
("bpy.types.shadernodeaddshader*", "render/shader_nodes/shader/add.html#bpy-types-shadernodeaddshader"),
|
||||
("bpy.types.shadernodeattribute*", "render/shader_nodes/input/attribute.html#bpy-types-shadernodeattribute"),
|
||||
("bpy.types.shadernodeblackbody*", "render/shader_nodes/converter/blackbody.html#bpy-types-shadernodeblackbody"),
|
||||
@ -2412,6 +2444,7 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodeoutputaov*", "render/shader_nodes/output/aov.html#bpy-types-shadernodeoutputaov"),
|
||||
("bpy.types.shadernodepointinfo*", "render/shader_nodes/input/point_info.html#bpy-types-shadernodepointinfo"),
|
||||
("bpy.types.shadernodewireframe*", "render/shader_nodes/input/wireframe.html#bpy-types-shadernodewireframe"),
|
||||
("bpy.types.shapekey.lock_shape*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-lock-shape"),
|
||||
("bpy.types.shapekey.slider_max*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-slider-max"),
|
||||
("bpy.types.shapekey.slider_min*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-slider-min"),
|
||||
("bpy.types.spacesequenceeditor*", "editors/video_sequencer/index.html#bpy-types-spacesequenceeditor"),
|
||||
@ -2491,6 +2524,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.sculpt.face_set_edit*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-edit"),
|
||||
("bpy.ops.sequencer.gap_insert*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-gap-insert"),
|
||||
("bpy.ops.sequencer.gap_remove*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-gap-remove"),
|
||||
("bpy.ops.sequencer.hold_split*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-hold-split"),
|
||||
("bpy.ops.sequencer.rendersize*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-rendersize"),
|
||||
("bpy.ops.sequencer.select_all*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-all"),
|
||||
("bpy.ops.sequencer.select_box*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-box"),
|
||||
@ -2609,8 +2643,11 @@ url_manual_mapping = (
|
||||
("bpy.ops.gpencil.stroke_trim*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-trim"),
|
||||
("bpy.ops.gpencil.trace_image*", "grease_pencil/modes/object/trace_image.html#bpy-ops-gpencil-trace-image"),
|
||||
("bpy.ops.graph.blend_to_ease*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-ease"),
|
||||
("bpy.ops.graph.channels_bake*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-channels-bake"),
|
||||
("bpy.ops.graph.fmodifier_add*", "editors/graph_editor/channels/editing.html#bpy-ops-graph-fmodifier-add"),
|
||||
("bpy.ops.graph.scale_average*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-scale-average"),
|
||||
("bpy.ops.graph.select_column*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-column"),
|
||||
("bpy.ops.graph.select_linked*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-linked"),
|
||||
("bpy.ops.image.external_edit*", "editors/image/editing.html#bpy-ops-image-external-edit"),
|
||||
("bpy.ops.mesh.colors_reverse*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-reverse"),
|
||||
("bpy.ops.mesh.dissolve_edges*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-edges"),
|
||||
@ -2889,6 +2926,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"),
|
||||
("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"),
|
||||
("bpy.ops.graph.match_slope*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-match-slope"),
|
||||
("bpy.ops.graph.select_less*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-less"),
|
||||
("bpy.ops.graph.select_more*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-more"),
|
||||
("bpy.ops.graph.time_offset*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-time-offset"),
|
||||
("bpy.ops.marker.select_all*", "animation/markers.html#bpy-ops-marker-select-all"),
|
||||
("bpy.ops.mask.copy_splines*", "movie_clip/masking/editing.html#bpy-ops-mask-copy-splines"),
|
||||
@ -2919,7 +2958,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.screen.area_split*", "interface/window_system/areas.html#bpy-ops-screen-area-split"),
|
||||
("bpy.ops.screen.screenshot*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot"),
|
||||
("bpy.ops.sculpt.dirty_mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-dirty-mask"),
|
||||
("bpy.ops.sculpt.reveal_all*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-reveal-all"),
|
||||
("bpy.ops.sculpt.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"),
|
||||
("bpy.ops.uv.align_rotation*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align-rotation"),
|
||||
("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"),
|
||||
@ -2988,6 +3026,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.font.textbox_add*", "modeling/texts/properties.html#bpy-ops-font-textbox-add"),
|
||||
("bpy.ops.gpencil.dissolve*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-dissolve"),
|
||||
("bpy.ops.graph.frame_jump*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-frame-jump"),
|
||||
("bpy.ops.graph.select_all*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-all"),
|
||||
("bpy.ops.graph.select_box*", "editors/graph_editor/introduction.html#bpy-ops-graph-select-box"),
|
||||
("bpy.ops.marker.duplicate*", "animation/markers.html#bpy-ops-marker-duplicate"),
|
||||
("bpy.ops.mask.select_less*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-less"),
|
||||
("bpy.ops.mask.select_more*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-more"),
|
||||
@ -3028,8 +3068,10 @@ url_manual_mapping = (
|
||||
("bpy.ops.view3d.view_roll*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-roll"),
|
||||
("bpy.ops.wm.open_mainfile*", "files/blend/open_save.html#bpy-ops-wm-open-mainfile"),
|
||||
("bpy.ops.wm.owner_disable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-disable"),
|
||||
("bpy.ops.wm.read_userpref*", "editors/preferences/introduction.html#bpy-ops-wm-read-userpref"),
|
||||
("bpy.ops.wm.save_homefile*", "interface/window_system/topbar.html#bpy-ops-wm-save-homefile"),
|
||||
("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"),
|
||||
("bpy.ops.wm.save_userpref*", "editors/preferences/introduction.html#bpy-ops-wm-save-userpref"),
|
||||
("bpy.types.arealight.size*", "render/lights/light_object.html#bpy-types-arealight-size"),
|
||||
("bpy.types.attributegroup*", "modeling/meshes/properties/object_data.html#bpy-types-attributegroup"),
|
||||
("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"),
|
||||
@ -3115,6 +3157,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"),
|
||||
("bpy.ops.object.mode_set*", "editors/3dview/modes.html#bpy-ops-object-mode-set"),
|
||||
("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"),
|
||||
("bpy.ops.paint.hide_show*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-paint-hide-show"),
|
||||
("bpy.ops.paintcurve.draw*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-draw"),
|
||||
("bpy.ops.pose.relax_rest*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-relax-rest"),
|
||||
("bpy.ops.pose.select_all*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-all"),
|
||||
|
@ -1299,7 +1299,6 @@ def km_outliner(params):
|
||||
("outliner.show_one_level", {"type": 'NUMPAD_MINUS', "value": 'PRESS'},
|
||||
{"properties": [("open", False)]}),
|
||||
*_template_items_select_actions(params, "outliner.select_all"),
|
||||
("outliner.expanded_toggle", {"type": 'A', "value": 'PRESS', "shift": True}, None),
|
||||
("outliner.keyingset_add_selected", {"type": 'K', "value": 'PRESS'}, None),
|
||||
("outliner.keyingset_remove_selected", {"type": 'K', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
|
||||
@ -1318,6 +1317,11 @@ def km_outliner(params):
|
||||
# Copy/paste.
|
||||
("outliner.id_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
("outliner.id_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
||||
op_menu("VIEW3D_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
("object.duplicate", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("object.duplicate", {"type": 'D', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("linked", True)]}),
|
||||
])
|
||||
|
||||
return keymap
|
||||
@ -4612,6 +4616,8 @@ def km_grease_pencil_edit_mode(params):
|
||||
# Dissolve
|
||||
("grease_pencil.dissolve", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
|
||||
("grease_pencil.dissolve", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None),
|
||||
# Separate
|
||||
("grease_pencil.separate", {"type": 'P', "value": 'PRESS'}, None),
|
||||
# Delete all active frames
|
||||
("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("type", "ALL_FRAMES")]}),
|
||||
|
@ -557,6 +557,8 @@ def km_outliner(params):
|
||||
# Copy/paste.
|
||||
("outliner.id_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
("outliner.id_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
||||
("object.duplicate", {"type": 'D', "value": 'PRESS', "ctrl": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -6,10 +6,12 @@ import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
OperatorFileListElement,
|
||||
WindowManager,
|
||||
)
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.app.translations import (
|
||||
@ -622,7 +624,7 @@ class AddPresetOperator(AddPresetBase, Operator):
|
||||
|
||||
ret = []
|
||||
for prop_id, prop in operator_rna.properties.items():
|
||||
if not (prop.is_hidden or prop.is_skip_save):
|
||||
if not prop.is_skip_preset:
|
||||
if prop_id not in properties_blacklist:
|
||||
ret.append("op.%s" % prop_id)
|
||||
|
||||
@ -655,6 +657,74 @@ class WM_MT_operator_presets(Menu):
|
||||
preset_operator = "script.execute_preset"
|
||||
|
||||
|
||||
class WM_OT_operator_presets_cleanup(Operator):
|
||||
bl_idname = "wm.operator_presets_cleanup"
|
||||
bl_label = "Clean Up Operator Presets"
|
||||
bl_description = "Remove outdated operator properties from presets that may cause problems"
|
||||
|
||||
operator: StringProperty(name="operator")
|
||||
properties: CollectionProperty(name="properties", type=OperatorFileListElement)
|
||||
|
||||
def cleanup_preset(self, filepath, properties):
|
||||
from pathlib import Path
|
||||
file = Path(filepath)
|
||||
if not (file.is_file() and filepath.suffix == ".py"):
|
||||
return
|
||||
lines = file.read_text().splitlines(True)
|
||||
if len(lines) == 0:
|
||||
return
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
if not any(line.startswith(("op.%s" % prop)) for prop in properties):
|
||||
new_lines.append(line)
|
||||
file.write_text("".join(new_lines))
|
||||
|
||||
def cleanup_operators_presets(self, operators, properties):
|
||||
base_preset_directory = bpy.utils.user_resource(
|
||||
'SCRIPTS', path="presets", create=False)
|
||||
for operator in operators:
|
||||
from pathlib import Path
|
||||
operator_path = AddPresetOperator.operator_path(operator)
|
||||
directory = Path(base_preset_directory, operator_path)
|
||||
|
||||
if not directory.is_dir():
|
||||
continue
|
||||
|
||||
for filepath in directory.iterdir():
|
||||
self.cleanup_preset(filepath, properties)
|
||||
|
||||
def execute(self, context):
|
||||
properties = []
|
||||
operators = []
|
||||
if self.operator:
|
||||
operators.append(self.operator)
|
||||
for prop in self.properties:
|
||||
properties.append(prop.name)
|
||||
else:
|
||||
# Cleanup by default I/O Operators Presets
|
||||
operators = ['WM_OT_alembic_export',
|
||||
'WM_OT_alembic_import',
|
||||
'WM_OT_collada_export',
|
||||
'WM_OT_collada_import',
|
||||
'WM_OT_gpencil_export_svg',
|
||||
'WM_OT_gpencil_export_pdf',
|
||||
'WM_OT_gpencil_export_svg',
|
||||
'WM_OT_gpencil_import_svg',
|
||||
'WM_OT_obj_export',
|
||||
'WM_OT_obj_import',
|
||||
'WM_OT_ply_export',
|
||||
'WM_OT_ply_import',
|
||||
'WM_OT_stl_export',
|
||||
'WM_OT_stl_import',
|
||||
'WM_OT_usd_export',
|
||||
'WM_OT_usd_import',
|
||||
]
|
||||
properties = ["filepath", "directory", "files", "filename"]
|
||||
|
||||
self.cleanup_operators_presets(operators, properties)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddPresetGpencilBrush(AddPresetBase, Operator):
|
||||
"""Add or remove grease pencil brush preset"""
|
||||
bl_idname = "scene.gpencil_brush_preset_add"
|
||||
@ -748,4 +818,5 @@ classes = (
|
||||
AddPresetEEVEERaytracing,
|
||||
ExecutePreset,
|
||||
WM_MT_operator_presets,
|
||||
WM_OT_operator_presets_cleanup,
|
||||
)
|
||||
|
@ -148,6 +148,8 @@ class PREFERENCES_OT_copy_prev(Operator):
|
||||
# Reload preferences and `recent-files.txt`.
|
||||
bpy.ops.wm.read_userpref()
|
||||
bpy.ops.wm.read_history()
|
||||
# Fix operator presets that have unwanted filepath properties
|
||||
bpy.ops.wm.operator_presets_cleanup()
|
||||
|
||||
# don't loose users work if they open the splash later.
|
||||
if bpy.data.is_saved is bpy.data.is_dirty is False:
|
||||
|
@ -3487,7 +3487,8 @@ class WM_MT_region_toggle_pie(Menu):
|
||||
text = enum_items[region_type].name
|
||||
attr = cls._region_info[region_type]
|
||||
value = getattr(space_data, attr)
|
||||
props = pie.operator("wm.context_toggle", text=text, icon='CHECKBOX_HLT' if value else 'CHECKBOX_DEHLT')
|
||||
props = pie.operator("wm.context_toggle", text=text, text_ctxt=i18n_contexts.default,
|
||||
icon='CHECKBOX_HLT' if value else 'CHECKBOX_DEHLT')
|
||||
props.data_path = "space_data." + attr
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -7,6 +7,7 @@ from bpy.types import Menu
|
||||
from bl_ui import node_add_menu
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
contexts as i18n_contexts,
|
||||
)
|
||||
|
||||
|
||||
@ -231,6 +232,7 @@ class NODE_MT_category_compositor_mask(Menu):
|
||||
class NODE_MT_category_compositor_tracking(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_tracking"
|
||||
bl_label = "Tracking"
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
@ -542,6 +542,7 @@ class NODE_MT_category_GEO_UTILITIES(Menu):
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_FIELD")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_MATH")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_ROTATION")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_DEPRECATED")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeIndexSwitch")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeMenuSwitch")
|
||||
@ -551,6 +552,15 @@ class NODE_MT_category_GEO_UTILITIES(Menu):
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_UTILITIES_DEPRECATED(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_UTILITIES_DEPRECATED"
|
||||
bl_label = "Deprecated"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler")
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_UTILITIES_FIELD(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_UTILITIES_FIELD"
|
||||
bl_label = "Field"
|
||||
@ -769,6 +779,7 @@ classes = (
|
||||
NODE_MT_category_GEO_UTILITIES_FIELD,
|
||||
NODE_MT_category_GEO_UTILITIES_MATH,
|
||||
NODE_MT_category_GEO_UTILITIES_ROTATION,
|
||||
NODE_MT_category_GEO_UTILITIES_DEPRECATED,
|
||||
NODE_MT_category_GEO_GROUP,
|
||||
)
|
||||
|
||||
|
@ -42,6 +42,9 @@ class MotionPathButtonsPanel:
|
||||
start_end_group.prop(mps, "frame_end", text="End")
|
||||
col.prop(mps, "frame_step", text="Step")
|
||||
|
||||
row = col.row()
|
||||
row.prop(mps, "bake_in_camera_space", text="Bake to Active Camera")
|
||||
|
||||
if bones:
|
||||
op_category = "pose"
|
||||
icon = 'BONE_DATA'
|
||||
|
@ -118,13 +118,15 @@ class DATA_PT_bone_collections(ArmatureButtonsPanel, Panel):
|
||||
col = row.column(align=True)
|
||||
col.operator("armature.collection_add", icon='ADD', text="")
|
||||
col.operator("armature.collection_remove", icon='REMOVE', text="")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.menu("ARMATURE_MT_collection_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
if active_bcoll:
|
||||
col.separator()
|
||||
col.operator("armature.collection_move", icon='TRIA_UP', text="").direction = 'UP'
|
||||
col.operator("armature.collection_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
|
||||
col.separator()
|
||||
|
||||
col.menu("ARMATURE_MT_collection_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
|
@ -15,6 +15,17 @@ class DataButtonsPanel:
|
||||
return hasattr(context, "grease_pencil") and context.grease_pencil
|
||||
|
||||
|
||||
class LayerDataButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "data"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
grease_pencil = context.grease_pencil
|
||||
return grease_pencil and grease_pencil.layers.active
|
||||
|
||||
|
||||
class DATA_PT_context_grease_pencil(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
@ -67,13 +78,59 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
|
||||
layout.use_property_decorate = True
|
||||
col = layout.column(align=True)
|
||||
|
||||
col = layout.row(align=True)
|
||||
col.prop(layer, "opacity", text="Opacity", slider=True)
|
||||
row = layout.row(align=True)
|
||||
row.prop(layer, "opacity", text="Opacity", slider=True)
|
||||
|
||||
|
||||
class DATA_PT_grease_pencil_layer_transform(LayerDataButtonsPanel, Panel):
|
||||
bl_label = "Transform"
|
||||
bl_parent_id = "DATA_PT_grease_pencil_layers"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
||||
grease_pencil = context.grease_pencil
|
||||
layer = grease_pencil.layers.active
|
||||
layout.active = not layer.lock
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(layer, "translation")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(layer, "rotation")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(layer, "scale")
|
||||
|
||||
|
||||
class DATA_PT_grease_pencil_layer_relations(LayerDataButtonsPanel, Panel):
|
||||
bl_label = "Relations"
|
||||
bl_parent_id = "DATA_PT_grease_pencil_layers"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
||||
grease_pencil = context.grease_pencil
|
||||
layer = grease_pencil.layers.active
|
||||
layout.active = not layer.lock
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(layer, "parent", text="Parent")
|
||||
|
||||
if layer.parent and layer.parent.type == 'ARMATURE':
|
||||
row = layout.row(align=True)
|
||||
row.prop_search(layer, "parent_bone", layer.parent.data, "bones", text="Bone")
|
||||
|
||||
|
||||
classes = (
|
||||
DATA_PT_context_grease_pencil,
|
||||
DATA_PT_grease_pencil_layers,
|
||||
DATA_PT_grease_pencil_layer_transform,
|
||||
DATA_PT_grease_pencil_layer_relations,
|
||||
GREASE_PENCIL_MT_grease_pencil_add_layer_extra,
|
||||
)
|
||||
|
||||
|
@ -98,6 +98,7 @@ class DATA_PT_EEVEE_light(DataButtonsPanel, Panel):
|
||||
col.separator()
|
||||
|
||||
if light.type in {'POINT', 'SPOT'}:
|
||||
col.prop(light, "use_soft_falloff")
|
||||
col.prop(light, "shadow_soft_size", text="Radius")
|
||||
elif light.type == 'SUN':
|
||||
col.prop(light, "angle")
|
||||
|
@ -608,7 +608,7 @@ class GreasePencilMaterialsPanel:
|
||||
row.operator("grease_pencil.stroke_material_set", text="Assign")
|
||||
elif not is_grease_pencil_version3 and ob.data.use_stroke_edit_mode:
|
||||
row = layout.row(align=True)
|
||||
row.operator("gpencil.stroke_material_set", text="Assign")
|
||||
row.operator("gpencil.stroke_change_color", text="Assign")
|
||||
row.operator("gpencil.material_select", text="Select").deselect = False
|
||||
row.operator("gpencil.material_select", text="Deselect").deselect = True
|
||||
# stroke color
|
||||
|
@ -212,10 +212,10 @@ class MASK_PT_point:
|
||||
if parent.parent in tracking.objects:
|
||||
ob = tracking.objects[parent.parent]
|
||||
col.prop_search(parent, "sub_parent", ob,
|
||||
tracks_list, icon='ANIM_DATA', text="Track")
|
||||
tracks_list, icon='ANIM_DATA', text="Track", text_ctxt=i18n_contexts.id_movieclip)
|
||||
else:
|
||||
col.prop_search(parent, "sub_parent", tracking,
|
||||
tracks_list, icon='ANIM_DATA', text="Track")
|
||||
tracks_list, icon='ANIM_DATA', text="Track", text_ctxt=i18n_contexts.id_movieclip)
|
||||
|
||||
|
||||
class MASK_PT_display:
|
||||
|
@ -319,6 +319,32 @@ class VIEWLAYER_PT_layer_passes_lightgroups(ViewLayerLightgroupsPanel):
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
|
||||
class VIEWLAYER_PT_filter(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Filter"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
view_layer = context.view_layer
|
||||
|
||||
col = layout.column(heading="Include")
|
||||
col.prop(view_layer, "use_sky", text="Environment")
|
||||
col.prop(view_layer, "use_solid", text="Surfaces")
|
||||
col.prop(view_layer, "use_strand", text="Curves")
|
||||
col.prop(view_layer, "use_volumes", text="Volumes")
|
||||
|
||||
col = layout.column(heading="Use")
|
||||
sub = col.row()
|
||||
sub.prop(view_layer, "use_motion_blur", text="Motion Blur")
|
||||
sub.active = scene.eevee.use_motion_blur
|
||||
|
||||
|
||||
class VIEWLAYER_PT_layer_custom_props(PropertyPanel, Panel):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
@ -340,6 +366,7 @@ classes = (
|
||||
VIEWLAYER_PT_layer_passes_cryptomatte,
|
||||
VIEWLAYER_PT_layer_passes_aov,
|
||||
VIEWLAYER_PT_layer_passes_lightgroups,
|
||||
VIEWLAYER_PT_filter,
|
||||
VIEWLAYER_PT_layer_custom_props,
|
||||
VIEWLAYER_UL_aov,
|
||||
)
|
||||
|
@ -363,7 +363,7 @@ class CLIP_PT_tools_clip(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_label = "Clip"
|
||||
bl_translation_context = bpy.app.translations.contexts.id_movieclip
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
bl_category = "Track"
|
||||
|
||||
@classmethod
|
||||
@ -473,6 +473,7 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_label = "Track"
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
bl_category = "Track"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@ -725,6 +726,7 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Track"
|
||||
bl_label = "Track"
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -1265,7 +1267,6 @@ class CLIP_PT_tools_scenesetup(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_label = "Scene Setup"
|
||||
bl_translation_context = bpy.app.translations.contexts.id_movieclip
|
||||
bl_category = "Solve"
|
||||
|
||||
@classmethod
|
||||
@ -1364,7 +1365,7 @@ class CLIP_MT_view(Menu):
|
||||
|
||||
class CLIP_MT_clip(Menu):
|
||||
bl_label = "Clip"
|
||||
bl_translation_context = bpy.app.translations.contexts.id_movieclip
|
||||
bl_translation_context = i18n_contexts.id_movieclip
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -159,6 +159,7 @@ class GRAPH_MT_view(Menu):
|
||||
layout.prop(st, "use_realtime_update")
|
||||
layout.prop(st, "show_sliders")
|
||||
layout.prop(st, "use_auto_merge_keyframes")
|
||||
layout.prop(st, "autolock_translation_axis")
|
||||
layout.separator()
|
||||
|
||||
if st.mode != 'DRIVERS':
|
||||
|
@ -1431,8 +1431,11 @@ class IMAGE_PT_view_vectorscope(ImageScopesPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
sima = context.space_data
|
||||
|
||||
layout.template_vectorscope(sima, "scopes")
|
||||
layout.prop(sima.scopes, "vectorscope_alpha")
|
||||
row = layout.split(factor=0.75)
|
||||
row.prop(sima.scopes, "vectorscope_alpha")
|
||||
row.prop(sima.scopes, "vectorscope_mode", text="")
|
||||
|
||||
|
||||
class IMAGE_PT_sample_line(ImageScopesPanel, Panel):
|
||||
|
@ -206,6 +206,7 @@ class NLA_MT_add(Menu):
|
||||
|
||||
class NLA_MT_tracks(Menu):
|
||||
bl_label = "Track"
|
||||
bl_translation_context = i18n_contexts.id_action
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
@ -155,6 +155,7 @@ class OUTLINER_MT_view_pie(Menu):
|
||||
pie = layout.menu_pie()
|
||||
pie.operator("outliner.show_hierarchy")
|
||||
pie.operator("outliner.show_active", icon='ZOOM_SELECTED')
|
||||
pie.operator("outliner.expanded_toggle")
|
||||
|
||||
|
||||
class OUTLINER_MT_edit_datablocks(Menu):
|
||||
|
@ -454,6 +454,7 @@ class TOPBAR_MT_blender_system(Menu):
|
||||
layout.separator()
|
||||
|
||||
layout.operator("screen.spacedata_cleanup")
|
||||
layout.operator("wm.operator_presets_cleanup")
|
||||
|
||||
|
||||
class TOPBAR_MT_templates_more(Menu):
|
||||
|
@ -1134,11 +1134,12 @@ class VIEW3D_MT_editor_menus(Menu):
|
||||
elif mode_string == 'VERTEX_GPENCIL':
|
||||
layout.menu("VIEW3D_MT_select_edit_gpencil")
|
||||
elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
|
||||
mesh = obj.data
|
||||
if mesh.use_paint_mask:
|
||||
layout.menu("VIEW3D_MT_select_paint_mask")
|
||||
elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
|
||||
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
|
||||
if obj.type == 'MESH':
|
||||
mesh = obj.data
|
||||
if mesh.use_paint_mask:
|
||||
layout.menu("VIEW3D_MT_select_paint_mask")
|
||||
elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
|
||||
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
|
||||
elif mode_string not in {'SCULPT', 'SCULPT_CURVES', 'PAINT_GREASE_PENCIL'}:
|
||||
layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
|
||||
|
||||
@ -3173,6 +3174,7 @@ class VIEW3D_MT_object_parent(Menu):
|
||||
|
||||
class VIEW3D_MT_object_track(Menu):
|
||||
bl_label = "Track"
|
||||
bl_translation_context = i18n_contexts.constraint
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
@ -3558,8 +3560,10 @@ class VIEW3D_MT_paint_weight(Menu):
|
||||
|
||||
layout.menu("VIEW3D_MT_paint_weight_lock", text="Locks")
|
||||
|
||||
def draw(self, _context):
|
||||
self.draw_generic(self.layout, is_editmode=False)
|
||||
def draw(self, context):
|
||||
obj = context.active_object
|
||||
if obj.type == 'MESH':
|
||||
self.draw_generic(self.layout, is_editmode=False)
|
||||
|
||||
|
||||
class VIEW3D_MT_sculpt(Menu):
|
||||
@ -4465,6 +4469,7 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
|
||||
|
||||
col.operator("mesh.mark_sharp")
|
||||
col.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
|
||||
col.operator("mesh.set_sharpness_by_angle")
|
||||
|
||||
if with_freestyle:
|
||||
col.separator()
|
||||
@ -5829,20 +5834,18 @@ class VIEW3D_MT_edit_greasepencil(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("grease_pencil.duplicate_move")
|
||||
layout.operator("grease_pencil.duplicate_move", text="Duplicate")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("VIEW3D_MT_edit_greasepencil_showhide")
|
||||
layout.operator_menu_enum("grease_pencil.separate", "mode", text="Separate")
|
||||
layout.operator("grease_pencil.clean_loose")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("VIEW3D_MT_edit_greasepencil_delete")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("grease_pencil.clean_loose")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_greasepencil_stroke(Menu):
|
||||
bl_label = "Stroke"
|
||||
@ -5858,27 +5861,26 @@ class VIEW3D_MT_edit_greasepencil_stroke(Menu):
|
||||
layout.menu("GREASE_PENCIL_MT_move_to_layer")
|
||||
layout.menu("VIEW3D_MT_grease_pencil_assign_material")
|
||||
layout.operator("grease_pencil.set_active_material")
|
||||
layout.operator_menu_enum("grease_pencil.reorder", text="Arrange", property="direction")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("grease_pencil.cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
|
||||
layout.operator("grease_pencil.stroke_switch_direction")
|
||||
layout.operator_menu_enum("grease_pencil.caps_set", text="Set Caps", property="type")
|
||||
layout.operator("grease_pencil.stroke_switch_direction")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("grease_pencil.set_uniform_thickness")
|
||||
layout.operator("grease_pencil.set_uniform_opacity")
|
||||
|
||||
layout.operator_menu_enum("grease_pencil.reorder", text="Reorder", property="direction")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_greasepencil_point(Menu):
|
||||
bl_label = "Point"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.operator("grease_pencil.stroke_smooth", text="Smooth Points")
|
||||
layout.operator("grease_pencil.stroke_smooth", text="Smooth")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves(Menu):
|
||||
@ -8223,7 +8225,15 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
|
||||
|
||||
col.separator()
|
||||
|
||||
col.menu("VIEW3D_MT_mirror", text="Mirror Points")
|
||||
col.menu("VIEW3D_MT_mirror", text="Mirror")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator("grease_pencil.duplicate_move", text="Duplicate")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator("grease_pencil.separate", text="Separate").mode = 'SELECTED'
|
||||
|
||||
# Removal Operators
|
||||
col.separator()
|
||||
@ -8242,18 +8252,28 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
|
||||
col.separator()
|
||||
|
||||
# Deform Operators
|
||||
col.operator("grease_pencil.stroke_smooth", text="Smooth Points")
|
||||
col.operator("grease_pencil.stroke_smooth", text="Smooth")
|
||||
col.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
|
||||
|
||||
col.separator()
|
||||
|
||||
col.menu("GREASE_PENCIL_MT_move_to_layer")
|
||||
col.menu("VIEW3D_MT_grease_pencil_assign_material")
|
||||
col.operator("grease_pencil.set_active_material", text="Set as Active Material")
|
||||
col.operator_menu_enum("grease_pencil.reorder", text="Arrange", property="direction")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.menu("VIEW3D_MT_mirror")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator("grease_pencil.duplicate_move", text="Duplicate")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator("grease_pencil.separate", text="Separate").mode = 'SELECTED'
|
||||
|
||||
|
||||
def draw_gpencil_layer_active(context, layout):
|
||||
gpl = context.active_gpencil_layer
|
||||
|
@ -65,6 +65,7 @@ class AssetLibrary {
|
||||
*/
|
||||
std::unique_ptr<AssetStorage> asset_storage_;
|
||||
|
||||
protected:
|
||||
std::optional<eAssetImportMethod> import_method_;
|
||||
/** Assets owned by this library may be imported with a different method than set in
|
||||
* #import_method_ above, it's just a default. */
|
||||
|
@ -15,10 +15,11 @@ set(SRC
|
||||
intern/asset_catalog.cc
|
||||
intern/asset_catalog_path.cc
|
||||
intern/asset_catalog_tree.cc
|
||||
intern/asset_essentials_library.cc
|
||||
intern/asset_identifier.cc
|
||||
intern/asset_library.cc
|
||||
intern/asset_library_all.cc
|
||||
intern/asset_library_essentials.cc
|
||||
intern/asset_library_from_preferences.cc
|
||||
intern/asset_library_on_disk.cc
|
||||
intern/asset_library_runtime.cc
|
||||
intern/asset_library_service.cc
|
||||
@ -34,6 +35,8 @@ set(SRC
|
||||
AS_asset_representation.hh
|
||||
AS_essentials_library.hh
|
||||
intern/asset_library_all.hh
|
||||
intern/asset_library_essentials.hh
|
||||
intern/asset_library_from_preferences.hh
|
||||
intern/asset_library_on_disk.hh
|
||||
intern/asset_library_runtime.hh
|
||||
intern/asset_library_service.hh
|
||||
|
@ -6,14 +6,23 @@
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_appdir.hh"
|
||||
|
||||
#include "utils.hh"
|
||||
|
||||
#include "AS_essentials_library.hh"
|
||||
#include "asset_library_essentials.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
EssentialsAssetLibrary::EssentialsAssetLibrary()
|
||||
: OnDiskAssetLibrary(ASSET_LIBRARY_ESSENTIALS,
|
||||
{},
|
||||
utils::normalize_directory_path(essentials_directory_path()))
|
||||
{
|
||||
import_method_ = ASSET_IMPORT_APPEND_REUSE;
|
||||
}
|
||||
|
||||
StringRefNull essentials_directory_path()
|
||||
{
|
||||
static std::string path = []() {
|
@ -0,0 +1,20 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "asset_library_on_disk.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
class EssentialsAssetLibrary : public OnDiskAssetLibrary {
|
||||
public:
|
||||
EssentialsAssetLibrary();
|
||||
};
|
||||
|
||||
} // namespace blender::asset_system
|
@ -0,0 +1,18 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#include "asset_library_from_preferences.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
PreferencesOnDiskAssetLibrary::PreferencesOnDiskAssetLibrary(StringRef name, StringRef root_path)
|
||||
: OnDiskAssetLibrary(ASSET_LIBRARY_CUSTOM, name, root_path)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
@ -0,0 +1,20 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "asset_library_on_disk.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
class PreferencesOnDiskAssetLibrary : public OnDiskAssetLibrary {
|
||||
public:
|
||||
PreferencesOnDiskAssetLibrary(StringRef name = "", StringRef root_path = "");
|
||||
};
|
||||
|
||||
} // namespace blender::asset_system
|
@ -20,6 +20,8 @@
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_essentials_library.hh"
|
||||
#include "asset_library_all.hh"
|
||||
#include "asset_library_essentials.hh"
|
||||
#include "asset_library_from_preferences.hh"
|
||||
#include "asset_library_on_disk.hh"
|
||||
#include "asset_library_runtime.hh"
|
||||
#include "asset_library_service.hh"
|
||||
@ -72,10 +74,7 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AssetLibrary *library = get_asset_library_on_disk_builtin(type, root_path);
|
||||
library->import_method_ = ASSET_IMPORT_APPEND_REUSE;
|
||||
|
||||
return library;
|
||||
return get_asset_library_on_disk_builtin(type, root_path);
|
||||
}
|
||||
case ASSET_LIBRARY_LOCAL: {
|
||||
/* For the "Current File" library we get the asset library root path based on main. */
|
||||
@ -132,8 +131,19 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(eAssetLibraryType l
|
||||
return lib;
|
||||
}
|
||||
|
||||
std::unique_ptr lib_uptr = std::make_unique<OnDiskAssetLibrary>(
|
||||
library_type, name, normalized_root_path);
|
||||
std::unique_ptr<OnDiskAssetLibrary> lib_uptr;
|
||||
switch (library_type) {
|
||||
case ASSET_LIBRARY_CUSTOM:
|
||||
lib_uptr = std::make_unique<PreferencesOnDiskAssetLibrary>(name, normalized_root_path);
|
||||
break;
|
||||
case ASSET_LIBRARY_ESSENTIALS:
|
||||
lib_uptr = std::make_unique<EssentialsAssetLibrary>();
|
||||
break;
|
||||
default:
|
||||
lib_uptr = std::make_unique<OnDiskAssetLibrary>(library_type, name, normalized_root_path);
|
||||
break;
|
||||
}
|
||||
|
||||
AssetLibrary *lib = lib_uptr.get();
|
||||
|
||||
lib->load_catalogs();
|
||||
|
@ -21,7 +21,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/** Blender major and minor version. */
|
||||
#define BLENDER_VERSION 401
|
||||
#define BLENDER_VERSION 402
|
||||
/** Blender patch version for bug-fix releases. */
|
||||
#define BLENDER_VERSION_PATCH 0
|
||||
/** Blender release cycle stage: alpha/beta/rc/release. */
|
||||
@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 18
|
||||
#define BLENDER_FILE_SUBVERSION 1
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
@ -93,7 +93,7 @@ void BKE_object_defgroup_unique_name(bDeformGroup *dg, Object *ob);
|
||||
|
||||
MDeformWeight *BKE_defvert_find_index(const MDeformVert *dv, int defgroup);
|
||||
/**
|
||||
* Ensures that `dv` has a deform weight entry for the specified defweight group.
|
||||
* Ensures that `dv` has a deform weight entry for the specified group (`defgroup`).
|
||||
*
|
||||
* \note this function is mirrored in editmesh_tools.cc, for use for edit-vertices.
|
||||
*/
|
||||
|
@ -34,14 +34,6 @@ namespace blender::bke {
|
||||
|
||||
namespace greasepencil {
|
||||
|
||||
struct DrawingTransforms {
|
||||
float4x4 world_space_to_layer_space;
|
||||
float4x4 layer_space_to_world_space;
|
||||
|
||||
DrawingTransforms() = default;
|
||||
DrawingTransforms(const Object &grease_pencil_ob);
|
||||
};
|
||||
|
||||
class DrawingRuntime {
|
||||
public:
|
||||
/**
|
||||
@ -447,6 +439,23 @@ class Layer : public ::GreasePencilLayer {
|
||||
*/
|
||||
void update_from_dna_read();
|
||||
|
||||
/**
|
||||
* Returns the transformation from layer space to object space.
|
||||
*/
|
||||
float4x4 to_object_space(const Object &object) const;
|
||||
|
||||
/**
|
||||
* Returns the transformation from layer space to world space.
|
||||
*/
|
||||
float4x4 to_world_space(const Object &object) const;
|
||||
|
||||
/**
|
||||
* Returns the name of the parent bone. Should only be used in case the parent object is an
|
||||
* armature.
|
||||
*/
|
||||
StringRefNull parent_bone_name() const;
|
||||
void set_parent_bone_name(const char *new_name);
|
||||
|
||||
private:
|
||||
using SortedKeysIterator = const int *;
|
||||
|
||||
@ -460,6 +469,16 @@ class Layer : public ::GreasePencilLayer {
|
||||
*/
|
||||
SortedKeysIterator remove_leading_null_frames_in_range(SortedKeysIterator begin,
|
||||
SortedKeysIterator end);
|
||||
|
||||
/**
|
||||
* The local transform of the layer (in layer space, not object space).
|
||||
*/
|
||||
float4x4 local_transform() const;
|
||||
|
||||
/**
|
||||
* Get the parent to world marix for this layer.
|
||||
*/
|
||||
float4x4 parent_to_world(const Object &parent) const;
|
||||
};
|
||||
|
||||
class LayerGroupRuntime {
|
||||
@ -706,6 +725,7 @@ TREENODE_COMMON_METHODS_FORWARD_IMPL(LayerGroup);
|
||||
namespace convert {
|
||||
|
||||
void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
const ListBase &vertex_group_names,
|
||||
GreasePencilDrawing &r_drawing);
|
||||
void legacy_gpencil_to_grease_pencil(Main &main, GreasePencil &grease_pencil, bGPdata &gpd);
|
||||
|
||||
|
@ -271,6 +271,7 @@ extern IDTypeInfo IDType_ID_LINK_PLACEHOLDER;
|
||||
void BKE_idtype_init(void);
|
||||
|
||||
/* General helpers. */
|
||||
const IDTypeInfo *BKE_idtype_get_info_from_idtype_index(const int idtype_index);
|
||||
const IDTypeInfo *BKE_idtype_get_info_from_idcode(short id_code);
|
||||
const IDTypeInfo *BKE_idtype_get_info_from_id(const ID *id);
|
||||
|
||||
|
@ -165,15 +165,15 @@ struct ModifierEvalContext {
|
||||
struct ModifierTypeInfo {
|
||||
/* A unique identifier for this modifier. Used to generate the panel id type name.
|
||||
* See #BKE_modifier_type_panel_id. */
|
||||
char idname[32];
|
||||
char idname[64];
|
||||
|
||||
/* The user visible name for this modifier */
|
||||
char name[32];
|
||||
char name[64];
|
||||
|
||||
/* The DNA struct name for the modifier data type, used to
|
||||
* write the DNA data out.
|
||||
*/
|
||||
char struct_name[32];
|
||||
char struct_name[64];
|
||||
|
||||
/* The size of the modifier data type, used by allocation. */
|
||||
int struct_size;
|
||||
@ -421,9 +421,6 @@ void BKE_modifier_free(ModifierData *md);
|
||||
*/
|
||||
void BKE_modifier_remove_from_list(Object *ob, ModifierData *md);
|
||||
|
||||
/* Generate new UID for the given modifier. */
|
||||
void BKE_modifier_session_uid_generate(ModifierData *md);
|
||||
|
||||
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md);
|
||||
|
||||
ModifierData *BKE_modifier_copy_ex(const ModifierData *md, int flag);
|
||||
@ -472,8 +469,20 @@ void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *user_dat
|
||||
|
||||
ModifierData *BKE_modifiers_findby_type(const Object *ob, ModifierType type);
|
||||
ModifierData *BKE_modifiers_findby_name(const Object *ob, const char *name);
|
||||
ModifierData *BKE_modifiers_findby_session_uid(const Object *ob, const SessionUID *session_uid);
|
||||
ModifierData *BKE_modifiers_findby_persistent_uid(const Object *ob, int persistent_uid);
|
||||
|
||||
void BKE_modifiers_clear_errors(Object *ob);
|
||||
|
||||
/**
|
||||
* Updates `md.persistent_uid` so that it is a valid identifier (>=1) and is unique in the object.
|
||||
*/
|
||||
void BKE_modifiers_persistent_uid_init(const Object &object, ModifierData &md);
|
||||
/**
|
||||
* Returns true when all the modifier identifiers are positive and unique. This should generally be
|
||||
* true and should only be used by asserts.
|
||||
*/
|
||||
bool BKE_modifiers_persistent_uids_are_valid(const Object &object);
|
||||
|
||||
/**
|
||||
* used for buttons, to find out if the 'draw deformed in edit-mode option is there.
|
||||
*
|
||||
@ -584,8 +593,6 @@ void BKE_modifier_deform_vertsEM(ModifierData *md,
|
||||
*/
|
||||
Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval);
|
||||
|
||||
void BKE_modifier_check_uids_unique_and_report(const Object *object);
|
||||
|
||||
void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase *modbase);
|
||||
void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob);
|
||||
|
||||
|
@ -396,6 +396,8 @@ typedef struct bNodeType {
|
||||
|
||||
/** True when the node cannot be muted. */
|
||||
bool no_muting;
|
||||
/** True when the node still works but it's usage is discouraged. */
|
||||
const char *deprecation_notice;
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA rna_ext;
|
||||
|
@ -115,7 +115,8 @@ bool BKE_object_copy_gpencil_modifier(Object *ob_dst, GpencilModifierData *gmd_s
|
||||
* Copy the whole stack of modifiers from one object into another.
|
||||
*
|
||||
* \warning *Does not* clear modifier stack and related data (particle systems, soft-body,
|
||||
* etc.) in `ob_dst`, if needed calling code must do it.
|
||||
* etc.) in `ob_dst`, if needed calling code must do it. The caller is also responsible for
|
||||
* ensuring the modifier identifiers are unique.
|
||||
*
|
||||
* \param do_copy_all: If true, even modifiers that should not support copying (like Hook one)
|
||||
* will be duplicated.
|
||||
|
@ -149,6 +149,13 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
|
||||
if (*dst != nullptr) {
|
||||
mpath = *dst;
|
||||
|
||||
if (avs->path_bakeflag & MOTIONPATH_BAKE_CAMERA_SPACE) {
|
||||
mpath->flag |= MOTIONPATH_FLAG_BAKE_CAMERA;
|
||||
}
|
||||
else {
|
||||
mpath->flag &= ~MOTIONPATH_FLAG_BAKE_CAMERA;
|
||||
}
|
||||
|
||||
/* Only reuse a path if it was already a valid path, and of the expected length. */
|
||||
if (mpath->start_frame != mpath->end_frame && mpath->length == expected_length) {
|
||||
mpath->start_frame = avs->path_sf;
|
||||
@ -176,6 +183,13 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
|
||||
mpath->flag &= ~MOTIONPATH_FLAG_BHEAD;
|
||||
}
|
||||
|
||||
if (avs->path_bakeflag & MOTIONPATH_BAKE_CAMERA_SPACE) {
|
||||
mpath->flag |= MOTIONPATH_FLAG_BAKE_CAMERA;
|
||||
}
|
||||
else {
|
||||
mpath->flag &= ~MOTIONPATH_FLAG_BAKE_CAMERA;
|
||||
}
|
||||
|
||||
/* Set default custom values (RGB). */
|
||||
mpath->color[0] = 1.0;
|
||||
mpath->color[1] = 0.0;
|
||||
|
@ -22,7 +22,7 @@ BakeDataBlockID::BakeDataBlockID(const ID &id)
|
||||
{
|
||||
this->type = GS(id.name);
|
||||
this->id_name = id.name + 2;
|
||||
if (id.lib) {
|
||||
if (ID_IS_LINKED(&id)) {
|
||||
this->lib_name = id.lib->id.name + 2;
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef WITH_USD
|
||||
# include "usd.h"
|
||||
# include "usd.hh"
|
||||
#endif
|
||||
|
||||
static void cachefile_handle_free(CacheFile *cache_file);
|
||||
@ -188,7 +188,8 @@ void BKE_cachefile_reader_open(CacheFile *cache_file,
|
||||
case CACHEFILE_TYPE_USD:
|
||||
# ifdef WITH_USD
|
||||
/* Open USD cache reader. */
|
||||
*reader = CacheReader_open_usd_object(cache_file->handle, *reader, object, object_path);
|
||||
*reader = blender::io::usd::CacheReader_open_usd_object(
|
||||
cache_file->handle, *reader, object, object_path);
|
||||
# endif
|
||||
break;
|
||||
case CACHE_FILE_TYPE_INVALID:
|
||||
@ -232,7 +233,7 @@ void BKE_cachefile_reader_free(CacheFile *cache_file, CacheReader **reader)
|
||||
break;
|
||||
case CACHEFILE_TYPE_USD:
|
||||
# ifdef WITH_USD
|
||||
USD_CacheReader_free(*reader);
|
||||
blender::io::usd::USD_CacheReader_free(*reader);
|
||||
# endif
|
||||
break;
|
||||
case CACHE_FILE_TYPE_INVALID:
|
||||
@ -272,7 +273,7 @@ static void cachefile_handle_free(CacheFile *cache_file)
|
||||
break;
|
||||
case CACHEFILE_TYPE_USD:
|
||||
# ifdef WITH_USD
|
||||
USD_CacheReader_free(*reader);
|
||||
blender::io::usd::USD_CacheReader_free(*reader);
|
||||
# endif
|
||||
break;
|
||||
case CACHE_FILE_TYPE_INVALID:
|
||||
@ -299,7 +300,7 @@ static void cachefile_handle_free(CacheFile *cache_file)
|
||||
break;
|
||||
case CACHEFILE_TYPE_USD:
|
||||
# ifdef WITH_USD
|
||||
USD_free_handle(cache_file->handle);
|
||||
blender::io::usd::USD_free_handle(cache_file->handle);
|
||||
# endif
|
||||
break;
|
||||
case CACHE_FILE_TYPE_INVALID:
|
||||
@ -365,7 +366,8 @@ void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file
|
||||
#ifdef WITH_USD
|
||||
if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc;*.usdz")) {
|
||||
cache_file->type = CACHEFILE_TYPE_USD;
|
||||
cache_file->handle = USD_create_handle(bmain, filepath, &cache_file->object_paths);
|
||||
cache_file->handle = blender::io::usd::USD_create_handle(
|
||||
bmain, filepath, &cache_file->object_paths);
|
||||
STRNCPY(cache_file->handle_filepath, filepath);
|
||||
}
|
||||
#endif
|
||||
|
@ -1359,6 +1359,12 @@ static void save_sample_line(
|
||||
scopes->vecscope[idx + 0] = yuv[1];
|
||||
scopes->vecscope[idx + 1] = yuv[2];
|
||||
|
||||
int color_idx = (idx / 2) * 4;
|
||||
scopes->vecscope_rgb[color_idx + 0] = rgb[0];
|
||||
scopes->vecscope_rgb[color_idx + 1] = rgb[1];
|
||||
scopes->vecscope_rgb[color_idx + 2] = rgb[2];
|
||||
scopes->vecscope_rgb[color_idx + 3] = scopes->vecscope_alpha;
|
||||
|
||||
/* Waveform. */
|
||||
switch (scopes->wavefrm_mode) {
|
||||
case SCOPES_WAVEFRM_RGB:
|
||||
@ -1707,6 +1713,7 @@ void BKE_scopes_update(Scopes *scopes,
|
||||
}
|
||||
if (scopes->vecscope) {
|
||||
MEM_freeN(scopes->vecscope);
|
||||
MEM_freeN(scopes->vecscope_rgb);
|
||||
}
|
||||
|
||||
scopes->waveform_1 = static_cast<float *>(
|
||||
@ -1717,6 +1724,8 @@ void BKE_scopes_update(Scopes *scopes,
|
||||
MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"));
|
||||
scopes->vecscope = static_cast<float *>(
|
||||
MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"));
|
||||
scopes->vecscope_rgb = static_cast<float *>(
|
||||
MEM_callocN(scopes->waveform_tot * 4 * sizeof(float), "vectorscope color channel"));
|
||||
|
||||
if (ibuf->float_buffer.data) {
|
||||
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
|
||||
@ -1794,6 +1803,7 @@ void BKE_scopes_free(Scopes *scopes)
|
||||
MEM_SAFE_FREE(scopes->waveform_2);
|
||||
MEM_SAFE_FREE(scopes->waveform_3);
|
||||
MEM_SAFE_FREE(scopes->vecscope);
|
||||
MEM_SAFE_FREE(scopes->vecscope_rgb);
|
||||
}
|
||||
|
||||
void BKE_scopes_new(Scopes *scopes)
|
||||
@ -1810,6 +1820,7 @@ void BKE_scopes_new(Scopes *scopes)
|
||||
scopes->waveform_2 = nullptr;
|
||||
scopes->waveform_3 = nullptr;
|
||||
scopes->vecscope = nullptr;
|
||||
scopes->vecscope_rgb = nullptr;
|
||||
}
|
||||
|
||||
void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings)
|
||||
|
@ -88,7 +88,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef WITH_USD
|
||||
# include "usd.h"
|
||||
# include "usd.hh"
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
@ -5395,7 +5395,8 @@ static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBa
|
||||
break;
|
||||
case CACHEFILE_TYPE_USD:
|
||||
# ifdef WITH_USD
|
||||
USD_get_transform(data->reader, cob->matrix, time * FPS, cache_file->scale);
|
||||
blender::io::usd::USD_get_transform(
|
||||
data->reader, cob->matrix, time * FPS, cache_file->scale);
|
||||
# endif
|
||||
break;
|
||||
case CACHE_FILE_TYPE_INVALID:
|
||||
|
@ -89,89 +89,85 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num)
|
||||
this->runtime->type_counts[CURVE_TYPE_CATMULL_ROM] = curve_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Expects `dst` to be initialized, since the original attributes must be freed.
|
||||
*/
|
||||
static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
|
||||
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other)
|
||||
{
|
||||
CustomData_free(&dst.point_data, dst.point_num);
|
||||
CustomData_free(&dst.curve_data, dst.curve_num);
|
||||
dst.point_num = src.point_num;
|
||||
dst.curve_num = src.curve_num;
|
||||
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, dst.point_num);
|
||||
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, dst.curve_num);
|
||||
|
||||
dst.vertex_group_active_index = src.vertex_group_active_index;
|
||||
BKE_defgroup_copy_list(&dst.vertex_group_names, &src.vertex_group_names);
|
||||
|
||||
implicit_sharing::copy_shared_pointer(src.curve_offsets,
|
||||
src.runtime->curve_offsets_sharing_info,
|
||||
&dst.curve_offsets,
|
||||
&dst.runtime->curve_offsets_sharing_info);
|
||||
|
||||
dst.tag_topology_changed();
|
||||
|
||||
/* Though type counts are a cache, they must be copied because they are calculated eagerly. */
|
||||
dst.runtime->type_counts = src.runtime->type_counts;
|
||||
dst.runtime->evaluated_offsets_cache = src.runtime->evaluated_offsets_cache;
|
||||
dst.runtime->nurbs_basis_cache = src.runtime->nurbs_basis_cache;
|
||||
dst.runtime->evaluated_position_cache = src.runtime->evaluated_position_cache;
|
||||
dst.runtime->bounds_cache = src.runtime->bounds_cache;
|
||||
dst.runtime->evaluated_length_cache = src.runtime->evaluated_length_cache;
|
||||
dst.runtime->evaluated_tangent_cache = src.runtime->evaluated_tangent_cache;
|
||||
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
|
||||
|
||||
if (src.runtime->bake_materials) {
|
||||
dst.runtime->bake_materials = std::make_unique<bake::BakeMaterialsList>(
|
||||
*src.runtime->bake_materials);
|
||||
this->curve_offsets = other.curve_offsets;
|
||||
if (other.runtime->curve_offsets_sharing_info) {
|
||||
other.runtime->curve_offsets_sharing_info->add_user();
|
||||
}
|
||||
}
|
||||
|
||||
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other) : CurvesGeometry()
|
||||
{
|
||||
copy_curves_geometry(*this, other);
|
||||
CustomData_copy(&other.point_data, &this->point_data, CD_MASK_ALL, other.point_num);
|
||||
CustomData_copy(&other.curve_data, &this->curve_data, CD_MASK_ALL, other.curve_num);
|
||||
|
||||
this->point_num = other.point_num;
|
||||
this->curve_num = other.curve_num;
|
||||
|
||||
BKE_defgroup_copy_list(&this->vertex_group_names, &other.vertex_group_names);
|
||||
this->vertex_group_active_index = other.vertex_group_active_index;
|
||||
|
||||
this->runtime = MEM_new<CurvesGeometryRuntime>(
|
||||
__func__,
|
||||
CurvesGeometryRuntime{other.runtime->curve_offsets_sharing_info,
|
||||
other.runtime->type_counts,
|
||||
other.runtime->evaluated_offsets_cache,
|
||||
other.runtime->nurbs_basis_cache,
|
||||
other.runtime->evaluated_position_cache,
|
||||
other.runtime->bounds_cache,
|
||||
other.runtime->evaluated_length_cache,
|
||||
other.runtime->evaluated_tangent_cache,
|
||||
other.runtime->evaluated_normal_cache,
|
||||
{}});
|
||||
|
||||
if (other.runtime->bake_materials) {
|
||||
this->runtime->bake_materials = std::make_unique<bake::BakeMaterialsList>(
|
||||
*other.runtime->bake_materials);
|
||||
}
|
||||
}
|
||||
|
||||
CurvesGeometry &CurvesGeometry::operator=(const CurvesGeometry &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
copy_curves_geometry(*this, other);
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
std::destroy_at(this);
|
||||
new (this) CurvesGeometry(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* The source should be empty, but in a valid state so that using it further will work. */
|
||||
static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src)
|
||||
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other)
|
||||
{
|
||||
dst.point_num = src.point_num;
|
||||
std::swap(dst.point_data, src.point_data);
|
||||
CustomData_free(&src.point_data, src.point_num);
|
||||
src.point_num = 0;
|
||||
this->curve_offsets = other.curve_offsets;
|
||||
other.curve_offsets = nullptr;
|
||||
|
||||
dst.curve_num = src.curve_num;
|
||||
std::swap(dst.curve_data, src.curve_data);
|
||||
CustomData_free(&src.curve_data, src.curve_num);
|
||||
src.curve_num = 0;
|
||||
this->point_data = other.point_data;
|
||||
CustomData_reset(&other.point_data);
|
||||
|
||||
std::swap(dst.curve_offsets, src.curve_offsets);
|
||||
this->curve_data = other.curve_data;
|
||||
CustomData_reset(&other.curve_data);
|
||||
|
||||
std::swap(dst.vertex_group_names.first, src.vertex_group_names.first);
|
||||
std::swap(dst.vertex_group_names.last, src.vertex_group_names.last);
|
||||
std::swap(dst.vertex_group_active_index, src.vertex_group_active_index);
|
||||
this->point_num = other.point_num;
|
||||
other.point_num = 0;
|
||||
|
||||
std::swap(dst.runtime, src.runtime);
|
||||
}
|
||||
this->curve_num = other.curve_num;
|
||||
other.curve_num = 0;
|
||||
|
||||
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other) : CurvesGeometry()
|
||||
{
|
||||
move_curves_geometry(*this, other);
|
||||
this->vertex_group_names = other.vertex_group_names;
|
||||
BLI_listbase_clear(&other.vertex_group_names);
|
||||
|
||||
this->vertex_group_active_index = other.vertex_group_active_index;
|
||||
other.vertex_group_active_index = 0;
|
||||
|
||||
this->runtime = other.runtime;
|
||||
other.runtime = nullptr;
|
||||
}
|
||||
|
||||
CurvesGeometry &CurvesGeometry::operator=(CurvesGeometry &&other)
|
||||
{
|
||||
if (this != &other) {
|
||||
move_curves_geometry(*this, other);
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
std::destroy_at(this);
|
||||
new (this) CurvesGeometry(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -179,11 +175,12 @@ CurvesGeometry::~CurvesGeometry()
|
||||
{
|
||||
CustomData_free(&this->point_data, this->point_num);
|
||||
CustomData_free(&this->curve_data, this->curve_num);
|
||||
implicit_sharing::free_shared_data(&this->curve_offsets,
|
||||
&this->runtime->curve_offsets_sharing_info);
|
||||
BLI_freelistN(&this->vertex_group_names);
|
||||
MEM_delete(this->runtime);
|
||||
this->runtime = nullptr;
|
||||
if (this->runtime) {
|
||||
implicit_sharing::free_shared_data(&this->curve_offsets,
|
||||
&this->runtime->curve_offsets_sharing_info);
|
||||
MEM_delete(this->runtime);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "BLI_sort_utils.h"
|
||||
#include "BLI_string_utils.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_context.hh"
|
||||
@ -169,7 +171,7 @@ void BKE_fmodifier_name_set(FModifier *fcm, const char *name)
|
||||
* Ensure the name is unique. */
|
||||
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type);
|
||||
ListBase list = BLI_listbase_from_link((Link *)fcm);
|
||||
BLI_uniquename(&list, fcm, fmi->name, '.', offsetof(FModifier, name), sizeof(fcm->name));
|
||||
BLI_uniquename(&list, fcm, DATA_(fmi->name), '.', offsetof(FModifier, name), sizeof(fcm->name));
|
||||
}
|
||||
|
||||
void BKE_fmodifiers_foreach_id(ListBase *fmodifiers, LibraryForeachIDData *data)
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
@ -25,8 +26,10 @@
|
||||
|
||||
#include "BLI_bounds.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_euler_types.hh"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_memory_utils.hh"
|
||||
@ -240,14 +243,6 @@ IDTypeInfo IDType_ID_GP = {
|
||||
|
||||
namespace blender::bke::greasepencil {
|
||||
|
||||
DrawingTransforms::DrawingTransforms(const Object &grease_pencil_ob)
|
||||
{
|
||||
/* TODO: For now layer space = object space. This needs to change once the layers have a
|
||||
* transform. */
|
||||
this->layer_space_to_world_space = float4x4_view(grease_pencil_ob.object_to_world);
|
||||
this->world_space_to_layer_space = math::invert(this->layer_space_to_world_space);
|
||||
}
|
||||
|
||||
static const std::string ATTR_RADIUS = "radius";
|
||||
static const std::string ATTR_OPACITY = "opacity";
|
||||
static const std::string ATTR_VERTEX_COLOR = "vertex_color";
|
||||
@ -664,6 +659,13 @@ Layer::Layer()
|
||||
|
||||
this->opacity = 1.0f;
|
||||
|
||||
this->parent = nullptr;
|
||||
this->parsubstr = nullptr;
|
||||
|
||||
zero_v3(this->translation);
|
||||
zero_v3(this->rotation);
|
||||
copy_v3_fl(this->scale, 1.0f);
|
||||
|
||||
BLI_listbase_clear(&this->masks);
|
||||
|
||||
this->runtime = MEM_new<LayerRuntime>(__func__);
|
||||
@ -680,11 +682,18 @@ Layer::Layer(const Layer &other) : Layer()
|
||||
|
||||
/* TODO: duplicate masks. */
|
||||
|
||||
/* Note: We do not duplicate the frame storage since it is only needed for writing. */
|
||||
/* Note: We do not duplicate the frame storage since it is only needed for writing to file. */
|
||||
|
||||
this->blend_mode = other.blend_mode;
|
||||
this->opacity = other.opacity;
|
||||
|
||||
this->parent = other.parent;
|
||||
this->set_parent_bone_name(other.parsubstr);
|
||||
|
||||
copy_v3_v3(this->translation, other.translation);
|
||||
copy_v3_v3(this->rotation, other.rotation);
|
||||
copy_v3_v3(this->scale, other.scale);
|
||||
|
||||
this->runtime->frames_ = other.runtime->frames_;
|
||||
this->runtime->sorted_keys_cache_ = other.runtime->sorted_keys_cache_;
|
||||
/* TODO: what about masks cache? */
|
||||
@ -702,6 +711,8 @@ Layer::~Layer()
|
||||
MEM_freeN(mask);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(this->parsubstr);
|
||||
|
||||
MEM_delete(this->runtime);
|
||||
this->runtime = nullptr;
|
||||
}
|
||||
@ -946,6 +957,57 @@ void Layer::update_from_dna_read()
|
||||
}
|
||||
}
|
||||
|
||||
float4x4 Layer::to_world_space(const Object &object) const
|
||||
{
|
||||
if (this->parent == nullptr) {
|
||||
return float4x4(object.object_to_world) * this->local_transform();
|
||||
}
|
||||
const Object &parent = *this->parent;
|
||||
return this->parent_to_world(parent) * this->local_transform();
|
||||
}
|
||||
|
||||
float4x4 Layer::to_object_space(const Object &object) const
|
||||
{
|
||||
if (this->parent == nullptr) {
|
||||
return this->local_transform();
|
||||
}
|
||||
const Object &parent = *this->parent;
|
||||
return float4x4(object.world_to_object) * this->parent_to_world(parent) *
|
||||
this->local_transform();
|
||||
}
|
||||
|
||||
StringRefNull Layer::parent_bone_name() const
|
||||
{
|
||||
return (this->parsubstr != nullptr) ? StringRefNull(this->parsubstr) : StringRefNull();
|
||||
}
|
||||
|
||||
void Layer::set_parent_bone_name(const char *new_name)
|
||||
{
|
||||
if (this->parsubstr != nullptr) {
|
||||
MEM_freeN(this->parsubstr);
|
||||
}
|
||||
this->parsubstr = BLI_strdup_null(new_name);
|
||||
}
|
||||
|
||||
float4x4 Layer::parent_to_world(const Object &parent) const
|
||||
{
|
||||
const float4x4 parent_object_to_world(parent.object_to_world);
|
||||
if (parent.type == OB_ARMATURE && !this->parent_bone_name().is_empty()) {
|
||||
if (bPoseChannel *channel = BKE_pose_channel_find_name(parent.pose,
|
||||
this->parent_bone_name().c_str()))
|
||||
{
|
||||
return parent_object_to_world * float4x4_view(channel->pose_mat);
|
||||
}
|
||||
}
|
||||
return parent_object_to_world;
|
||||
}
|
||||
|
||||
float4x4 Layer::local_transform() const
|
||||
{
|
||||
return math::from_loc_rot_scale<float4x4, math::EulerXYZ>(
|
||||
float3(this->translation), float3(this->rotation), float3(this->scale));
|
||||
}
|
||||
|
||||
LayerGroup::LayerGroup()
|
||||
{
|
||||
new (&this->base) TreeNode(GP_LAYER_TREE_GROUP);
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_material.h"
|
||||
|
||||
@ -19,10 +20,52 @@
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
namespace blender::bke::greasepencil::convert {
|
||||
|
||||
/**
|
||||
* Find vertex groups that have assigned vertices in this drawing.
|
||||
* Returns:
|
||||
* - ListBase with used vertex group names (bDeformGroup)
|
||||
* - Array of indices in the new vertex group list for remapping
|
||||
*/
|
||||
static void find_used_vertex_groups(const bGPDframe &gpf,
|
||||
const ListBase &all_names,
|
||||
ListBase &r_vertex_group_names,
|
||||
Array<int> &r_indices)
|
||||
{
|
||||
const int num_vertex_groups = BLI_listbase_count(&all_names);
|
||||
Array<int> is_group_used(num_vertex_groups, false);
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf.strokes) {
|
||||
if (!gps->dvert) {
|
||||
continue;
|
||||
}
|
||||
Span<MDeformVert> dverts = {gps->dvert, gps->totpoints};
|
||||
for (const MDeformVert &dvert : dverts) {
|
||||
for (const MDeformWeight &weight : Span<MDeformWeight>{dvert.dw, dvert.totweight}) {
|
||||
is_group_used[weight.def_nr] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_listbase_clear(&r_vertex_group_names);
|
||||
r_indices.reinitialize(num_vertex_groups);
|
||||
int new_group_i = 0;
|
||||
int old_group_i;
|
||||
LISTBASE_FOREACH_INDEX (const bDeformGroup *, def_group, &all_names, old_group_i) {
|
||||
if (!is_group_used[old_group_i]) {
|
||||
r_indices[old_group_i] = -1;
|
||||
continue;
|
||||
}
|
||||
r_indices[old_group_i] = new_group_i++;
|
||||
|
||||
bDeformGroup *def_group_copy = static_cast<bDeformGroup *>(MEM_dupallocN(def_group));
|
||||
BLI_addtail(&r_vertex_group_names, def_group_copy);
|
||||
}
|
||||
}
|
||||
|
||||
void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
const ListBase &vertex_group_names,
|
||||
GreasePencilDrawing &r_drawing)
|
||||
{
|
||||
/* Construct an empty CurvesGeometry in-place. */
|
||||
@ -54,6 +97,25 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
/* All strokes are poly curves. */
|
||||
curves.fill_curve_types(CURVE_TYPE_POLY);
|
||||
|
||||
/* Find used vertex groups in this drawing. */
|
||||
ListBase stroke_vertex_group_names;
|
||||
Array<int> stroke_def_nr_map;
|
||||
find_used_vertex_groups(gpf, vertex_group_names, stroke_vertex_group_names, stroke_def_nr_map);
|
||||
BLI_assert(BLI_listbase_is_empty(&curves.vertex_group_names));
|
||||
curves.vertex_group_names = stroke_vertex_group_names;
|
||||
const bool use_dverts = !BLI_listbase_is_empty(&curves.vertex_group_names);
|
||||
|
||||
/* Copy vertex weights and map the vertex group indices. */
|
||||
auto copy_dvert = [&](const MDeformVert &src_dvert, MDeformVert &dst_dvert) {
|
||||
dst_dvert = src_dvert;
|
||||
dst_dvert.dw = static_cast<MDeformWeight *>(MEM_dupallocN(src_dvert.dw));
|
||||
const MutableSpan<MDeformWeight> vertex_weights = {dst_dvert.dw, dst_dvert.totweight};
|
||||
for (MDeformWeight &weight : vertex_weights) {
|
||||
/* Map def_nr to the reduced vertex group list. */
|
||||
weight.def_nr = stroke_def_nr_map[weight.def_nr];
|
||||
}
|
||||
};
|
||||
|
||||
/* Point Attributes. */
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
MutableSpan<float> radii = drawing.radii_for_write();
|
||||
@ -66,6 +128,8 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
attributes.lookup_or_add_for_write_span<ColorGeometry4f>("vertex_color", AttrDomain::Point);
|
||||
SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".selection", AttrDomain::Point);
|
||||
MutableSpan<MDeformVert> dverts = use_dverts ? curves.wrap().deform_verts_for_write() :
|
||||
MutableSpan<MDeformVert>();
|
||||
|
||||
/* Curve Attributes. */
|
||||
SpanAttributeWriter<bool> stroke_cyclic = attributes.lookup_or_add_for_write_span<bool>(
|
||||
@ -126,6 +190,8 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
MutableSpan<ColorGeometry4f> stroke_vertex_colors = vertex_colors.span.slice(
|
||||
stroke_points_range);
|
||||
MutableSpan<bool> stroke_selections = selection.span.slice(stroke_points_range);
|
||||
MutableSpan<MDeformVert> stroke_dverts = use_dverts ? dverts.slice(stroke_points_range) :
|
||||
MutableSpan<MDeformVert>();
|
||||
|
||||
/* Do first point. */
|
||||
const bGPDspoint &first_pt = stroke_points.first();
|
||||
@ -143,6 +209,9 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
stroke_rotations.first() = first_pt.uv_rot;
|
||||
stroke_vertex_colors.first() = ColorGeometry4f(first_pt.vert_color);
|
||||
stroke_selections.first() = (first_pt.flag & GP_SPOINT_SELECT) != 0;
|
||||
if (use_dverts && gps->dvert) {
|
||||
copy_dvert(gps->dvert[0], stroke_dverts.first());
|
||||
}
|
||||
|
||||
/* Do the rest of the points. */
|
||||
for (const int i : stroke_points.index_range().drop_back(1)) {
|
||||
@ -156,6 +225,9 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
stroke_rotations[point_i] = pt.uv_rot;
|
||||
stroke_vertex_colors[point_i] = ColorGeometry4f(pt.vert_color);
|
||||
stroke_selections[point_i] = (pt.flag & GP_SPOINT_SELECT) != 0;
|
||||
if (use_dverts && gps->dvert) {
|
||||
copy_dvert(gps->dvert[point_i], stroke_dverts[point_i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,6 +282,13 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
|
||||
|
||||
new_layer.blend_mode = int8_t(gpl->blend_mode);
|
||||
|
||||
new_layer.parent = gpl->parent;
|
||||
new_layer.set_parent_bone_name(gpl->parsubstr);
|
||||
|
||||
copy_v3_v3(new_layer.translation, gpl->location);
|
||||
copy_v3_v3(new_layer.rotation, gpl->rotation);
|
||||
copy_v3_v3(new_layer.scale, gpl->scale);
|
||||
|
||||
/* Convert the layer masks. */
|
||||
LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
|
||||
LayerMask *new_mask = new LayerMask(mask->name);
|
||||
@ -225,7 +304,7 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
|
||||
grease_pencil.drawing_array[i]);
|
||||
|
||||
/* Convert the frame to a drawing. */
|
||||
legacy_gpencil_frame_to_grease_pencil_drawing(*gpf, drawing);
|
||||
legacy_gpencil_frame_to_grease_pencil_drawing(*gpf, gpd.vertex_group_names, drawing);
|
||||
|
||||
/* Add the frame to the layer. */
|
||||
if (GreasePencilFrame *new_frame = new_layer.add_frame(gpf->framenum, i)) {
|
||||
@ -242,6 +321,10 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
|
||||
/* TODO: Update drawing user counts. */
|
||||
}
|
||||
|
||||
/* Copy vertex group names and settings. */
|
||||
BKE_defgroup_copy_list(&grease_pencil.vertex_group_names, &gpd.vertex_group_names);
|
||||
grease_pencil.vertex_group_active_index = gpd.vertex_group_active_index;
|
||||
|
||||
/* Convert the onion skinning settings. */
|
||||
grease_pencil.onion_skinning_settings.opacity = gpd.onion_factor;
|
||||
grease_pencil.onion_skinning_settings.mode = gpd.onion_mode;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user